% language=us runpath=texruns:manuals/primitives \setupexternalfigures [location={default,global}] \enableexperiments[fonts.compact] \enableexperiments[fonts.accurate] % \tracepositions % The usual time stamp. This written while listening intermized to Fish (just ran % into), Lazulli (some yt videos too, looking forward to a next live act) and % because this all is boring checking out Sarah Coopers channel for new DT syncs % every few hours. (Picking up writing this manual in 2023 makes me realize how % time flies.) % When you feel unhappy about the lack of detail in this manual, just keep in mind % that you cannot really demand anything from volunteers: just hope for more (or % pay for it). Friendly comments and corrections are of course always welcome. As % we like what we're doing here, it all might eventually evolve to perfection, stay % tuned. % % Hans Hagen | j.hagen @ xs4all . nl | ntg-context @ ntg . nl % iflastnamedcs % ignorerest % \enableexperiments[fonts.compact] \usemodule[system-syntax] \usemodule[system-units] \usemodule[article-basic] \usemodule[abbreviations-logos] \usemodule[scite] \setupinteraction [state=start, color=, contrastcolor=, style=, contraststyle=] \definecolor[maincolor][darkblue] \definecolor[primcolor][darkblue] \definecolor[nonecolor][darkgray] \setuptyping [option=tex] \setuptype [option=tex] \setuphead [subject] [color=maincolor] \definehead [newprimitive] [subsection] [color=maincolor] \definehead [oldprimitive] [subsection] [%color=nonecolor, color=\ifcstok{\structureuservariable{obsolete}}{yes}darkred\else nonecolor\fi] \setuplist [newprimitive] [textcolor=maincolor] \setuplist [oldprimitive] [textcolor=nonecolor] % We use the next one because we want to check what has been done. In a document % like this using \type {\foo} makes more sense. \protected\def\prm#1% % {\doifmode{*bodypart}{\index{\tex{#1}}}\tex{#1}} % {\ifmode{*bodypart}\index{\tex{#1!\string#1!}}\fi\tex{#1}} {\ifmode{*bodypart}\index{\tex{#1}}\fi\tex{#1}} \protected\def\stx#1% {\ctxlua{moduledata.engine.specification("#1")}} % only for checking % This is why we need to tag bodymatter. \starttext \startbodymatter \pushoverloadmode \startMPpage fill Page withcolor "darkgray" ; draw textext("\sstf {\white new} primitives") xysized (.9bbwidth(Page),bbheight(Page)-2cm) shifted center Page withcolor "maincolor" ; draw textext.ulft("\sstf in luametatex") xysized (.9bbwidth(Page)/3,(bbheight(Page)-2cm)/6) shifted center lrcorner Page shifted (-.1bbwidth(Page),.05bbwidth(Page)) withcolor "white" ; setbounds currentpicture to Page ; \stopMPpage \startsubject[title={Introduction}] Here I will discuss some of the new primitives in \LUATEX\ and \LUAMETATEX, the later being a successor that permits the \CONTEXT\ folks to experiment with new features. The order is arbitrary. When you compare \LUATEX\ with \PDFTEX, there are actually quite some differences. Some primitives that \PDFTEX\ introduced have been dropped in \LUATEX\ because they can be done better in \LUA. Others have been promoted to core primitives that no longer have a \type {pdf} prefix. Then there are lots of new primitives, some introduce new concepts, some are a side effect of for instance new math font technologies, and then there are those that are handy extensions to the macro language. The \LUAMETATEX\ engine drops quite some primitives, like those related to \PDFTEX\ specific f(r)ont or backend features. It also adds some new primitives, mostly concerning the macro language. We also discuss the primitives that fit into the macro programming scope that are present in traditional \TEX\ and \ETEX\ but there are for sure better of explanations out there already. Primitives that relate to typesetting, like those controlling math, fonts, boxes, attributes, directions, catcodes, \LUA\ (functions) etc are not discussed or discussed in less detail here. There are for instance primitives to create aliases to low level registers like counters and dimensions, as well as other (semi|-|numeric) quantities like characters, but normally these are wrapped into high level macros so that definitions can't clash too much. Numbers, dimensions etc can be advanced, multiplied and divided and there is a simple expression mechanism to deal with them. We don't go into these details here: it's mostly an overview of what the engine provides. If you are new to \TEX, you need to play a while with its mixed bag of typesetting and programming features in order to understand the difference between this macro language and other languages you might be familiar with. \startcolumns \placelist [newprimitive,oldprimitive] [alternative=c] \stopcolumns In this document the section titles that discuss the \color [nonecolor] {original \TEX\ and \ETEX\ primitives} have a different color those explaining the \color [primcolor] {\LUATEX\ and \LUAMETATEX\ primitives}. Primitives that extend typesetting related functionality, provide control over subsystems (like math), allocate additional data types and resources, deal with fonts and languages, manipulate boxes and glyphs, etc.\ are hardly discussed here, only mentioned. Math for instance is a topic of its own. In this document we concentrate on the programming aspects. Most of the new primitives are discussed in specific manuals and often also original primitives are covered there but the best explanations of the traditional primitives can be found in The \TEX book by Donald Knuth and \TEX\ by Topic from Victor Eijkhout. I see no need to try to improve on those. % {\em Some new primitives in this list might be forgotten or already became % obsolete. Let me know if you run into one.} \stopsubject % When writing this manual I also decided to merge some of the condition related % code so that it dealt a bit more natural with the newer features. A usual side % effects if writing manuals. \startsubject[title=Primitives] \startoldprimitive[title={\prm {}}] This original \TEX\ primitive is equivalent to the more verbose \prm {explicitspace}. \stopoldprimitive \startoldprimitive[title={\prm {-}}] This original \TEX\ primitive is equivalent to the more verbose \prm {explicitdiscretionary}. \stopoldprimitive \startoldprimitive[title={\prm {/}}] This original \TEX\ primitive is equivalent to the more verbose \prm {explicititaliccorrection}. \stopoldprimitive % \startnewprimitive[title={\prm {Uabove}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uabovewithdelims}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uatop}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uatopwithdelims}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Udelcode}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Udelimited}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Udelimiter}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Udelimiterover}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Udelimiterunder}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uhextensible}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uleft}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathaccent}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathaccentbasedepth}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathaccentbaseheight}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathaccentbottomovershoot}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathaccentbottomshiftdown}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathaccentextendmargin}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathaccentsuperscriptdrop}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathaccentsuperscriptpercent}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathaccenttopovershoot}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathaccenttopshiftup}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathaccentvariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathadapttoleft}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathadapttoright}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathaxis}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathbottomaccentvariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathchar}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathchardef}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathcode}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathconnectoroverlapmin}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathdegreevariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathdelimiterextendmargin}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathdelimiterovervariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathdelimiterpercent}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathdelimitershortfall}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathdelimiterundervariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathdenominatorvariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathdictdef}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathexheight}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathextrasubpreshift}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathextrasubprespace}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathextrasubshift}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathextrasubspace}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathextrasuppreshift}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathextrasupprespace}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathextrasupshift}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathextrasupspace}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathflattenedaccentbasedepth}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathflattenedaccentbaseheight}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathflattenedaccentbottomshiftdown}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathflattenedaccenttopshiftup}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathfractiondelsize}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathfractiondenomdown}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathfractiondenomvgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathfractionnumup}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathfractionnumvgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathfractionrule}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathfractionvariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathhextensiblevariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathlimitabovebgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathlimitabovekern}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathlimitabovevgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathlimitbelowbgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathlimitbelowkern}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathlimitbelowvgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathlimits}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathnoaxis}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathnolimits}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathnolimitsubfactor}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathnolimitsupfactor}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathnumeratorvariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathopenupdepth}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathopenupheight}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathoperatorsize}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathoverbarkern}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathoverbarrule}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathoverbarvgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathoverdelimiterbgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathoverdelimitervariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathoverdelimitervgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathoverlayaccentvariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathoverlinevariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathphantom}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathpresubshiftdistance}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathpresupshiftdistance}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathprimeraise}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathprimeraisecomposed}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathprimeshiftdrop}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathprimeshiftup}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathprimespaceafter}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathprimevariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathprimewidth}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathquad}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathradicaldegreeafter}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathradicaldegreebefore}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathradicaldegreeraise}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathradicalextensibleafter}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathradicalextensiblebefore}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathradicalkern}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathradicalrule}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathradicalvariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathradicalvgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathruledepth}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathruleheight}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathskeweddelimitertolerance}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathskewedfractionhgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathskewedfractionvgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsource}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathspaceafterscript}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathspacebeforescript}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathstackdenomdown}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathstacknumup}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathstackvariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathstackvgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsubscriptsnap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsubscriptvariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsubshiftdistance}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsubshiftdown}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsubshiftdrop}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsubsupshiftdown}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsubsupvgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsubtopmax}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsupbottommin}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsuperscriptsnap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsuperscriptvariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsupshiftdistance}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsupshiftdrop}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsupshiftup}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathsupsubbottommax}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathtopaccentvariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathunderbarkern}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathunderbarrule}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathunderbarvgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathunderdelimiterbgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathunderdelimitervariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathunderdelimitervgap}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathunderlinevariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathuseaxis}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathvextensiblevariant}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathvoid}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathxscale}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umathyscale}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Umiddle}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uoperator}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uover}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uoverdelimiter}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uoverwithdelims}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uradical}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uright}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uroot}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Urooted}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uskewed}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uskewedwithdelims}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Ustartdisplaymath}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Ustartmath}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Ustartmathmode}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Ustopdisplaymath}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Ustopmath}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Ustopmathmode}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Ustretched}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Ustretchedwithdelims}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uunderdelimiter}}] % \stopnewprimitive % \startnewprimitive[title={\prm {Uvextensible}}] % \stopnewprimitive \startoldprimitive[title={\prm {above}}][obsolete=yes] This is a variant of \prm {over} that doesn't put a rule in between. \stopoldprimitive \startoldprimitive[title={\prm {abovedisplayshortskip}}] The glue injected before a display formula when the line above it is not overlapping with the formula. Watch out for interference with \prm {baselineskip}. It can be controlled by \prm {displayskipmode}. \stopoldprimitive \startoldprimitive[title={\prm {abovedisplayskip}}] The glue injected before a display formula. Watch out for interference with \prm {baselineskip}. It can be controlled by \prm {displayskipmode}. \stopoldprimitive \startoldprimitive[title={\prm {abovewithdelims}}][obsolete=yes] This is a variant of \prm {atop} but with delimiters. It has a more advanced upgrade in \prm {Uabovewithdelims}. \stopoldprimitive \startoldprimitive[title={\prm {accent}}][obsolete=yes] This primitive is kind of obsolete in wide engines and takes two arguments: the indexes of an accent and a base character. \stopoldprimitive \startnewprimitive[title={\prm {additionalpageskip}}] This quantity will be added to the current page goal, stretch and shrink after which it will be set to zero. \stopnewprimitive \startoldprimitive[title={\prm {adjdemerits}}] When \TEX\ considers to lines to be incompatible it will add this penalty to its verdict when considering this breakpoint. \stopoldprimitive \startnewprimitive[title={\prm {adjustspacing}}] This parameter controls expansion (hz). A value~2 expands glyphs and font kerns and a value of~3 only glyphs. Expansion of kerns can have side effects when they are used for positioning by \OPENTYPE\ features. \stopnewprimitive \startnewprimitive[title={\prm {adjustspacingshrink}}] When set to a non zero value this overloads the shrink maximum in a font when expansion is applied. This is then the case for all fonts. \stopnewprimitive \startnewprimitive[title={\prm {adjustspacingstep}}] When set to a non zero value this overloads the expansion step in a font when expansion is applied. This is then the case for all fonts. \stopnewprimitive \startnewprimitive[title={\prm {adjustspacingstretch}}] When set to a non zero value this overloads the stretch maximum in a font when expansion is applied. This is then the case for all fonts. \stopnewprimitive \startoldprimitive[title={\prm {advance}}] Advances the given register by an also given value: \starttyping \advance\scratchdimen 10pt \advance\scratchdimen by 3pt \advance\scratchcounterone \zerocount \advance\scratchcounterone \scratchcountertwo \stoptyping The \type {by} keyword is optional. \stopoldprimitive \startnewprimitive[title={\prm {advanceby}}] This is slightly more efficient variant of \prm {advance} that doesn't look for \type {by} and therefore, if one is missing, doesn't need to push back the last seen token. Using \prm {advance} with \type {by} is nearly as efficient but takes more tokens. \stopnewprimitive \startnewprimitive[title={\prm {afterassigned}}] The \prm {afterassignment} primitive stores a token to be injected (and thereby expanded) after an assignment has happened. Unlike \prm {aftergroup}, multiple calls are not accumulated, and changing that would be too incompatible. This is why we have \prm {afterassigned}, which can be used to inject a bunch of tokens. But in order to be consistent this one is also not accumulative. \startbuffer \afterassigned{done}% \afterassigned{{\bf done}}% \scratchcounter=123 \stopbuffer \typebuffer results in: \inlinebuffer\ being typeset. \stopnewprimitive \startoldprimitive[title={\prm {afterassignment}}] The token following \prm {afterassignment}, a traditional \TEX\ primitive, is saved and gets injected (and then expanded) after a following assignment took place. \startbuffer \afterassignment !\def\MyMacro {}\quad \afterassignment !\let\MyMacro ?\quad \afterassignment !\scratchcounter 123\quad \afterassignment !% \afterassignment ?\advance\scratchcounter by 1 \stopbuffer \typebuffer The \prm {afterassignment}s are not accumulated, the last one wins: {\getbuffer} \stopoldprimitive \startoldprimitive[title={\prm {aftergroup}}] The traditional \TEX\ \prm {aftergroup} primitive stores the next token and expands that after the group has been closed. \startbuffer before{ ! \aftergroup a\aftergroup f\aftergroup t\aftergroup e\aftergroup r} \stopbuffer Multiple \prm {aftergroup}s are combined: \typebuffer \getbuffer \stopoldprimitive \startnewprimitive[title={\prm {aftergrouped}}] The in itself powerful \prm {aftergroup} primitives works quite well, even if you need to do more than one thing: you can either use it multiple times, or you can define a macro that does multiple things and apply that after the group. However, you can avoid that by using this primitive which takes a list of tokens. \startbuffer regular \bgroup \aftergrouped{regular}% \bf bold \egroup \stopbuffer \typebuffer Because it happens after the group, we're no longer typesetting in bold. {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {aliased}}] This primitive is part of the overload protection subsystem where control sequences can be tagged. \startbuffer \permanent\def\foo{FOO} \let\ofo\foo \aliased \let\oof\foo \meaningasis\foo \meaningasis\ofo \meaningasis\oof \stopbuffer \typebuffer gives: \startlines \tt \getbuffer \stoplines When a something is \prm {let} the \quote {permanent}, \quote {primitive} and \quote {immutable} flags are removed but the \prm {aliased} prefix retains them. \startbuffer \let\relaxed\relax \meaningasis\relax \meaningasis\relaxed \stopbuffer \typebuffer So in this example the \type {\relaxed} alias is not flagged as primitive: \startlines \tt \getbuffer \stoplines \stopnewprimitive \startnewprimitive[title={\prm {aligncontent}}] This is equivalent to a hash in an alignment preamble. Contrary to \prm {alignmark} there is no need to duplicate inside a macro definition. \stopnewprimitive \startnewprimitive[title={\prm {alignmark}}] When you have the \type {#} not set up as macro parameter character cq.\ align mark, you can use this primitive instead. The same rules apply with respect to multiple such tokens in (nested) macros and alignments. \stopnewprimitive \startnewprimitive[title={\prm {alignmentcellsource}}] This sets the source id (a box property) of the current alignment cell. \stopnewprimitive \startnewprimitive[title={\prm {alignmentwrapsource}}] This sets the source id (a box property) of the current alignment row (in a \prm {halign}) or column (in a \prm {valign}). \stopnewprimitive \startnewprimitive[title={\prm {aligntab}}] When you have the \type {&} not set up as align tab, you can use this primitive instead. The same rules apply with respect to multiple such tokens in (nested) macros and alignments. \stopnewprimitive \startnewprimitive[title={\prm {allcrampedstyles}}] A symbolic representation of \prm {crampeddisplaystyle}, \prm {crampedtextstyle}, \prm {crampedscriptstyle} and \prm {crampedscriptscriptstyle}; integer representation: \the\allcrampedstyles. \stopnewprimitive \startnewprimitive[title={\prm {alldisplaystyles}}] A symbolic representation of \prm {displaystyle} and \prm {crampeddisplaystyle}; integer representation: \the\alldisplaystyles. \stopnewprimitive \startnewprimitive[title={\prm {allmainstyles}}] A symbolic representation of \prm {displaystyle}, \prm {crampeddisplaystyle}, \prm {textstyle} and \prm {crampedtextstyle}; integer representation: \the\allmainstyles. \stopnewprimitive \startnewprimitive[title={\prm {allmathstyles}}] A symbolic representation of \prm {displaystyle}, \prm {crampeddisplaystyle}, \prm {textstyle}, \prm {crampedtextstyle}, \prm {scriptstyle}, \prm {crampedscriptstyle}, \prm {scriptscriptstyle} and \prm {crampedscriptscriptstyle}; integer representation: \the\allmathstyles. \stopnewprimitive \startnewprimitive[title={\prm {allscriptscriptstyles}}] A symbolic representation of \prm {scriptscriptstyle} and \prm {crampedscriptscriptstyle}; integer representation: \the\allscriptscriptstyles. \stopnewprimitive \startnewprimitive[title={\prm {allscriptstyles}}] A symbolic representation of \prm {scriptstyle} and \prm {crampedscriptstyle}; integer representation: \the\allscriptstyles. \stopnewprimitive \startnewprimitive[title={\prm {allsplitstyles}}] A symbolic representation of \prm {displaystyle} and \prm {textstyle} but not \prm {scriptstyle} and \prm {scriptscriptstyle}: set versus reset; integer representation: \the\allsplitstyles. \stopnewprimitive \startnewprimitive[title={\prm {alltextstyles}}] A symbolic representation of \prm {textstyle} and \prm {crampedtextstyle}; integer representation: \the\alltextstyles. \stopnewprimitive \startnewprimitive[title={\prm {alluncrampedstyles}}] A symbolic representation of \prm {displaystyle}, \prm {textstyle}, \prm {scriptstyle} and \prm {scriptscriptstyle}; integer representation: \the\alluncrampedstyles. \stopnewprimitive \startnewprimitive[title={\prm {allunsplitstyles}}] A symbolic representation of \prm {scriptstyle} and \prm {scriptscriptstyle}; integer representation: \the\allunsplitstyles. \stopnewprimitive \startnewprimitive[title={\prm {amcode}}] \stopnewprimitive \startnewprimitive[title={\prm {associateunit}}] The \TEX\ engine comes with some build in units, like \type {pt} (fixed) and \type {em} (adaptive). On top of that a macro package can add additional units, which is what we do in \CONTEXT. In \in {figure} [fig:units] we show the current repertoire. \startplacefigure[title=Available units,reference=fig:units] \showunitsmap[tight] \showunitsmaplegend \stopplacefigure When this primitive is used in a context where a number is expected it returns the origin of the unit (in the color legend running from 1 upto 4). A new unit is defined as: \starttyping \newdimen\MyDimenZA \MyDimenZA=10pt \protected\def\MyDimenAB{\dimexpr\hsize/2\relax} \associateunit za \MyDimenZA \associateunit zb \MyMacroZB \stoptyping Possible associations are: macros that expand to a dimension, internal dimension registers, register dimensions (\prm {dimendef}, direct dimensions (\prm {dimensiondef}) and \LUA\ functions that return a dimension. One can run into scanning ahead issues where \TEX\ expects a unit and a user unit gets expanded. This is why for instance in \CONTEXT\ we define the \type{ma} unit as: \starttyping \protected\def\mathaxisunit{\scaledmathaxis\mathstyle\norelax} \associateunit ma \mathaxisunit % or \newuserunit \mathaxisunit ma \stoptyping So that it can be used in rule specifications that themselves look ahead for keywords and therefore are normally terminated by a \prm {relax}. Adding the extra \prm {norelax} will make the scanner see one that doesn't get fed back into the input. Of course a macro package has to manage extra units in order to avoid conflicts. \stopnewprimitive \startnewprimitive[title={\prm {atendoffile}}] The \prm {everyeof} primitive is kind of useless because you don't know if a file (which can be a tokenlist processed as pseudo file) itself includes a file, which then results in nested application of this token register. One way around this is: \startbuffer \atendoffile\SomeCommand \stopbuffer \typebuffer This acts on files the same way as \prm {atendofgroup} does. Multiple calls will be accumulated and are bound to the current file. \stopnewprimitive \startnewprimitive[title={\prm {atendoffiled}}] This is the multi token variant of \prm {atendoffile}. Multiple invocations are accumulated and by default prepended to the existing list. As with grouping this permits proper nesting. You can force an append by the optional keyword {reverse}. \stopnewprimitive \startnewprimitive[title={\prm {atendofgroup}}] The token provided will be injected just before the group ends. Because these tokens are collected, you need to be aware of possible interference between them. However, normally this is managed by the macro package. \startbuffer \bgroup \atendofgroup\unskip \atendofgroup )% (but it works okay \egroup \stopbuffer \typebuffer Of course these effects can also be achieved by combining (extra) grouping with \prm {aftergroup} calls, so this is more a convenience primitives than a real necessity: {\inlinebuffer}, as proven here. \stopnewprimitive \startnewprimitive[title={\prm {atendofgrouped}}] This is the multi token variant of \prm {atendofgroup}. Of course the next example is somewhat naive when it comes to spacing and so, but it shows the purpose. \startbuffer \bgroup \atendofgrouped{\bf QED}% \atendofgrouped{ (indeed)}% This sometimes looks nicer. \egroup \stopbuffer \typebuffer Multiple invocations are accumulated: {\inlinebuffer}. \stopnewprimitive \startoldprimitive[title={\prm {atop}}][obsolete=yes] This one stack two math elements on top of each other, like a fraction but with no rule. It has a more advanced upgrade in \prm {Uatop}. \stopoldprimitive \startoldprimitive[title={\prm {atopwithdelims}}][obsolete=yes] This is a variant of \prm {atop} but with delimiters. It has a more advanced upgrade in \prm {Uatopwithdelims}. \stopoldprimitive \startnewprimitive[title={\prm {attribute}}] The following sets an attribute(register) value: \starttyping \attribute 999 = 123 \stoptyping An attribute is unset by assigning \the \attributeunsetvalue\ to it. A user needs to be aware of attributes being used now and in the future of a macro package and setting them this way is very likely going to interfere. \stopnewprimitive \startnewprimitive[title={\prm {attributedef}}] This primitive can be used to relate a control sequence to an attribute register and can be used to implement a mechanism for defining unique ones that won't interfere. As with other registers: leave management to the macro package in order to avoid unwanted side effects! \stopnewprimitive \startnewprimitive[title={\prm {automaticdiscretionary}}] This is an alias for the automatic hyphen trigger \type {-}. \stopnewprimitive \startnewprimitive[title={\prm {automatichyphenpenalty}}] The penalty injected after an automatic discretionary \type {-}, when \prm {hyphenationmode} enables this. \stopnewprimitive \startnewprimitive[title={\prm {automigrationmode}}] This bitset determines what will bubble up to an outer level: \getbuffer[engine:syntax:automigrationcodes] The current value is {\tttf 0x\tohexadecimal\automigrationmode}. \stopnewprimitive \startnewprimitive[title={\prm {autoparagraphmode}}] A paragraph can be triggered by an empty line, a \prm {par} token or an equivalent of it. This parameter controls how \type {\par} is interpreted in different scenarios: \getbuffer[engine:syntax:autoparagraphcodes] The current value is {\tttf 0x\tohexadecimal\autoparagraphmode} and setting it to a non|-|zero value can have consequences for mechanisms that expect otherwise. The text option uses the same code as an empty line. The macro option checks a token in a macro preamble against the frozen \prm {\par} token. The last option ignores the par token. \stopnewprimitive \startoldprimitive[title={\prm {badness}}] This one returns the last encountered badness value. \stopoldprimitive \startoldprimitive[title={\prm {baselineskip}}] This is the maximum glue put between lines. The depth of the previous and height of the next line are substracted. \stopoldprimitive \startoldprimitive[title={\prm {batchmode}}] This command disables (error) messages which can safe some runtime in situations where \TEX's character|-|by|-|character log output impacts runtime. It only makes sense in automated workflows where one doesn't look at the log anyway. \stopoldprimitive \startnewprimitive[title={\prm {begincsname}}] The next code creates a control sequence token from the given serialized tokens: \starttyping \csname mymacro\endcsname \stoptyping When \type {\mymacro} is not defined a control sequence will be created with the meaning \prm {relax}. A side effect is that a test for its existence might fail because it now exists. The next sequence will {\em not} create an controil sequence: \starttyping \begincsname mymacro\endcsname \stoptyping This actually is kind of equivalent to: \starttyping \ifcsname mymacro\endcsname \csname mymacro\endcsname \fi \stoptyping \stopnewprimitive \startoldprimitive[title={\prm {begingroup}}] This primitive starts a group and has to be ended with \prm {endgroup}. See \prm {beginsimplegroup} for more info. \stopoldprimitive \startnewprimitive[title={\prm {beginlocalcontrol}}] Once \TEX\ is initialized it will enter the main loop. In there certain commands trigger a function that itself can trigger further scanning and functions. In \LUAMETATEX\ we can have local main loops and we can either enter it from the \LUA\ end (which we don't discuss here) or at the \TEX\ end using this primitive. \startbuffer \scratchcounter100 \edef\whatever{ a \beginlocalcontrol \advance\scratchcounter 10 b \endlocalcontrol \beginlocalcontrol c \endlocalcontrol d \advance\scratchcounter 10 } \the\scratchcounter \whatever \the\scratchcounter \stopbuffer \typebuffer A bit of close reading probably gives an impression of what happens here: {\getbuffer} The local loop can actually result in material being injected in the current node list. However, where normally assignments are not taking place in an \prm {edef}, here they are applied just fine. Basically we have a local \TEX\ job, be it that it shares all variables with the parent loop. \stopnewprimitive \startnewprimitive[title={\prm {beginmathgroup}}] In math mode grouping with \prm {begingroup} and \prm {endgroup} in some cases works as expected, but because the math input is converted in a list that gets processed later some settings can become persistent, like changes in style or family. The engine therefore provides the alternatives \prm {beginmathgroup} and \prm {endmathgroup} that restore some properties. \stopnewprimitive \startnewprimitive[title={\prm {beginsimplegroup}}] The original \TEX\ engine distinguishes two kind of grouping that at the user end show up as: \starttyping \begingroup \endgroup \bgroup \egroup { } \stoptyping where the last two pairs are equivalent unless the scanner explicitly wants to see a left and|/|or right brace and not an equivalent. For the sake of simplify we use the aliases here. It is not possible to mix these pairs, so: \starttyping \bgroup xxx\endgroup \begingroup xxx\egroup \stoptyping will in both cases issue an error. This can make it somewhat hard to write generic grouping macros without somewhat dirty trickery. The way out is to use the generic group opener \prm {beginsimplegroup}. Internally \LUAMETATEX\ is aware of what group it currently is dealing with and there we distinguish: \starttabulate[||||] \NC simple group \NC \type {\bgroup} \NC \type {\egroup} \NC \NR \NC semi simple group \NC \type {\begingroup} \NC \type {\endgroup} \type {\endsimplegroup} \NC \NR \NC also simple group \NC \type {\beginsimplegroup} \NC \type {\egroup} \type {\endgroup} \type {\endsimplegroup} \NC \NR \NC math simple group \NC \type {\beginmathgroup} \NC \type {\endmathgroup} \NC \NR \stoptabulate This means that you can say: \starttyping \beginsimplegroup xxx\endsimplegroup \beginsimplegroup xxx\endgroup \beginsimplegroup xxx\egroup \stoptyping So a group started with \prm {beginsimplegroup} can be finished in three ways which means that the user (or calling macro) doesn't have take into account what kind of grouping was used to start with. Normally usage of this primitive is hidden in macros and not something the user has to be aware of. \stopnewprimitive \startoldprimitive[title={\prm {belowdisplayshortskip}}] The glue injected aftter a display formula when the line above it is not overlapping with the formula (\TEX\ can't look ahead). Watch out for interference with \prm {baselineskip}. It can be controlled by \prm {displayskipmode}. \stopoldprimitive \startoldprimitive[title={\prm {belowdisplayskip}}] The glue injected after a display formula. Watch out for interference with \prm {baselineskip}. It can be controlled by \prm {displayskipmode}. \stopoldprimitive \startoldprimitive[title={\prm {binoppenalty}}][obsolete=yes] This internal quantity is a compatibility feature because normally we will use the inter atom spacing variables. \stopoldprimitive \startoldprimitive[title={\prm {botmark}}][obsolete=yes] This is a reference to the last mark on the current page, it gives back tokens. \stopoldprimitive \startoldprimitive[title={\prm {botmarks}}] This is a reference to the last mark with the given id (a number) on the current page, it gives back tokens. \stopoldprimitive \startnewprimitive[title={\prm {boundary}}] Boundaries are signals added to he current list. This primitive injects a user boundary with the given (integer) value. Such a boundary can be consulted at the \LUA\ end or with \prm {lastboundary}. \stopnewprimitive \startoldprimitive[title={\prm {box}}] This is the box register accessor. While other registers have one property a box has many, like \prm {wd}, \prm {ht} and \prm {dp}. This primitive returns the box and resets the register. \stopoldprimitive \startnewprimitive[title={\prm {boxadapt}}] Adapting will recalculate the dimensions with a scale factor for the glue: \startbuffer \setbox 0 \hbox {test test test} \setbox 2 \hbox {\red test test test} \boxadapt 0 200 \setbox 4 \hbox {\blue test test test} \boxadapt 0 -200 \ruledhbox{\box0} \vskip-\lineheight \ruledhbox{\box0} \vskip-\lineheight \ruledhbox{\box0} \stopbuffer \typebuffer Like \prm {boxfreeze} and \prm {boxrepack} this primitive has been introduced for experimental usage, although we do use some in production code. \getbuffer \stopnewprimitive \startnewprimitive[title={\prm {boxanchor}}] This feature is part of an (experimental) mechanism that relates boxes. The engine just tags a box and it is up to the macro package to deal with it. \startbuffer \setbox0\hbox anchor "01010202 {test}\tohexadecimal\boxanchor0 \stopbuffer \typebuffer This gives: \inlinebuffer. Of course this feature is very macro specific and should not be used across macro packages without coordination. An anchor has two parts each not exceeding \type {0x0FFF}. \stopnewprimitive \startnewprimitive[title={\prm {boxanchors}}] This feature is part of an (experimental) mechanism that relates boxes. The engine just tags a box and it is up to the macro package to deal with it. \startbuffer \setbox0\hbox anchors "0101 "0202 {test}\tohexadecimal\boxanchors0 \stopbuffer \typebuffer This gives: \inlinebuffer. Of course this feature is very macro specific and should not be used across macro packages without coordination. An anchor has two parts each not exceeding \type {0x0FFF}. \stopnewprimitive \startnewprimitive[title={\prm {boxattribute}}] Every node, and therefore also every box gets the attributes set that are active at the moment of creation. Additional attributes can be set too: \startbuffer \darkred \setbox0\hbox attr 9999 1 {whatever} \the\boxattribute 0 \colorattribute \the\boxattribute 0 9998 \the\boxattribute 0 9999 \stopbuffer \typebuffer A macro package should make provide a way define attributes that don't clash the ones it needs itself, like, in \CONTEXT, the ones that can set a color \startlines \getbuffer \stoplines The number \the\attributeunsetvalue\ (\tohexadecimal\attributeunsetvalue) indicates an unset attribute. \stopnewprimitive \startnewprimitive[title={\prm {boxdirection}}] The direction of a box defaults to \type {l2r} but can be explicitly set: \startbuffer \setbox0\hbox direction 1 {this is a test}\textdirection1 \setbox2\hbox direction 0 {this is a test}\textdirection0 \the\boxdirection0: \box0 \the\boxdirection2: \box2 \stopbuffer \typebuffer The \prm {textdirection} does not influence the box direction: \startlines \getbuffer \stoplines \stopnewprimitive \startnewprimitive[title={\prm {boxfinalize}}] This is special version of \prm {boxfreeze} which we demonstrate with an example: \startbuffer[setthem] \setbox0\ruledvbox to 3cm{\hsize 2cm test\vskip10pt plus 10pt test} \setbox2\copy0\setbox4\copy0\setbox6\copy0\setbox8\copy0 \stopbuffer \startbuffer[usethem] \boxlimitate 0 0 % don't recurse \boxfreeze 2 0 % don't recurse \boxfinalize 4 500 % scale glue multiplier by .50 \boxfinalize 6 250 % scale glue multiplier by .25 \boxfinalize 8 100 % scale glue multiplier by .10 \hpack\bgroup \copy0\quad\copy2\quad\copy4\quad\copy6\quad\copy8 \egroup \stopbuffer \typebuffer[usethem] where the boxes are populated with: \typebuffer[setthem] \startlinecorrection \getbuffer[setthem,usethem] \stoplinecorrection \stopnewprimitive \startnewprimitive[title={\prm {boxfreeze}}] Glue in a box has a fixed component that will always be used and stretch and shrink that kicks in when needed. The effective value (width) of the glue is driven by some box parameters that are set by the packaging routine. This is why we can unbox: the original value is kept. It is the backend that calculates the effective value. Te \prm {boxfreeze} primitive can do the same: turn the flexible glue into a fixed one. \startbuffer \setbox 0 \hbox to 6cm {\hss frost} \setbox 2 \hbox to 6cm {\hss frost} \boxfreeze 2 0 \ruledhbox{\unhbox 0} \ruledhbox{\unhbox 2} \stopbuffer \typebuffer The second parameter to \prm {boxfreeze} determines recursion. We don't recurse here so just freeze the outer level: \getbuffer \stopnewprimitive \startnewprimitive[title={\prm {boxgeometry}}] A box can have an orientation, offsets and|/|or anchors. These are stored independently but for efficiency reasons we register if one or more of these properties is set. This primitive accesses this state; it is a bitset: \getbuffer[engine:syntax:listgeometrycodes] \stopnewprimitive \startnewprimitive[title={\prm {boxlimit}}] This primitive will freeze the glue in a box but only when there is glue marked with the limit option. \stopnewprimitive \startnewprimitive[title={\prm {boxlimitate}}] This primitive will freeze the glue in a box. It takes two arguments, a box number and an number that when set to non|-|zero will recurse into nested lists. \stopnewprimitive \startnewprimitive[title={\prm {boxlimitmode}}] This variable controls if boxes with glue marked \quote {limit} will be checked and frozen. \stopnewprimitive \startoldprimitive[title={\prm {boxmaxdepth}}] You can limit the depth of boxes being constructed. It's one of these parameters that should be used with care because when that box is filled nested boxes can be influenced. \stopoldprimitive \startnewprimitive[title={\prm {boxorientation}}] The orientation field can take quite some values and is discussed in one of the low level \CONTEXT\ manuals. Some properties are dealt with in the \TEX\ engine because they influence dimensions but in the end it is the backend that does the work. \stopnewprimitive \startnewprimitive[title={\prm {boxrepack}}] When a box of to wide or tight we can tweak it a bit with this primitive. The primitive expects a box register and a dimension, where a positive number adds and a negatie subtracts from the current box with. \startbuffer \setbox 0 \hbox {test test test} \setbox 2 \hbox {\red test test test} \boxrepack0 +.2em \setbox 4 \hbox {\green test test test} \boxrepack0 -.2em \ruledhbox{\box0} \vskip-\lineheight \ruledhbox{\box0} \vskip-\lineheight \ruledhbox{\box0} \stopbuffer \typebuffer \getbuffer We can also use this primitive to check the natural dimensions of a box: \startbuffer \setbox 0 \hbox spread 10pt {test test test} \ruledhbox{\box0} (\the\boxrepack0,\the\wd0) \stopbuffer \typebuffer In this context only one argument is expected. \getbuffer \stopnewprimitive \startnewprimitive[title={\prm {boxshift}}] Returns or sets how much the box is shifted: up or down in horizontally mode, left or right in vertical mode. \stopnewprimitive \startnewprimitive[title={\prm {boxshrink}}] Returns the amount of shrink found (applied) in a box: \startbuffer \setbox0\hbox to 4em {m m m m} \the\boxshrink0 \stopbuffer \typebuffer gives: \inlinebuffer \stopnewprimitive \startnewprimitive[title={\prm {boxsource}}] This feature is part of an (experimental) mechanism that relates boxes. The engine just tags a box and it is up to the macro package to deal with it. \startbuffer \setbox0\hbox source 123 {m m m m} \the\boxsource0 \stopbuffer \typebuffer This gives: \inlinebuffer. Of course this feature is very macro specific and should not be used across macro packages without coordination. \stopnewprimitive \startnewprimitive[title={\prm {boxstretch}}] Returns the amount of stretch found (applied) in a box: \startbuffer \setbox0\hbox to 6em {m m m m} \the\boxstretch0 \stopbuffer \typebuffer gives: \inlinebuffer \stopnewprimitive \startnewprimitive[title={\prm {boxtarget}}] This feature is part of an (experimental) mechanism that relates boxes. The engine just tags a box and it is up to the macro package to deal with it. \startbuffer \setbox0\hbox source 123 {m m m m} \the\boxsource0 \stopbuffer \typebuffer This gives: \inlinebuffer. Of course this feature is very macro specific and should not be used across macro packages without coordination. \stopnewprimitive \startnewprimitive[title={\prm {boxtotal}}] Returns the total of height and depth of the given box. \stopnewprimitive \startnewprimitive[title={\prm {boxvadjust}}] When used as query this returns a bitset indicating the associated adjust and migration (marks and inserts) data: \starttabulate[|T|l|] \NC 0x1 \NC pre adjusted \NC \NR \NC 0x2 \NC post adjusted \NC \NR \NC 0x4 \NC pre migrated \NC \NR \NC 0x8 \NC post migrated \NC \NR \stoptabulate\ When used as a setter it directly adds adjust data to the box and it accepts the same keywords as \prm {vadjust}. \stopnewprimitive \startnewprimitive[title={\prm {boxxmove}}] This will set the vertical offset and adapt the dimensions accordingly. \stopnewprimitive \startnewprimitive[title={\prm {boxxoffset}}] Returns or sets the horizontal offset of the given box. \stopnewprimitive \startnewprimitive[title={\prm {boxymove}}] This will set the vertical offset and adapt the dimensions accordingly. \stopnewprimitive \startnewprimitive[title={\prm {boxyoffset}}] Returns or sets the vertical offset of the given box. \stopnewprimitive \startoldprimitive[title={\prm {brokenpenalty}}] This penalty is added after a line that ends with a hyphen; it can help to discourage a page break (or split in a box). \stopoldprimitive \startoldprimitive[title={\prm {catcode}}] Every character can be put in a category, but this is typically something that the macro package manages because changes can affect behavior. Also, once passed as an argument, the catcode of a character is frozen. There are 16 different values: \starttabulate[|l|c|l|c|] \NC \type {\escapecatcode } \NC \the\escapecatcode \NC \type {\begingroupcatcode } \NC \the\begingroupcatcode \NC \NR \NC \type {\endgroupcatcode } \NC \the\endgroupcatcode \NC \type {\mathshiftcatcode } \NC \the\mathshiftcatcode \NC \NR \NC \type {\alignmentcatcode } \NC \the\alignmentcatcode \NC \type {\endoflinecatcode } \NC \the\endoflinecatcode \NC \NR \NC \type {\parametercatcode } \NC \the\parametercatcode \NC \type {\superscriptcatcode} \NC \the\superscriptcatcode \NC \NR \NC \type {\subscriptcatcode } \NC \the\subscriptcatcode \NC \type {\ignorecatcode } \NC \the\ignorecatcode \NC \NR \NC \type {\spacecatcode } \NC \the\spacecatcode \NC \type {\lettercatcode } \NC \the\lettercatcode \NC \NR \NC \type {\othercatcode } \NC \the\othercatcode \NC \type {\activecatcode } \NC \the\activecatcode \NC \NR \NC \type {\commentcatcode } \NC \the\commentcatcode \NC \type {\invalidcatcode } \NC \the\invalidcatcode \NC \NR \stoptabulate The first column shows the constant that \CONTEXT\ provides and the name indicates the purpose. Here are two examples: \starttyping \catcode123=\begingroupcatcode \catcode125=\endgroupcatcode \stoptyping \stopoldprimitive \startnewprimitive[title={\prm {catcodetable}}] The catcode table with the given index will become active. \stopnewprimitive \startnewprimitive[title={\prm {cdef}}] This primitive is like \prm {edef} but in some usage scenarios is slightly more efficient because (delayed) expansion is ignored which in turn saves building a temporary token list. \startbuffer \edef\FooA{this is foo} \meaningfull\FooA\crlf \cdef\FooB{this is foo} \meaningfull\FooB\par \stopbuffer \typebuffer {\tttf \getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {cdefcsname}}] This primitive is like \prm {edefcsame} but in some usage scenarios is slightly more efficient because (delayed) expansion is ignored which in turn saves building a temporary token list. \startbuffer \edefcsname FooA\endcsname{this is foo} \meaningasis\FooA\crlf \cdefcsname FooB\endcsname{this is foo} \meaningasis\FooB\par \stopbuffer \typebuffer {\tttf \getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {cfcode}}] This primitive is a companion to \prm {efcode} and sets the compression factor. It takes three values: font, character code, and factor. \stopnewprimitive \startoldprimitive[title={\prm {char}}] This appends a character with the given index in the current font. \stopoldprimitive \startoldprimitive[title={\prm {chardef}}] The following definition relates a control sequence to a specific character: \starttyping \chardef\copyrightsign"A9 \stoptyping However, because in a context where a number is expected, such a \prm {chardef} is seen as valid number, there was a time when this primitive was used to define constants without overflowing the by then limited pool of count registers. In \ETEX\ aware engines this was less needed, and in \LUAMETATEX\ we have \prm {integerdef} as a more natural candidate. \stopoldprimitive \startoldprimitive[title={\prm {cleaders}}] See \prm {gleaders} for an explanation. \stopoldprimitive \startnewprimitive[title={\prm {clearmarks}}] This primitive is an addition to the multiple marks mechanism that originates in \ETEX\ and reset the mark registers of the given category (a number). \stopnewprimitive \startoldprimitive[title={\prm {clubpenalties}}] This is an array of penalty put before the first lines in a paragraph. High values discourage (or even prevent) a lone line at the end of a page. This command expects a count value indicating the number of entries that will follow. The first entry is ends up after the first line. \stopoldprimitive \startoldprimitive[title={\prm {clubpenalty}}] This is the penalty put before a club line in a paragraph. High values discourage (or even prevent) a lone line at the end of a next page. \stopoldprimitive \startnewprimitive[title={\prm {constant}}] This prefix tags a macro (without arguments) as being constant. The main consequence is that in some cases expansion gets delayed which gives a little performance boost and less (temporary) memory usage, for instance in \type {\csname} like scenarios. \stopnewprimitive \startnewprimitive[title={\prm {constrained}}] See previous section about \prm {retained}. \stopnewprimitive \startoldprimitive[title={\prm {copy}}] This is the box register accessor that returns a copy of the box. \stopoldprimitive % \startnewprimitive[title={\prm {copymathatomrule}}] % \stopnewprimitive % \startnewprimitive[title={\prm {copymathparent}}] % \stopnewprimitive % \startnewprimitive[title={\prm {copymathspacing}}] % \stopnewprimitive \startoldprimitive[title={\prm {count}}] This accesses a count register by index. This is kind of \quote {not done} unless you do it local and make sure that it doesn't influence macros that you call. \starttyping \count4023=10 \stoptyping In standard \TEX\ the first 10 counters are special because they get reported to the console, and \type {\count0} is then assumed to be the page counter. \stopoldprimitive \startoldprimitive[title={\prm {countdef}}] This primitive relates a control sequence to a count register. Compare this to the example in the previous section. \starttyping \countdef\MyCounter4023 \MyCounter=10 \stoptyping However, this is also \quote {not done}. Instead one should use the allocator that the macro package provides. \starttyping \newcount\MyCounter \MyCounter=10 \stoptyping In \LUAMETATEX\ we also have integers that don't rely on registers. These are assigned by the primitive \prm {integerdef}: \starttyping \integerdef\MyCounterA 10 \stoptyping Or better \type {\newinteger}. \starttyping \newinteger\MyCounterB \MyCounterN10 \stoptyping There is a lowlevel manual on registers. \stopoldprimitive \startoldprimitive[title={\prm {cr}}] This ends a row in an alignment. It also ends an alignment preamble. \stopoldprimitive \startnewprimitive[title={\prm {crampeddisplaystyle}}] A less spacy alternative of \prm {displaystyle}; integer representation: \the\scriptstyle. \stopnewprimitive \startnewprimitive[title={\prm {crampedscriptscriptstyle}}] A less spacy alternative of \prm {scriptscriptstyle}; integer representation: \the\scriptscriptstyle. \stopnewprimitive \startnewprimitive[title={\prm {crampedscriptstyle}}] A less spacy alternative of \prm {scriptstyle}; integer representation: \the\scriptstyle. \stopnewprimitive \startnewprimitive[title={\prm {crampedtextstyle}}] A less spacy alternative of \prm {textstyle}; integer representation: \the\textstyle. \stopnewprimitive \startoldprimitive[title={\prm {crcr}}] This ends a row in an alignment when it hasn't ended yet. \stopoldprimitive \startnewprimitive[title={\prm {csactive}}] Because \LUATEX\ (and \LUAMETATEX) are \UNICODE\ engines active characters are implemented a bit differently. They don't occupy a eight bit range of characters but are stored as control sequence with a special prefix \type {U+FFFF} which never shows up in documents. The \prm {csstring} primitive injects the name of a control sequence without leading escape character, the \prm {csactive} injects the internal name of the following (either of not active) character. As we cannot display the prefix: \type {\csactive~} will inject the \UTF\ sequences for \type {U+FFFF} and \type {U+007E}, so here we get the bytes \type {EFBFBF7E}. Basically the next token is preceded by \prm {string}, so when you don't provide a character you are in for a surprise. \stopnewprimitive \startoldprimitive[title={\prm {csname}}] This original \TEX\ primitive starts the construction of a control sequence reference. It does a lookup and when no sequence with than name is found, it will create a hash entry and defaults its meaning to \prm {relax}. \starttyping \csname letters and other characters\endcsname \stoptyping \stopoldprimitive \startnewprimitive[title={\prm {csstring}}] This primitive returns the name of the control sequence given without the leading escape character (normally a backslash). Of course you could strip that character with a simple helper but this is more natural. \startbuffer \csstring\mymacro \stopbuffer \typebuffer We get the name, not the meaning: {\tt \inlinebuffer}. \stopnewprimitive \startoldprimitive[title={\prm {currentgrouplevel}}] \startbuffer [\the\currentgrouplevel] \bgroup [\the\currentgrouplevel] \bgroup [\the\currentgrouplevel] \egroup [\the\currentgrouplevel] \egroup [\the\currentgrouplevel] \stopbuffer The next example gives: \inlinebuffer. \typebuffer \stopoldprimitive \startoldprimitive[title={\prm {currentgrouptype}}] \startbuffer [\the\currentgrouptype] \bgroup [\the\currentgrouptype] \begingroup [\the\currentgrouptype] \endgroup [\the\currentgrouptype] [\the\currentgrouptype] \beginmathgroup [\the\currentgrouptype] \endmathgroup [\the\currentgrouptype] [\the\currentgrouptype] \egroup \stopbuffer The next example gives: \inlinebuffer. \typebuffer The possible values depend in the engine and for \LUAMETATEX\ they are: \startluacode context.startcolumns { n = 4 } context.starttabulate { "|r|l|" } for i=0,#tex.groupcodes do context.NC() context(i) context.NC() context(tex.groupcodes[i]) context.NC() context.NR() end context.stoptabulate() context.stopcolumns() \stopluacode \stopoldprimitive \startoldprimitive[title={\prm {currentifbranch}}] \startbuffer [\the\currentifbranch] \iftrue [\the\currentifbranch] \iffalse [\the\currentifbranch] \else [\the\currentifbranch] \fi [\the\currentifbranch] \fi [\the\currentifbranch] \stopbuffer The next example gives: \inlinebuffer. \typebuffer So when in the \quote {then} branch we get plus one and when in the \quote {else} branch we end up with a minus one. \stopoldprimitive \startoldprimitive[title={\prm {currentiflevel}}] \startbuffer [\the\currentiflevel] \iftrue [\the\currentiflevel]\iftrue [\the\currentiflevel] \iftrue [\the\currentiflevel] \fi [\the\currentiflevel] \fi [\the\currentiflevel] \fi [\the\currentiflevel] \stopbuffer The next example gives: \inlinebuffer. \typebuffer \stopoldprimitive \startoldprimitive[title={\prm {currentiftype}}] \startbuffer [\the\currentiftype] \iftrue [\the\currentiftype]\iftrue [\the\currentiftype] \iftrue [\the\currentiftype] \fi [\the\currentiftype] \fi [\the\currentiftype] \fi [\the\currentiftype] \stopbuffer The next example gives: \inlinebuffer. \typebuffer The values are engine dependent: \startluacode local t = tex.getiftypes() context.startcolumns { n = 5 } context.starttabulate { "|r|l|" } for i=0,#tex.groupcodes do context.NC() context(i) context.NC() context(t[i]) context.NC() context.NR() end context.stoptabulate() context.stopcolumns() \stopluacode \stopoldprimitive \startnewprimitive[title={\prm {currentloopiterator}}] Here we show the different expanded loop variants: \startbuffer \edef\testA{\expandedloop 1 10 1{!}} \edef\testB{\expandedrepeat 10 {!}} \edef\testC{\expandedendless {\ifnum\currentloopiterator>10 \quitloop\else !\fi}} \edef\testD{\expandedendless {\ifnum#I>10 \quitloop\else !\fi}} \stopbuffer \typebuffer \getbuffer All these give the same result: \startlines \tt \meaningasis\testA \meaningasis\testB \meaningasis\testC \meaningasis\testD \stoplines The \type {#I} is a shortcut to the current loop iterator; other shortcuts are \type {#P} for the parent iterator value and \type {#G} for the grand parent. \stopnewprimitive \startnewprimitive[title={\prm {currentloopnesting}}] This integer reports how many nested loops are currently active. Of course in practice the value only has meaning when you know at what outer level your nested loop started. \stopnewprimitive \startnewprimitive[title={\prm {currentmarks}}] Marks only get updated when a page is split off or part of a box using \prm {vsplit} gets wrapped up. This primitive gives access to the current value of a mark and takes the number of a mark class. \stopnewprimitive \startoldprimitive[title={\prm {currentstacksize}}] This is more diagnostic feature than a useful one but we show it anyway. There is some basic overhead when we enter a group: \startbuffer \bgroup [\the\currentstacksize] \bgroup [\the\currentstacksize] \bgroup [\the\currentstacksize] [\the\currentstacksize] \egroup [\the\currentstacksize] \egroup [\the\currentstacksize] \egroup \stopbuffer \typebuffer \getbuffer As soon as we define something or change a value, the stack gets populated by information needed for recovery after the group ends. \startbuffer \bgroup [\the\currentstacksize] \scratchcounter 1 \bgroup [\the\currentstacksize] \scratchdimen 1pt \scratchdimen 2pt \bgroup [\the\currentstacksize] \scratchcounter 2 \scratchcounter 3 [\the\currentstacksize] \egroup [\the\currentstacksize] \egroup [\the\currentstacksize] \egroup \stopbuffer \typebuffer \getbuffer The stack also keeps some state information, for instance when a box is being built. In \LUAMETATEX\ that is is quite a bit more than in other engines but it is compensated by more efficient save stack handling elsewhere. \startbuffer \hbox \bgroup [\the\currentstacksize] \hbox \bgroup [\the\currentstacksize] \hbox \bgroup [\the\currentstacksize] [\the\currentstacksize] \egroup [\the\currentstacksize] \egroup [\the\currentstacksize] \egroup \stopbuffer \typebuffer \getbuffer \stopoldprimitive \startoldprimitive[title={\prm {day}}] This internal number starts out with the day that the job started. \stopoldprimitive \startnewprimitive[title={\prm {dbox}}] A \prm {dbox} is just a \prm {vbox} (baseline at the bottom) but it has the property \quote {dual baseline} which means that is some cases it will behave like a \prm {vtop} (baseline at the top) too. Like: \ruledhbox\bgroup \showstruts \ruleddbox {\hsize 3cm \strut dbox \par \strut dbox \par\strut dbox } \ruledvbox {\hsize 3cm \strut vbox \par \strut vbox \par\strut vbox } \ruledvtop {\hsize 3cm \strut vtop \par \strut vtop \par\strut vtop } \ruledvcenter{\hsize 3cm \strut vcenter \par \strut vcenter \par\strut vcenter}% \egroup A \type {\dbox} behaves like a \type {\vtop} when it's appended to a vertical list which means that the height of the first box or rule determines the (base)line correction that gets applied. % This example is taken from lowlevel-boxes: \startlinecorrection \startcombination [nx=3,ny=1,location=top] {\vbox \bgroup \hsize .3\textwidth \small\small \setupalign[tolerant,stretch] \dontcomplain xxxxxxxxxxxxxxxx\par \ruledvbox{\samplefile{ward}}\par xxxxxxxxxxxxxxxx\par \egroup} {\type {\vbox}} {\vbox \bgroup \hsize .3\textwidth \small\small \setupalign[tolerant,stretch] \dontcomplain xxxxxxxxxxxxxxxx\par \ruledvtop{\samplefile{ward}}\par xxxxxxxxxxxxxxxx\par \egroup} {\type {\vtop}} {\vbox \bgroup \hsize .3\textwidth \small\small \setupalign[tolerant,stretch] \dontcomplain xxxxxxxxxxxxxxxx\par \ruleddbox{\samplefile{ward}}\par xxxxxxxxxxxxxxxx\par \egroup} {\type {\dbox}} \stopcombination \stoplinecorrection \stopnewprimitive \startoldprimitive[title={\prm {deadcycles}}] This counter is incremented every time the output routine is entered. When \prm {maxdeadcycles} is reached \TEX\ will issue an error message, so you'd better reset its value when a page is done. \stopoldprimitive \startoldprimitive[title={\prm {def}}] This is the main definition command, as in: \starttyping \def\foo{l me} \stoptyping with companions like \prm {gdef}, \prm {edef}, \prm {xdef}, etc. and variants like: \starttyping \def\foo#1{... #1...} \stoptyping where the hash is used in the preamble and for referencing. More about that can be found in the low level manual about macros. \stopoldprimitive \startoldprimitive[title={\prm {defaulthyphenchar}}][obsolete=yes] When a font is loaded its hyphen character is set to this value. It can be changed afterwards. However, in \LUAMETATEX\ font loading is under \LUA\ control so these properties can be set otherwise. \stopoldprimitive \startoldprimitive[title={\prm {defaultskewchar}}][obsolete=yes] When a font is loaded its skew character is set to this value. It can be changed afterwards. However, in \LUAMETATEX\ font loading is under \LUA\ control so these properties can be set otherwise. Also, \OPENTYPE\ math fonts have top anchor instead. \stopoldprimitive \startnewprimitive[title={\prm {defcsname}}] We now get a series of log clutter avoidance primitives. It's fine if you argue that they are not really needed, just don't use them. \starttyping \expandafter\def\csname MyMacro:1\endcsname{...} \defcsname MyMacro:1\endcsname{...} \stoptyping The fact that \TEX\ has three (expanded and global) companions can be seen as a signal that less verbosity makes sense. It's just that macro packages use plenty of \prm {csname}'s. \stopnewprimitive \startnewprimitive[title={\prm {deferred}}] This is mostly a compatibility prefix and it can be checked at the \LUA\ end when there is a \LUA\ based assignment going on. It is the counterpart of \prm {immediate}. In the traditional engines a \prm {write} is normally deferred (turned into a node) and can be handled \prm {immediate}, while a \prm {special} does the opposite. \stopnewprimitive \startoldprimitive[title={\prm {delcode}}][obsolete=yes] This assigns delimiter properties to an eight bit character so it has little use in an \OPENTYPE\ math setup. WHen the assigned value is hex encoded, the first byte denotes the small family, then we have two bytes for the small index, followed by three similar bytes for the large variant. \stopoldprimitive \startoldprimitive[title={\prm {delimiter}}][obsolete=yes] This command inserts a delimiter with the given specification. In \OPENTYPE\ math we use a different command so it is unlikely that this primitive is used in \LUAMETATEX. It takes a number that can best be coded hexadecimal: one byte for the class, one for the small family, two for the small index, one for the large family and two for the large index. This demonstrates that it can't handle wide fonts. Also, in \OPENTYPE\ math fonts the larger sizes and extensible come from the same font as the small symbol. On top of that, in \LUAMETATEX\ we have more classes than fit in a byte. \stopoldprimitive \startoldprimitive[title={\prm {delimiterfactor}}][obsolete=yes] This is one of the parameters that determines the size of a delimiter: at least this factor times the formula height divided by 1000. In \OPENTYPE\ math different properties and strategies are used. \stopoldprimitive \startoldprimitive[title={\prm {delimitershortfall}}][obsolete=yes] This is one of the parameters that determines the size of a delimiter: at least the formula height minus this parameter. In \OPENTYPE\ math different properties and strategies are used. \stopoldprimitive \startnewprimitive[title={\prm {detokened}}] The following token will be serialized into characters with category \quote {other}. \startbuffer \toks0{123} \def\foo{let's be \relax'd} \def\oof#1{let's see #1} \detokened\toks0 \detokened\foo \detokened\oof \detokened\setbox \detokened X \stopbuffer \typebuffer Gives: \startlines\tt \getbuffer \stoplines Macros with arguments are not shown. \stopnewprimitive \startoldprimitive[title={\prm {detokenize}}] This \ETEX\ primitive turns the content of the provides list will become characters, kind of verbatim. \startbuffer \expandafter\let\expandafter\temp\detokenize{1} \meaning\temp \expandafter\let\expandafter\temp\detokenize{A} \meaning\temp \stopbuffer \typebuffer \startlines \tttf \getbuffer \stoplines \stopoldprimitive \startnewprimitive[title={\prm {detokenized}}] The following (single) token will be serialized into characters with category \quote {other}. \startbuffer \toks0{123} \def\foo{let's be \relax'd} \def\oof#1{let's see #1} \detokenized\toks0 \detokenized\foo \detokenized\oof \detokenized\setbox \detokenized X \stopbuffer \typebuffer Gives: \startlines\tt \getbuffer \stoplines It is one of these new primitives that complement others like \prm {detokened} and such, and they are often mostly useful in experiments of some low level magic, which made them stay. \stopnewprimitive \startoldprimitive[title={\prm {dimen}}] Like \prm {count} this is a register accessor which is described in more detail in a low level manual. \starttyping \dimen0=10pt \stoptyping While \TEX\ has some assumptions with respect to the first ten count registers (as well as the one that holds the output, normally 255), all dimension registers are treated equal. However, you need to be aware of clashes with other usage. Therefore you can best use the predefined scratch registers or define dedicate ones with the \type {\newdimen} macro. \stopoldprimitive \startoldprimitive[title={\prm {dimendef}}] This primitive is used by the \type {\newdimen} macro when it relates a control sequence with a specific register. Only use it when you know what you're doing. \stopoldprimitive \startnewprimitive[title={\prm {dimensiondef}}] A variant of \prm {integerdef} is: \starttyping \dimensiondef\MyDimen = 1234pt \stoptyping The properties are comparable to the ones described in the section \prm {integerdef}. \stopnewprimitive \startoldprimitive[title={\prm {dimexpr}}] This primitive is similar to of \prm {numexpr} but operates on dimensions instead. Integer quantities are interpreted as dimensions in scaled points. \startbuffer \the\dimexpr (1pt + 2pt - 5pt) * 10 / 2 \relax \stopbuffer \typebuffer gives: \inlinebuffer. You can mix in symbolic integers and dimensions. This doesn't work: \startbuffer \the\dimexpr 10 * (1pt + 2pt - 5pt) / 2 \relax \stopbuffer because the engine scans for a dimension and only for an integer (or equivalent) after a \type {*} or \type {/}. \stopoldprimitive \startnewprimitive[title={\prm {dimexpression}}] This command is like \prm {numexpression} but results in a dimension instead of an integer. Where \prm {dimexpr} doesn't like \typ {2 * 10pt} this expression primitive is quite happy with it. \stopnewprimitive \startnewprimitive[title={\prm {directlua}}] This is the low level interface to \LUA: \startbuffer \directlua { tex.print ("Greetings from the lua end!") } \stopbuffer Gives: \quotation {\inlinebuffer} as expected. In \LUA\ we have access to all kind of internals of the engine. In \LUAMETATEX\ the interfaces have been polished and extended compared to \LUATEX. Although many primitives and mechanisms were added to the \TEX\ frontend, the main extension interface remains \LUA. More information can be found in documents that come with \CONTEXT, in presentations and in articles. \stopnewprimitive \startoldprimitive[title={\prm {discretionary}}] The three snippets given with this command determine the pre, post and replace component of the injected discretionary node. The \type {penalty} keyword permits setting a penalty with this node. The \type {postword} keyword indicates that this discretionary starts a word, and \type {preword} ends it. With \type {break} the line break algorithm will prefer a pre or post component over a replace, and with \type {nobreak} replace will win over pre. With \type {class} you can set a math class that will determine spacing and such for discretionaries used in math mode. \stopoldprimitive \startnewprimitive[title={\prm {discretionaryoptions}}] Processing of discretionaries is controlled by this bitset: \getbuffer[engine:syntax:discoptioncodes] These can also be set on \prm {discretionary} using the \type {options} key. \stopnewprimitive \startoldprimitive[title={\prm {displayindent}}] The \prm {displaywidth}, \prm {displayindent} and \prm {predisplaysize} parameters are set by the line break routine (but can be adapted by the user), so that mid|-|par display formula can adapt itself to hanging indentation and par shapes. I order to calculate thee values and adapt the line break state afterwards such a display formula is assumed to occupy three lines, so basically a rather compact formula. \stopoldprimitive \startoldprimitive[title={\prm {displaylimits}}] By default in math display mode limits are place on top while in inline mode they are placed like scripts, after the operator. Placement can be forced with the \prm {limits} and \prm {nolimits} modifiers (after the operator). Because there can be multiple of these in a row there is \prm {displaylimits} that forces the default placement, so effectively it acts here as a reset modifier. \stopoldprimitive \startoldprimitive[title={\prm {displaystyle}}] One of the main math styles; integer representation: \the\displaystyle. \stopoldprimitive \startoldprimitive[title={\prm {displaywidowpenalties}}] This is a math specific variant of \prm {widowpenalties}. \stopoldprimitive \startoldprimitive[title={\prm {displaywidowpenalty}}] This is a math specific variant of \prm {widowpenalty}. \stopoldprimitive \startoldprimitive[title={\prm {displaywidth}}] This parameter determines the width of the formula and normally defaults to the \prm {hsize} unless we are in the middle of a paragraph in which case it is compensated for hanging indentation or the par shape. \stopoldprimitive \startoldprimitive[title={\prm {divide}}] The \prm {divide} operation can be applied to integers, dimensions, float, attribute and glue quantities. There are subtle rounding differences between the divisions in expressions and \prm {divide}: \starttabulate \NC \type {\scratchcounter1049 \numexpr\scratchcounter/ 10\relax} \EQ \scratchcounter1049 \the\numexpr\scratchcounter/ 10\relax \NC \NR \NC \type {\scratchcounter1049 \numexpr\scratchcounter: 10\relax} \EQ \scratchcounter1049 \the\numexpr\scratchcounter: 10\relax \NC \NR \NC \type {\scratchcounter1049 \divide\scratchcounter by 10} \EQ \scratchcounter1049 \divide\scratchcounter by 10 \the\scratchcounter \NC \NR \stoptabulate The \type {:} divider in \prm {dimexpr} is something that we introduced in \LUATEX. \stopoldprimitive \startnewprimitive[title={\prm {divideby}}] This is slightly more efficient variant of \prm {divide} that doesn't look for \type {by}. See previous section. \stopnewprimitive \startnewprimitive[title={\prm {doubleadjdemerits}}] This penalty will be added to the penalty assigned to a breakpoint that results in two incompatible lines (in \LUAMETATEX\ we can be more granular with respect to compatible lines and this concerns a larger delta). \stopnewprimitive \startoldprimitive[title={\prm {doublehyphendemerits}}] This penalty will be added to the penalty assigned to a breakpoint that results in two lines ending with a hyphen. \stopoldprimitive \startoldprimitive[title={\prm {dp}}] Returns the depth of the given box. \stopoldprimitive \startnewprimitive[title={\prm {dpack}}] This does what \prm {dbox} does but without callback overhead. \stopnewprimitive \startnewprimitive[title={\prm {dsplit}}] This is the dual baseline variant of \prm {vsplit} (see \prm {dbox} for what that means). \stopnewprimitive \startoldprimitive[title={\prm {dump}}] This finishes an (ini) run and dumps a format (basically the current state of the engine). \stopoldprimitive \startoldprimitive[title={\prm {edef}}] This is the expanded version of \prm {def}. \startbuffer \def \foo{foo} \meaning\foo \def \ofo{\foo\foo} \meaning\ofo \edef\oof{\foo\foo} \meaning\oof \stopbuffer \typebuffer Because \type {\foo} is unprotected it will expand inside the body definition: \startlines \tt \getbuffer \stoplines \stopoldprimitive \startnewprimitive[title={\prm {edefcsname}}] This is the companion of \prm {edef}: \starttyping \expandafter\edef\csname MyMacro:1\endcsname{...} \edefcsname MyMacro:1\endcsname{...} \stoptyping \stopnewprimitive \startnewprimitive[title={\prm {edivide}}] When expressions were introduced the decision was made to round the divisions which is incompatible with the way \prm {divide} works. The expression scanners in \LUAMETATEX\ compensates that by providing a \type {:} for integer division. The \prm {edivide} does the opposite: it rounds the way expressions do. \startbuffer \the\dimexpr .4999pt : 2 \relax =.24994pt \the\dimexpr .4999pt / 2 \relax =.24995pt \scratchdimen.4999pt \divide \scratchdimen 2 \the\scratchdimen=.24994pt \scratchdimen.4999pt \edivide\scratchdimen 2 \the\scratchdimen=.24995pt \the\numexpr 1001 : 2 \relax =500 \the\numexpr 1001 / 2 \relax =501 \scratchcounter1001 \divide \scratchcounter 2 \the\scratchcounter=500 \scratchcounter1001 \edivide\scratchcounter 2 \the\scratchcounter=501 \stopbuffer \typebuffer Keep in mind that with dimensions we have a fractional part so we actually rounding applies to the fraction. For that reason we also provide \prm {rdivide}. \startlines \getbuffer \stoplines \stopnewprimitive \startnewprimitive[title={\prm {edivideby}}] This the \type {by}|-|less variant of \prm {edivide}. \stopnewprimitive \startnewprimitive[title={\prm {efcode}}] This primitive originates in \PDFTEX\ and can be used to set the expansion factor of a glyph (characters). This primitive is obsolete because the values can be set in the font specification that gets passed via \LUA\ to \TEX. Keep in mind that setting font properties at the \TEX\ end is a global operation and can therefore influence related fonts. In \LUAMETATEX\ the \prm {cf} code can be used to specify the compression factor independent from the expansion factor. The primitive takes three values: font, character code, and factor. \stopnewprimitive \startoldprimitive[title={\prm {else}}] This traditional primitive is part of the condition testing mechanism. When a condition matches, \TEX\ will continue till it sees an \prm {else} or \prm {or} or \prm {orelse} (to be discussed later). It will then do a fast skipping pass till it sees an \prm {fi}. \stopoldprimitive \startoldprimitive[title={\prm {emergencyextrastretch}}] This is one of the extended parbuilder parameters. You can you it so temporary increase the permitted stretch without knowing or messing with the normal value. \stopoldprimitive \startnewprimitive[title={\prm {emergencyleftskip}}] This is one of the extended parbuilder parameters (playground). It permits going ragged left in case of a too bad result. \stopnewprimitive \startnewprimitive[title={\prm {emergencyrightskip}}] This is one of the extended parbuilder parameters (playground). It permits going ragged right in case of a too bad result. \stopnewprimitive \startoldprimitive[title={\prm {emergencystretch}}] When set the par builder will run a third pass in order to fit the set criteria. \stopoldprimitive \startoldprimitive[title={\prm {end}}] This ends a \TEX\ run, unless of course this primitive is redefined. \stopoldprimitive \startoldprimitive[title={\prm {endcsname}}] This primitive is used in combination with \prm {csname}, \prm {ifcsname} and \prm {begincsname} where its end the scanning for the to be constructed control sequence token. \stopoldprimitive \startoldprimitive[title={\prm {endgroup}}] This is the companion of the \prm {begingroup} primitive that opens a group. See \prm {beginsimplegroup} for more info. \stopoldprimitive \startoldprimitive[title={\prm {endinput}}] The engine can be in different input modes: reading from file, reading from a token list, expanding a macro, processing something that comes back from \LUA, etc. This primitive quits reading from file: \startbuffer this is seen \endinput here we're already quit \stopbuffer \typebuffer There is a catch. This is what the above gives: \getbuffer but how about this: \startbuffer this is seen before \endinput after here we're already quit \stopbuffer \typebuffer Here we get: \getbuffer Because a token list is one line, the following works okay: \starttyping \def\quitrun{\ifsomething \endinput \fi} \stoptyping but in a file you'd have to do this when you quit in a conditional: \starttyping \ifsomething \expandafter \endinput \fi \stoptyping While the one|-|liner works as expected: \starttyping \ifsomething \endinput \fi \stoptyping \stopoldprimitive \startoldprimitive[title={\prm {endlinechar}}] This is an internal integer register. When set to positive value the character with that code point will be appended to the line. The current value is \the \endlinechar. Here is an example: \startbuffer \endlinechar\hyphenasciicode line 1 line 2 \stopbuffer \typebuffer \start \getbuffer \stop If the character is active, the property is honored and the command kicks in. The maximum value is 127 (the maximum character code a single byte \UTF\ character can carry.) \stopoldprimitive \startnewprimitive[title={\prm {endlocalcontrol}}] See \prm {beginlocalcontrol}. \stopnewprimitive \startnewprimitive[title={\prm {endmathgroup}}] This primitive is the counterpart of \prm {beginmathgroup}. \stopnewprimitive \startnewprimitive[title={\prm {endsimplegroup}}] This one ends a simple group, see \prm {beginsimplegroup} for an explanation about grouping primitives. \stopnewprimitive \startnewprimitive[title={\prm {enforced}}] The engine can be set up to prevent overloading of primitives and macros defined as \prm {permanent} or \prm {immutable}. However, a macro package might want to get around this in controlled situations, which is why we have a \prm {enforced} prefix. This prefix in interpreted differently in so called \quote {ini} mode when macro definitions can be dumped in the format. Internally they get an \type {always} flag as indicator that in these places an overload is possible. \starttyping \permanent\def\foo{original} \def\oof {\def\foo{fails}} \def\oof{\enforced\def\foo{succeeds}} \stoptyping Of course this only has an effect when overload protection is enabled. \stopnewprimitive \startoldprimitive[title={\prm {eofinput}}] This is a variant on \prm {input} that takes a token list as first argument. That list is expanded when the file ends. It has companion primitives \prm {atendoffile} (single token) and \prm {atendoffiled} (multiple tokens). \stopoldprimitive \startoldprimitive[title={\prm {eqno}}] This primitive stores the (typeset) content (presumably a number) and when the display formula is wrapped that number will end up right of the formula. \stopoldprimitive \startoldprimitive[title={\prm {errhelp}}] This is additional help information to \prm {errmessage} that triggers an error and shows a message. \stopoldprimitive \startoldprimitive[title={\prm {errmessage}}] This primitive expects a token list and shows its expansion on the console and|/|or in the log file, depending on how \TEX\ is configured. After that it will enter the error state and either goes on or waits for input, again depending on how \TEX\ is configured. For the record: we don't use this primitive in \CONTEXT. \stopoldprimitive \startoldprimitive[title={\prm {errorcontextlines}}] This parameter determines the number on lines shown when an error is triggered. \stopoldprimitive \startoldprimitive[title={\prm {errorstopmode}}] This directive stops at every opportunity to interact. In \CONTEXT\ we overload the actions in a callback and quit the run because we can assume that a successful outcome is unlikely. \stopoldprimitive \startoldprimitive[title={\prm {escapechar}}] This internal integer has the code point of the character that get prepended to a control sequence when it is serialized (for instance in tracing or messages). \stopoldprimitive \startnewprimitive[title={\prm {etoks}}] This assigns an expanded token list to a token register: \starttyping \def\temp{less stuff} \etoks\scratchtoks{a bit \temp} \stoptyping The orginal value of the register is lost. \stopnewprimitive \startnewprimitive[title={\prm {etoksapp}}] A variant of \prm {toksapp} is the following: it expands the to be appended content. \starttyping \def\temp{more stuff} \etoksapp\scratchtoks{some \temp} \stoptyping \stopnewprimitive \startnewprimitive[title={\prm {etokspre}}] A variant of \prm {tokspre} is the following: it expands the to be prepended content. \starttyping \def\temp{less stuff} \etokspre\scratchtoks{a bit \temp} \stoptyping \stopnewprimitive \startnewprimitive[title={\prm {eufactor}}] When we introduced the \type {es} (2.5cm) and \type {ts} (2.5mm) units as metric variants of the \type {in} we also added the \type {eu} factor. One \type {eu} equals one tenth of a \type {es} times the \prm {eufactor}. The \type {ts} is a convenient offset in test files, the \type {es} a convenient ones for layouts and image dimensions and the \type {eu} permits definitions that scale nicely without the need for dimensions. They also were a prelude to what later became possible with \prm {associateunit}. \stopnewprimitive \startnewprimitive[title={\prm {everybeforepar}}] This token register is expanded before a paragraph is triggered. The reason for triggering is available in \prm {lastpartrigger}. \stopnewprimitive \startoldprimitive[title={\prm {everycr}}] This token list gets expanded when a row ends in an alignment. Normally it will use \prm {noalign} as wrapper \startbuffer {\everycr{\noalign{H}} \halign{#\cr test\cr test\cr}} {\everycr{\noalign{V}} \hsize 4cm \valign{#\cr test\cr test\cr}} \stopbuffer \typebuffer Watch how the \prm {cr} ending the preamble also get this treatment: \getbuffer \stopoldprimitive \startoldprimitive[title={\prm {everydisplay}}] This token list gets expanded every time we enter display mode. It is a companion of \prm {everymath}. \stopoldprimitive \startoldprimitive[title={\prm {everyeof}}] The content of this token list is injected when a file ends but it can only be used reliably when one is really sure that no other file is loaded in the process. So in the end it is of no real use in a more complex macro package. \stopoldprimitive \startoldprimitive[title={\prm {everyhbox}}] This token list behaves similar to \prm {everyvbox} so look there for an explanation. \stopoldprimitive \startoldprimitive[title={\prm {everyjob}}] This token list register is injected at the start of a job, or more precisely, just before the main control loop starts. \stopoldprimitive \startoldprimitive[title={\prm {everymath}}] Often math needs to be set up independent from the running text and this token list can be used to do that. There is also \prm {everydisplay}. \stopoldprimitive \startnewprimitive[title={\prm {everymathatom}}] When a math atom is seen this tokenlist is expanded before content is processed inside the atom body. \stopnewprimitive \startoldprimitive[title={\prm {everypar}}] When a paragraph starts this tokenlist is expanded before content is processed. \stopoldprimitive \startnewprimitive[title={\prm {everytab}}] This token list gets expanded every time we start a table cell in \prm {halign} or \prm {valign}. \stopnewprimitive \startoldprimitive[title={\prm {everyvbox}}] This token list gets expanded every time we start a vertical box. Like \prm {everyhbox} this is not that useful unless you are certain that there are no nested boxes that don't need this treatment. Of course you can wipe this register in this expansion, like: \starttyping \everyvbox{\kern10pt\everyvbox{}} \stoptyping \stopoldprimitive \startnewprimitive[title={\prm {exceptionpenalty}}] In exceptions we can indicate a penalty by \type {[digit]} in which case a penalty is injected set by this primitive, multiplied by the digit. \stopnewprimitive \startoldprimitive[title={\prm {exhyphenchar}}] The character that is used as pre component of the related discretionary. \stopoldprimitive \startoldprimitive[title={\prm {exhyphenpenalty}}] The penalty injected after \type {-} or \type {\-} unless \prm {hyphenationmode} is set to force the dedisated penalties. \stopoldprimitive \startnewprimitive[title={\prm {expand}}] Beware, this is not a prefix but a directive to ignore the protected characters of the following macro. \startbuffer \protected \def \testa{\the\scratchcounter} \edef\testb{\testa} \edef\testc{\expand\testa} \stopbuffer \typebuffer The meaning of the three macros is: \startlines \getbuffer \tttf \meaningfull\testa \meaningfull\testb \meaningfull\testc \stoplines \stopnewprimitive \startnewprimitive[title={\prm {expandactive}}] This a bit of an outlier and mostly there for completeness. \startbuffer \meaningasis~ \edef\foo{~} \meaningasis\foo \edef\foo{\expandactive~} \meaningasis\foo \stopbuffer \typebuffer There seems to be no difference but the real meaning of the first \type {\foo} is \quote {active character 126} while the second \type {\foo} \quote {protected call ~} is. % \showluatokens\foo \startlines \getbuffer \stoplines Of course the definition of the active tilde is \CONTEXT\ specific and situation dependent. \stopnewprimitive \startoldprimitive[title={\prm {expandafter}}] This original \TEX\ primitive stores the next token, does a one level expansion of what follows it, which actually can be an not expandable token, and reinjects the stored token in the input. Like: \starttyping \expandafter\let\csname my weird macro name\endcsname{m w m n} \stoptyping Without \prm {expandafter} the \prm {csname} primitive would have been let to the left brace (effectively then a begin group). Actually in this particular case the control sequence with the weird name is injected and when it didn't yet exist it will get the meaning \prm {relax} so we sort of have two assignments in a row then. \stopoldprimitive \startnewprimitive[title={\prm {expandafterpars}}] Here is another gobbler: the next token is reinjected after following spaces and par tokens have been read. So: \startbuffer [\expandafterpars 1 2] [\expandafterpars 3 4] [\expandafterpars 5 6] \stopbuffer \typebuffer gives us: \inlinebuffer, because empty lines are like \prm {par} and therefore ignored. \stopnewprimitive \startnewprimitive[title={\prm {expandafterspaces}}] This is a gobbler: the next token is reinjected after following spaces have been read. Here is a simple example: \startbuffer [\expandafterspaces 1 2] [\expandafterspaces 3 4] [\expandafterspaces 5 6] \stopbuffer \typebuffer We get this typeset: \inlinebuffer, because a newline normally is configured to be a space (and leading spaces in a line are normally being ingored anyway). \stopnewprimitive \startnewprimitive[title={\prm {expandcstoken}}] The rationale behind this primitive is that when we \prm {let} a single token like a character it is hard to compare that with something similar, stored in a macro. This primitive pushes back a single token alias created by \prm {let} into the input. \startbuffer \let\tempA + \meaning\tempA \let\tempB X \meaning\tempB \crlf \let\tempC $ \meaning\tempC \par \edef\temp {\tempA} \doifelse{\temp}{+}{Y}{N} \meaning\temp \crlf \edef\temp {\tempB} \doifelse{\temp}{X}{Y}{N} \meaning\temp \crlf \edef\temp {\tempC} \doifelse{\temp}{X}{Y}{N} \meaning\temp \par \edef\temp{\expandcstoken\tempA} \doifelse{\temp}{+}{Y}{N} \meaning\temp \crlf \edef\temp{\expandcstoken\tempB} \doifelse{\temp}{X}{Y}{N} \meaning\temp \crlf \edef\temp{\expandcstoken\tempC} \doifelse{\temp}{$}{Y}{N} \meaning\temp \par \doifelse{\expandcstoken\tempA}{+}{Y}{N} \doifelse{\expandcstoken\tempB}{X}{Y}{N} \doifelse{\expandcstoken\tempC}{$}{Y}{N} \par \stopbuffer \typebuffer The meaning of the \prm {let} macros shows that we have a shortcut to a character with (in this case) catcode letter, other (here \quote {other character} gets abbreviated to \quote {character}), math shift etc. \start \tttf \getbuffer \stop Here we use the \CONTEXT\ macro \type {\doifelse} which can be implemented in different ways, but the only property relevant to the user is that the expanded content of the two arguments is compared. \stopnewprimitive \startnewprimitive[title={\prm {expanded}}] This primitive complements the two expansion related primitives mentioned in the previous two sections. This time the content will be expanded and then pushed back into the input. Protected macros will not be expanded, so you can use this primitive to expand the arguments in a call. In \CONTEXT\ you need to use \type {\normalexpanded} because we already had a macro with that name. We give some examples: \startbuffer \def\A{!} \def\B#1{\string#1} \B{\A} \def\B#1{\string#1} \normalexpanded{\noexpand\B{\A}} \protected\def\B#1{\string#1} \B{\A} \stopbuffer \typebuffer \startlines\getbuffer\stoplines \stopnewprimitive \startnewprimitive[title={\prm {expandedafter}}] The following two lines are equivalent: \startbuffer \def\foo{123} \expandafter[\expandafter[\expandafter\secondofthreearguments\foo]] \expandedafter{[[\secondofthreearguments}\foo]] \stopbuffer \typebuffer In \CONTEXT\ \MKIV\ the number of times that one has multiple \prm {expandafter}s is much larger than in \CONTEXT\ \LMTX\ thanks to some of the new features in \LUAMETATEX, and this primitive is not really used yet in the core code. \startlines\getbuffer\stoplines \stopnewprimitive \startnewprimitive[title={\prm {expandeddetokenize}}] This is a companion to \prm {detokenize} that expands its argument: \startbuffer \def\foo{12#H3} \def\oof{\foo} \detokenize {\foo} \detokenize {\oof} \expandeddetokenize{\foo} \expandeddetokenize{\oof} \edef\ofo{\expandeddetokenize{\foo}} \meaningless\ofo \edef\ofo{\expandeddetokenize{\oof}} \meaningless\ofo \stopbuffer \typebuffer This is a bit more convenient than \starttyping \detokenize \expandafter {\normalexpanded {\foo}} \stoptyping kind of solutions. We get: \startlines \getbuffer \stoplines \stopnewprimitive \startnewprimitive[title={\prm {expandedendless}}] This one loops forever but because the loop counter is not set you need to find a way to quit it. \stopnewprimitive \startnewprimitive[title={\prm {expandedloop}}] This variant of the previously introduced \prm {localcontrolledloop} doesn't enter a local branch but immediately does its work. This means that it can be used inside an expansion context like \prm {edef}. \startbuffer \edef\whatever {\expandedloop 1 10 1 {\scratchcounter=\the\currentloopiterator\relax}} \meaningasis\whatever \stopbuffer \typebuffer \start \veryraggedright \tt\tfx \getbuffer \stop \blank \stopnewprimitive \startnewprimitive[title={\prm {expandedrepeat}}] This one takes one instead of three arguments which is sometimes more convenient. \stopnewprimitive \startnewprimitive[title={\prm {expandparameter}}] This primitive is a predecessor of \prm {parameterdef} so we stick to a simple example. \startbuffer \def\foo#1#2% {\integerdef\MyIndexOne\parameterindex\plusone % 1 \integerdef\MyIndexTwo\parameterindex\plustwo % 2 \oof{P}\oof{Q}\oof{R}\norelax} \def\oof#1% {<1:\expandparameter\MyIndexOne><1:\expandparameter\MyIndexOne>% #1% <2:\expandparameter\MyIndexTwo><2:\expandparameter\MyIndexTwo>} \foo{A}{B} \stopbuffer \typebuffer In principle the whole parameter stack can be accessed but often one never knows if a specific macro is called nested. The original idea behind this primitive was tracing but it can also be used to avoid passing parameters along a chain of calls. \getbuffer \stopnewprimitive \startnewprimitive[title={\prm {expandtoken}}] This primitive creates a token with a specific combination of catcode and character code. Because it assumes some knowledge of \TEX\ we can show it using some \prm {expandafter} magic: \startbuffer \expandafter\let\expandafter\temp\expandtoken 11 `X \meaning\temp \expandafter\let\expandafter\temp\expandtoken 12 `X \meaning\temp \stopbuffer \typebuffer The meanings are: \startlines \tttf \getbuffer \stoplines Using other catcodes is possible but the results of injecting them into the input directly (or here by injecting \type {\temp}) can be unexpected because of what \TEX\ expects. You can get messages you normally won't get, for instance about unexpected alignment interference, which is a side effect of \TEX\ using some catcode|/|character combinations as signals and there is no reason to change those internals. That said: \startbuffer \xdef\tempA{\expandtoken 9 `X} \meaning\tempA \xdef\tempB{\expandtoken 10 `X} \meaning\tempB \xdef\tempC{\expandtoken 11 `X} \meaning\tempC \xdef\tempD{\expandtoken 12 `X} \meaning\tempD \stopbuffer \typebuffer are all valid and from the meaning you cannot really deduce what's in there: \startlines \tttf \getbuffer \stoplines % grouped therefore xdef But you can be assured that: \startbuffer [AB: \ifx\tempA\tempB Y\else N\fi] [AC: \ifx\tempA\tempC Y\else N\fi] [AD: \ifx\tempA\tempD Y\else N\fi] [BC: \ifx\tempB\tempC Y\else N\fi] [BD: \ifx\tempB\tempD Y\else N\fi] [CD: \ifx\tempC\tempD Y\else N\fi] \stopbuffer \typebuffer makes clear that they're different: \inlinebuffer, and in case you wonder, the characters with catcode 10 are spaces, while those with code 9 are ignored. \stopnewprimitive \startnewprimitive[title={\prm {expandtoks}}] This is a more efficient equivalent of \prm {the} applied to a token register, so: \startbuffer \scratchtoks{just some tokens} \edef\TestA{[\the \scratchtoks]} \edef\TestB{[\expandtoks\scratchtoks]} [\the \scratchtoks] [\TestA] \meaning\TestA [\expandtoks\scratchtoks] [\TestB] \meaning\TestB \stopbuffer \typebuffer does the expected: \startlines \getbuffer \stoplines The \prm {expandtoken} primitive avoid a copy into the input when there is no need for it. \stopnewprimitive \startnewprimitive[title={\prm {explicitdiscretionary}}] This is the verbose alias for one of \TEX's single character control sequences: \type {\-}. \stopnewprimitive \startnewprimitive[title={\prm {explicithyphenpenalty}}] The penalty injected after an automatic discretionary \type {\-}, when \prm {hyphenationmode} enables this. \stopnewprimitive \startnewprimitive[title={\prm {explicititaliccorrection}}] This is the verbose alias for one of \TEX's single character control sequences: \type {\/}. Italic correction is a character property specific to \TEX\ and the concept is not present in modern font technologies. There is a callback that hooks into this command so that a macro package can provide its own solution to this (or alternatively it can assign values to the italic correction field. \stopnewprimitive \startnewprimitive[title={\prm {explicitspace}}] This is the verbose alias for one of \TEX's single character control sequences: \type {\ }. A space is inserted with properties according the space related variables. There is look|-|back involved in order to deal with space factors. When \prm {nospaces} is set to~1 no spaces are inserted, when its value is~2 a zero space is inserted. \stopnewprimitive \startoldprimitive[title={\prm {fam}}] In a numeric context it returns the current family number, otherwise it sets the given family. The number of families in a traditional engine is 16, in \LUATEX\ it is 256 and in \LUAMETATEX\ we have at most \cldcontext {tex . magicconstants . max_n_of_math_families} families. A future version can lower that number when we need more classes. \stopoldprimitive \startoldprimitive[title={\prm {fi}}] This traditional primitive is part of the condition testing mechanism and ends a test. So, we have: \starttyping \ifsomething ... \else ... \fi \ifsomething ... \or ... \or ... \else ... \fi \ifsomething ... \orelse \ifsometing ... \else ... \fi \ifsomething ... \or ... \orelse \ifsometing ... \else ... \fi \stoptyping The \prm {orelse} is new in \LUAMETATEX\ and a continuation like we find in other programming languages (see later section). \stopoldprimitive \startoldprimitive[title={\prm {finalhyphendemerits}}] This penalty will be added to the penalty assigned to a breakpoint when that break results in a pre|-|last line ending with a hyphen. \stopoldprimitive \startoldprimitive[title={\prm {firstmark}}][obsolete=yes] This is a reference to the first mark on the (split off) page, it gives back tokens. \stopoldprimitive \startoldprimitive[title={\prm {firstmarks}}] This is a reference to the first mark with the given id (a number) on the (split off) page, it gives back tokens. \stopoldprimitive \startnewprimitive[title={\prm {firstvalidlanguage}}] Language id's start at zero, which makes it the first valid language. You can set this parameter to indicate the first language id that is actually a language. The current value is \the \firstvalidlanguage, so lower values will not trigger hyphenation. \stopnewprimitive \startnewprimitive[title={\prm {float}}] In addition to integers and dimensions, which are fixed 16.16 integer floats we also have \quote {native} floats, based on 32 bit posit unums. \startbuffer \float0 = 123.456 \the\float0 \float2 = 123.456 \the\float0 \advance \float0 by 123.456 \the\float0 \advance \float0 by \float2 \the\float0 \divideby\float0 3 \the\float0 \stopbuffer \typebuffer They come with the same kind of support as the other numeric data types: \startlines \getbuffer \stoplines \startbuffer \dimen00 = 123.456pt \the\dimen0 \dimen02 = 123.456pt \the\dimen0 \advance \dimen0 by 123.456pt \the\dimen0 \advance \dimen0 by \dimen2 \the\dimen0 \divideby\dimen0 3 \the\dimen0 \stopbuffer We leave the subtle differences between floats and dimensions to the user to investigate: \typebuffer The nature of posits is that they are more accurate around zero (or smaller numbers in general). \startlines \getbuffer \stoplines This also works: \startbuffer \float0=123.456e4 \float2=123.456 \multiply\float2 by 10000 \the\float0 \the\float2 \stopbuffer \typebuffer The values are (as expected) the same: \startlines \getbuffer \stoplines \stopnewprimitive \startnewprimitive[title={\prm {floatdef}}] This primitive defines a symbolic (macro) alias to a float register, just like \prm {countdef} and friends do. \stopnewprimitive \startnewprimitive[title={\prm {floatexpr}}] This is the companion of \prm {numexpr}, \prm {dimexpr} etc. \startbuffer \scratchcounter 200 \the \floatexpr 123.456/456.123 \relax \the \floatexpr 1.2*\scratchcounter \relax \the \floatexpr \scratchcounter/3 \relax \number\floatexpr \scratchcounter/3 \relax \stopbuffer \typebuffer Watch the difference between \prm {the} and \prm {number}: \startlines \getbuffer \stoplines \stopnewprimitive \startoldprimitive[title={\prm {floatingpenalty}}] When an insertion is split (across pages) this one is added to to accumulated \prm {insertpenalties}. In \LUAMETATEX\ this penalty can be stored per insertion class. \stopoldprimitive \startnewprimitive[title={\prm {flushmarks}}] This primitive is an addition to the multiple marks mechanism that originates in \ETEX\ and inserts a reset signal for the mark given category that will perform a clear operation (like \prm {clearmarks} which operates immediately). \stopnewprimitive \startoldprimitive[title={\prm {font}}] This primitive is either a symbolic reference to the current font or in the perspective of an assignment is used to trigger a font definitions with a given name (\type {cs}) and specification. In \LUAMETATEX\ the assignment will trigger a callback that then handles the definition; in addition to the filename an optional size specifier is checked (\type {at} or \type {scaled}). In \LUAMETATEX\ {\em all} font loading is delegated to \LUA, and there is no loading code built in the engine. Also, instead of \prm {font} in \CONTEXT\ one uses dedicated and more advanced font definition commands. \stopoldprimitive \startnewprimitive[title={\prm {fontcharba}}] Fetches the bottom anchor of a character in the given font, so: \startbuffer \the\fontcharba\textfont0 "222B \stopbuffer results in: \inlinebuffer. However, this anchor is only available when it is set and it is not part of \OPENTYPE; it is something that \CONTEXT\ provides for math fonts. \stopnewprimitive \startoldprimitive[title={\prm {fontchardp}}] Fetches the depth of a character in the given font, so: \startbuffer \the\fontchardp\font`g \stopbuffer results in: \inlinebuffer. \stopoldprimitive \startoldprimitive[title={\prm {fontcharht}}] Fetches the width of a character in the given font, so: \startbuffer \the\fontcharht\font`g \stopbuffer results in: \inlinebuffer. \stopoldprimitive \startoldprimitive[title={\prm {fontcharic}}] Fetches the italic correction of a character in the given font, but because it is not an \OPENTYPE\ property it is unlikely to return something useful. Although math fonts have such a property in \CONTEXT\ we deal with it differently. \stopoldprimitive \startnewprimitive[title={\prm {fontcharta}}] Fetches the top anchor of a character in the given font, so: \startbuffer \the\fontcharba\textfont0 "222B \stopbuffer results in: \inlinebuffer. This is a specific property of math characters because in text mark anchoring is driven by a feature. \stopnewprimitive \startoldprimitive[title={\prm {fontcharwd}}] Fetches the width of a character in the given font, so: \startbuffer \the\fontcharwd\font`g \stopbuffer results in: \inlinebuffer. \stopoldprimitive \startoldprimitive[title={\prm {fontdimen}}] A traditional \TEX\ font has a couple of font specific dimensions, we only mention the seven that come with text fonts: \startitemize[n,packed] \startitem The slant (slope) is an indication that we have an italic shape. The value divided by 65.536 is a fraction that can be compared with for instance the \type {slanted} operator in \METAPOST. It is used for positioning accents, so actually not limited to oblique fonts (just like italic correction can be a property of any character). It is not relevant in the perspective of \OPENTYPE\ fonts where we have glyph specific top and bottom anchors. \stopitem \startitem Unless is it overloaded by \prm {spaceskip} this determines the space between words (or actually anything separated by a space). \stopitem \startitem This is the stretch component of \prm {fontdimen}~2(space). \startitem This is the shrink component of \prm {fontdimen}~2(space). \stopitem \startitem The so called ex|-|height is normally the height of the \quote {x} and is also accessible as \type {em} unit. \stopitem \startitem The so called em|-|width or in \TEX\ speak quad width is about the with of an \quote {M} but in many fonts just matches the font size. It is also accessible as \type {em} unit. \stopitem \startitem This is a very \TEX\ specific property also known as extra space. It gets {\em added} to the regular space after punctuation when \prm {spacefactor} is 2000 or more. It can be overloaded by \prm {xspaceskip}. \stopitem \stopitemize This primitive expects a a number and a font identifier. Setting a font dimension is a global operation as it directly pushes the value in the font resource. \stopoldprimitive \startnewprimitive[title={\prm {fontid}}] Returns the (internal) number associated with the given font: \startbuffer {\bf \xdef\MyFontA{\the\fontid\font}} {\sl \xdef\MyFontB{\setfontid\the\fontid\font}} \stopbuffer \typebuffer \getbuffer with: \startbuffer test {\setfontid\MyFontA test} test {\MyFontB test} test \stopbuffer \typebuffer gives: \inlinebuffer. \stopnewprimitive % \startnewprimitive[title={\prm {fontmathcontrol}}] % \stopnewprimitive \startoldprimitive[title={\prm {fontname}}] Depending on how the font subsystem is implemented this gives some information about the used font: \startbuffer {\tf \fontname\font} {\bf \fontname\font} {\sl \fontname\font} \stopbuffer \typebuffer \startlines \getbuffer \stoplines \stopoldprimitive \startnewprimitive[title={\prm {fontspecdef}}] This primitive creates a reference to a specification that when triggered will change multiple parameters in one go. \starttyping \fontspecdef\MyFontSpec \fontid\font scale 1200 xscale 1100 yscale 800 weight 200 slant 500 \relax \stoptyping is equivalent to: \starttyping \fontspecdef\MyFontSpec \fontid\font all 1200 1100 800 200 500 \relax \stoptyping while \starttyping \fontspecdef\MyFontSpec \fontid\font all \glyphscale \glyphxscale \glyphyscale \glyphslant \glyphweight \relax \stoptyping is the same as \starttyping \fontspecdef\MyFontSpec \fontid\font \relax \stoptyping The engine adapts itself to these glyph parameters but when you access certain quantities you have to make sure that you use the scaled ones. The same is true at the \LUA\ end. This is somewhat fundamental in the sense that when one uses these sort of dynamic features one also need to keep an eye on code that uses font specific dimensions. \stopnewprimitive \startnewprimitive[title={\prm {fontspecid}}] Internally a font reference is a number and this primitive returns the number of the font bound to the specification. \stopnewprimitive \startnewprimitive[title={\prm {fontspecifiedname}}] Depending on how the font subsystem is implemented this gives some information about the (original) definition of the used font: \startbuffer {\tf \fontspecifiedname\font} {\bf \fontspecifiedname\font} {\sl \fontspecifiedname\font} \stopbuffer \typebuffer \startlines \getbuffer \stoplines \stopnewprimitive \startnewprimitive[title={\prm {fontspecifiedsize}}] Depending on how the font subsystem is implemented this gives some information about the (original) size of the used font: \startbuffer {\tf \the\fontspecifiedsize\font : \the\glyphscale} {\bfa \the\fontspecifiedsize\font : \the\glyphscale} {\slx \the\fontspecifiedsize\font : \the\glyphscale} \stopbuffer \typebuffer Depending on how the font system is setup, this is not the real value that is used in the text because we can use for instance \prm {glyphscale}. So the next lines depend on what font mode this document is typeset. \startlines \getbuffer \stoplines \stopnewprimitive \startnewprimitive[title={\prm {fontspecscale}}] This returns the scale factor of a fontspec where as usual 1000 means scaling by~1. \stopnewprimitive \startnewprimitive[title={\prm {fontspecslant}}] This returns the slant factor of a font specification, usually between zero and 1000 with 1000 being maximum slant. \stopnewprimitive \startnewprimitive[title={\prm {fontspecweight}}] This returns the weight of the font specification. Reasonable values are between zero and 500. \stopnewprimitive \startnewprimitive[title={\prm {fontspecxscale}}] This returns the scale factor of a font specification where as usual 1000 means scaling by~1. \stopnewprimitive \startnewprimitive[title={\prm {fontspecyscale}}] This returns the scale factor of a font specification where as usual 1000 means scaling by~1. \stopnewprimitive \startnewprimitive[title={\prm {fonttextcontrol}}] This returns the text control flags that are set on the given font, here {\tttf 0x\tohexadecimal \fonttextcontrol \font}. Bits that can be set are: \getbuffer[engine:syntax:textcontrolcodes] \stopnewprimitive \startnewprimitive[title={\prm {forcedleftcorrection}}] This is a callback driven left correction signal similar to italic corrections. \stopnewprimitive \startnewprimitive[title={\prm {forcedrightcorrection}}] This is a callback driven right correction signal similar to italic corrections. \stopnewprimitive \startnewprimitive[title={\prm {formatname}}] It is in the name: {\tttf \filenameonly {\formatname}}, but we cheat here by only showing the filename and not the full path, which in a \CONTEXT\ setup can span more than a line in this paragraph. \stopnewprimitive \startnewprimitive[title={\prm {frozen}}] You can define a macro as being frozen: \starttyping \frozen\def\MyMacro{...} \stoptyping When you redefine this macro you get an error: \starttyping ! You can't redefine a frozen macro. \stoptyping This is a prefix like \prm {global} and it can be combined with other prefixes. \footnote {The \prm {outer} and \prm {long} prefixes are no|-|ops in \LUAMETATEX\ and \LUATEX\ can be configured to ignore them.} \stopnewprimitive \startnewprimitive[title={\prm {futurecsname}}] In order to make the repertoire of \type {def}, \type {let} and \type {futurelet} primitives complete we also have: \starttyping \futurecsname MyMacro:1\endcsname\MyAction \stoptyping \stopnewprimitive \startnewprimitive[title={\prm {futuredef}}] We elaborate on the example of using \prm {futurelet} in the previous section. Compare that one with the next: \startbuffer \def\MySpecialToken{[} \def\DoWhatever{\ifx\NextToken\MySpecialToken YES\else NOP\fi : } \futurelet\NextToken\DoWhatever [A]\crlf \futurelet\NextToken\DoWhatever (A)\par \stopbuffer \typebuffer This time we get: {\getbuffer} It is for that reason that we now also have \prm {futuredef}: \startbuffer \def\MySpecialToken{[} \def\DoWhatever{\ifx\NextToken\MySpecialToken YES\else NOP\fi : } \futuredef\NextToken\DoWhatever [A]\crlf \futuredef\NextToken\DoWhatever (A)\par \stopbuffer \typebuffer So we're back to what we want: {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {futureexpand}}] This primitive can be used as an alternative to a \prm {futurelet} approach, which is where the name comes from. \footnote {In the engine primitives that have similar behavior are grouped in commands that are then dealt with together, code wise.} \startbuffer \def\variantone<#1>{(#1)} \def\varianttwo#1{[#1]} \futureexpand<\variantone\varianttwo \futureexpand<\variantone\varianttwo{two} \stopbuffer \typebuffer So, the next token determines which of the two variants is taken: {\getbuffer} Because we look ahead there is some magic involved: spaces are ignored but when we have no match they are pushed back into the input. The next variant demonstrates this: \startbuffer \def\variantone<#1>{(#1)} \def\varianttwo{} \def\temp{\futureexpand<\variantone\varianttwo} [\temp ] [\temp {two}] [\expandafter\temp\space ] [\expandafter\temp\space {two}] \stopbuffer \typebuffer This gives us: {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {futureexpandis}}] We assume that the previous section is read. This variant will not push back spaces, which permits a consistent approach i.e.\ the user can assume that macro always gobbles the spaces. \startbuffer \def\variantone<#1>{(#1)} \def\varianttwo{} \def\temp{\futureexpandis<\variantone\varianttwo} [\temp ] [\temp {two}] [\expandafter\temp\space ] [\expandafter\temp\space {two}] \stopbuffer \typebuffer So, here no spaces are pushed back. This \type {is} in the name of this primitive means \quote {ignore spaces}, but having that added to the name would have made the primitive even more verbose (after all, we also don't have \type {\expandeddef} but \prm {edef} and no \type {\globalexpandeddef} but \prm {xdef}. {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {futureexpandisap}}] This primitive is like the one in the previous section but also ignores par tokens, so \type {isap} means \quote {ignore spaces and paragraphs}. \stopnewprimitive \startoldprimitive[title={\prm {futurelet}}] The original \TEX\ primitive \prm {futurelet} can be used to create an alias to a next token, push it back into the input and then expand a given token. \startbuffer \let\MySpecialTokenL[ \let\MySpecialTokenR] % nicer for checker \def\DoWhatever{\ifx\NextToken\MySpecialTokenL YES\else NOP\fi : } \futurelet\NextToken\DoWhatever [A]\crlf \futurelet\NextToken\DoWhatever (A)\par \stopbuffer \typebuffer This is typically the kind of primitive that most users will never use because it expects a sane follow up handler (here \type {\DoWhatever}) and therefore is related to user interfacing. {\getbuffer} \stopoldprimitive \startoldprimitive[title={\prm {gdef}}] The is the global companion of \prm {def}. \stopoldprimitive \startnewprimitive[title={\prm {gdefcsname}}] As with standard \TEX\ we also define global ones: \starttyping \expandafter\gdef\csname MyMacro:1\endcsname{...} \gdefcsname MyMacro:1\endcsname{...} \stoptyping \stopnewprimitive % \startnewprimitive[title={\prm {givenmathstyle}}] % \stopnewprimitive \startnewprimitive[title={\prm {gleaders}}] Leaders are glue with special property: a box, rule of (in \LUAMETATEX) glyph, like: \startlines x\leaders \glyph `M \hfill x xx\leaders \glyph `M \hfill xx x\cleaders \glyph `M \hfill x xx\cleaders \glyph `M \hfill xx x\xleaders \glyph `M \hfill x xx\xleaders \glyph `M \hfill xx x\gleaders \glyph `M \hfill x xx\gleaders \glyph `M \hfill xx \stoplines Leaders fill the available space. The \prm {leaders} command starts at the left edge and stops when there is no more space. The blobs get centered when we use \prm {cleaders}: excess space is distributed before and after a blob while \prm {xleaders} also puts space between the blobs. When a rule is given the advance (width or height and depth) is ignored, so these are equivalent. \starttyping x\leaders \hrule \hfill x x\leaders \hrule width 1cm \hfill x \stoptyping When a box is used one will normally have some alignment in that box. \starttyping x\leaders \hbox {\hss.\hss} \hfill x x\leaders \hbox {\hss.\hss} \hskip 6cm \relax x \stoptyping The reference point is the left edge of the current (outer) box and the effective glue (when it has stretch or shrink) depends on that box. The \prm {gleaders} variant takes the page as reference. That makes it possible to \quote {align} across boxes. \stopnewprimitive \startnewprimitive[title={\prm {glet}}] This is the global companion of \prm {let}. The fact that it is not an original primitive is probably due to the expectation for it not it not being used (as) often (as in \CONTEXT). \stopnewprimitive \startnewprimitive[title={\prm {gletcsname}}] Naturally \LUAMETATEX\ also provides a global variant: \starttyping \expandafter\global\expandafter\let\csname MyMacro:1\endcsname\relax \expandafter \glet\csname MyMacro:1\endcsname\relax \gletcsname MyMacro:1\endcsname\relax \stoptyping So, here we save even more. \stopnewprimitive \startnewprimitive[title={\prm {glettonothing}}] This is the global companion of \prm {lettonothing}. \stopnewprimitive \startoldprimitive[title={\prm {global}}] This is one of the original prefixes that can be used when we define a macro of change some register. \starttyping \bgroup \def\MyMacroA{a} \global\def\MyMacroB{a} \gdef\MyMacroC{a} \egroup \stoptyping The macro defined in the first line is forgotten when the groups is left. The second and third definition are both global and these definitions are retained. \stopoldprimitive \startoldprimitive[title={\prm {globaldefs}}] When set to a positive value, this internal integer will force all definitions to be global, and in a complex macro package that is not something a user will do unless it is very controlled. \stopoldprimitive \startoldprimitive[title={\prm {glueexpr}}] This is a more extensive variant of \prm {dimexpr} that also handles the optional stretch and shrink components. \stopoldprimitive \startoldprimitive[title={\prm {glueshrink}}] This returns the shrink component of a glue quantity. The result is a dimension so you need to apply \prm {the} when applicable. \stopoldprimitive \startoldprimitive[title={\prm {glueshrinkorder}}] This returns the shrink order of a glue quantity. The result is a integer so you need to apply \prm {the} when applicable. \stopoldprimitive \startnewprimitive[title={\prm {gluespecdef}}] A variant of \prm {integerdef} and \prm {dimensiondef} is: \starttyping \gluespecdef\MyGlue = 3pt plus 2pt minus 1pt \stoptyping The properties are comparable to the ones described in the previous sections. \stopnewprimitive \startoldprimitive[title={\prm {gluestretch}}] This returns the stretch component of a glue quantity. The result is a dimension so you need to apply \prm {the} when applicable. \stopoldprimitive \startoldprimitive[title={\prm {gluestretchorder}}] This returns the stretch order of a glue quantity. The result is a integer so you need to apply \prm {the} when applicable. \stopoldprimitive \startoldprimitive[title={\prm {gluetomu}}] The sequence \typ {\the \gluetomu 20pt plus 10pt minus 5pt} gives \the \gluetomu 20pt plus 10pt minus 5pt. \stopoldprimitive \startnewprimitive[title={\prm {glyph}}] This is a more extensive variant of \prm {char} that permits setting some properties if the injected character node. \startbuffer \ruledhbox{\glyph scale 2000 xscale 9000 yscale 1200 slant 700 weight 200 xoffset 10pt yoffset -5pt left 10pt right 20pt 123} \quad \ruledhbox{\glyph scale 2000 xscale 9000 yscale 1200 slant 700 weight 200 125} \stopbuffer \typebuffer In addition one can specify \type {font} (symbol), \type {id} (valid font id number), an \type {options} (bit set) and \type {raise}. \startlinecorrection \dontleavehmode\getbuffer \stoplinecorrection When no parameters are set, the current ones are used. More details and examples of usage can be found in the \CONTEXT\ distribution. \stopnewprimitive \startnewprimitive[title={\prm {glyphdatafield}}] The value of this parameter is assigned to data field in glyph nodes that get injected. It has no meaning in itself but can be used at the \LUA\ end. \stopnewprimitive \startnewprimitive[title={\prm {glyphoptions}}] The value of this parameter is assigned to the options field in glyph nodes that get injected. \startcolumns \getbuffer[engine:syntax:glyphoptions] \stopcolumns \stopnewprimitive \startnewprimitive[title={\prm {glyphscale}}] An integer parameter defining the current glyph scale, assigned to glyphs (characters) inserted into the current list. \stopnewprimitive \startnewprimitive[title={\prm {glyphscriptfield}}] The value of this parameter is assigned to script field in glyph nodes that get injected. It has no meaning in itself but can be used at the \LUA\ end. \stopnewprimitive \startnewprimitive[title={\prm {glyphscriptscale}}] This multiplier is applied to text font and glyph dimension properties when script style is used. \stopnewprimitive \startnewprimitive[title={\prm {glyphscriptscriptscale}}] This multiplier is applied to text font and glyph dimension properties when script script style is used. \stopnewprimitive \startnewprimitive[title={\prm {glyphslant}}] An integer parameter defining the current glyph slant, assigned to glyphs (characters) inserted into the current list. \stopnewprimitive \startnewprimitive[title={\prm {glyphstatefield}}] The value of this parameter is assigned to script state in glyph nodes that get injected. It has no meaning in itself but can be used at the \LUA\ end. \stopnewprimitive \startnewprimitive[title={\prm {glyphtextscale}}] This multiplier is applied to text font and glyph dimension properties when text style is used. \stopnewprimitive \startnewprimitive[title={\prm {glyphweight}}] An integer parameter defining the current glyph weight, assigned to glyphs (characters) inserted into the current list. \stopnewprimitive \startnewprimitive[title={\prm {glyphxoffset}}] An integer parameter defining the current glyph x offset, assigned to glyphs (characters) inserted into the current list. Normally this will only be set when one explicitly works with glyphs and defines a specific sequence. \stopnewprimitive \startnewprimitive[title={\prm {glyphxscale}}] An integer parameter defining the current glyph x scale, assigned to glyphs (characters) inserted into the current list. \stopnewprimitive \startnewprimitive[title={\prm {glyphxscaled}}] This primitive returns the given dimension scaled by the \prm {glyphscale} and \prm {glyphxscale}. \stopnewprimitive \startnewprimitive[title={\prm {glyphyoffset}}] An integer parameter defining the current glyph x offset, assigned to glyphs (characters) inserted into the current list. Normally this will only be set when one explicitly works with glyphs and defines a specific sequence. \stopnewprimitive \startnewprimitive[title={\prm {glyphyscale}}] An integer parameter defining the current glyph y scale, assigned to glyphs (characters) inserted into the current list. \stopnewprimitive \startnewprimitive[title={\prm {glyphyscaled}}] This primitive returns the given dimension scaled by the \prm {glyphscale} and \prm {glyphyscale}. \stopnewprimitive \startnewprimitive[title={\prm {gtoksapp}}] This is the global variant of \prm {toksapp}. \stopnewprimitive \startnewprimitive[title={\prm {gtokspre}}] This is the global variant of \prm {tokspre}. \stopnewprimitive \startoldprimitive[title={\prm {halign}}] This command starts horizontally aligned material. Macro packages use this command in table mechanisms and math alignments. It starts with a preamble followed by entries (rows and columns). \stopoldprimitive \startoldprimitive[title={\prm {hangafter}}] This parameter tells the par builder when indentation specified with \prm {hangindent} starts. A negative value does the opposite and starts indenting immediately. So, a value of $-2$ will make the first two lines indent. \startoldprimitive[title={\prm {hangindent}}] This parameter relates to \prm {hangafter} and sets the amount of indentation. When larger than zero indentation happens left, otherwise it starts at the right edge. \stopoldprimitive \stopoldprimitive \startoldprimitive[title={\prm {hbadness}}] This sets the threshold for reporting a horizontal badness value, its current value is \the \badness. \stopoldprimitive \startoldprimitive[title={\prm {hbox}}] This constructs a horizontal box. There are a lot of optional parameters so more details can be found in dedicated manuals. When the content is packed a callback can kick in that can be used to apply for instance font features. \stopoldprimitive \startnewprimitive[title={\prm {hccode}}] The \TEX\ engine is good at hyphenating but traditionally that has been limited to hyphens. Some languages however use different characters. You can set up a different \prm {hyphenchar} as well as pre and post characters, but there's also a dedicated code for controlling this. \startbuffer \hccode"2013 "2013 \hsize 50mm test\char"2013test\par \hsize 1mm test\char"2013test\par \hccode"2013 `! \hsize 50mm test\char"2013test\par \hsize 1mm test\char"2013test\par \stopbuffer \typebuffer This example shows that we can mark a character as hyphen|-|like but also can remap it to something else: \startpacked \getbuffer \stoppacked \stopnewprimitive \startoldprimitive[title={\prm {hfil}}] This is a shortcut for \typ {\hskip plus 1 fil} (first order filler). \stopoldprimitive \startoldprimitive[title={\prm {hfill}}] This is a shortcut for \typ {\hskip plus 1 fill} (second order filler). \stopoldprimitive \startoldprimitive[title={\prm {hfilneg}}] This is a shortcut for \typ {\hskip plus - 1 fil} so it can compensate \prm {hfil}. \stopoldprimitive \startoldprimitive[title={\prm {hfuzz}}] This dimension sets the threshold for reporting horizontal boxes that are under- or overfull. The current value is \the \hfuzz. \stopoldprimitive \startnewprimitive[title={\prm {hjcode}}] The so called lowercase code determines if a character is part of a to|-|be|-|hyphenated word. In \LUATEX\ we introduced the \quote {hyphenation justification} code as replacement. When a language is saved and no \prm {hjcode} is set the \prm {lccode} is used instead. This code serves a second purpose. When the assigned value is greater than 0 but less than 32 it indicated the to be used length when checking for left- and righthyphenmin. For instance it make sense to set the code to~2 for characters like Å“. \stopnewprimitive \startoldprimitive[title={\prm {hkern}}] This primitive is like \prm {kern} but will force the engine into horizontal mode if it isn't yet. \stopoldprimitive \startnewprimitive[title={\prm {hmcode}}] The \type {hm} stands for \quote {hyphenation math}. When bit~1 is set the characters will be repeated on the next line after a break. The second bit concerns italic correction but is of little relevance now that we moved to a different model in \CONTEXT. Here are some examples, we also show an example of \prm {mathdiscretionary} because that is what this code triggers: \startbuffer test $ \dorecurse {50} { a \discretionary class 2 {$\darkred +$}{$\darkgreen +$}{$\darkblue +$} } b$ test $ a \mathdiscretionary class 1 {-}{-}{-} b$ \bgroup \hmcode"002B=1 % + \hmcode"002D=1 % - \hmcode"2212=1 % - test $ \dorecurse{50}{a + b - } c$ \egroup \stopbuffer \typebuffer {\setuptolerance[verytolerant,stretch]\getbuffer} \stopnewprimitive \startoldprimitive[title={\prm {holdinginserts}}] When set to a positive value inserts will be kept in the stream and not moved to the insert registers. \stopoldprimitive \startnewprimitive[title={\prm {holdingmigrations}}] When set to a positive value marks (and adjusts) will be kept in the stream and not moved to the outer level or related registers. \stopnewprimitive \startnewprimitive[title={\prm {hpack}}] This primitive is like \prm {hbox} but without the callback overhead. \stopnewprimitive \startnewprimitive[title={\prm {hpenalty}}] This primitive is like \prm {penalty} but will force the engine into horizontal mode if it isn't yet. \stopnewprimitive \startoldprimitive[title={\prm {hrule}}] This creates a horizontal rule. Unless the width is set it will stretch to fix the available width. In addition to the traditional \type {width}, \type {height} and \type {depth} specifiers some more are accepted. These are discussed in other manuals. To give an idea: \startbuffer h\hrule width 10mm height 2mm depth 1mm \relax rule h\hrule width 10mm height 2mm depth 1mm xoffset 30mm yoffset -10mm \relax rule v\vrule width 10mm height 2mm depth 1mm \relax rule v\vrule width 10mm height 2mm depth 1mm xoffset 30mm yoffset 10mm \relax rule \stopbuffer \typebuffer The \prm {relax} stops scanning and because we have more keywords we get a different error report than in traditional \TEX\ when a lookahead confuses the engine. On separate lines we get the following. \startlines \getbuffer \stoplines \stopoldprimitive \startoldprimitive[title={\prm {hsize}}] This sets (or gets) the current horizontal size. \startbuffer \hsize 40pt \setbox0\vbox{x} hsize: \the\wd0 \setbox0\vbox{\hsize 40pt x} hsize: \the\wd0 \stopbuffer \typebuffer In both cases we get the same size reported but the first one will also influence the current paragraph when used ungrouped. \startlines \getbuffer \stoplines \stopoldprimitive \startoldprimitive[title={\prm {hskip}}] The given glue is injected in the horizontal list. If possible horizontal mode is entered. \stopoldprimitive \startoldprimitive[title={\prm {hss}}] \startbuffer x\hbox to 0pt{\hskip 0pt plus 1 fil minus 1 fil\relax test}x x\hbox to 0pt{\hss test}x x\hbox to 0pt{test\hskip 0pt plus 1 fil minus 1 fil\relax}x x\hbox to 0pt{test\hss}x \stopbuffer In traditional \TEX\ glue specifiers are shared. This makes a lot of sense when memory has to be saved. For instance spaces in a paragraph of text are often the same and a glue specification has at least an amount, stretch, shrink, stretch order and shrink order field plus a leader pointer; in \LUAMETATEX\ we have even more fields. In \LUATEX\ these shared (and therefore referenced) glue spec nodes became just copies. \typebuffer The \prm {hss} primitives injects a glue node with one order stretch and one order shrink. In traditional \TEX\ this is a reference to a shared specification, and in \LUATEX\ just a copy of a predefined specifier. The only gain is now in tokens because one could just be explicit or use a glue register with that value because we have plenty glue registers. \startlines \getbuffer \stoplines We could have this: \starttyping \permanent\protected\untraced\def\hss {\hskip0pt plus 1 fil minus 1 fil\relax} \stoptyping or this: \starttyping \gluespecdef\hssglue 0pt plus 1 fil minus 1 fil \permanent\protected\untraced\def\hss {\hskip\hssglue} \stoptyping but we just keep the originals around. \stopoldprimitive \startoldprimitive[title={\prm {ht}}] Returns the height of the given box. \stopoldprimitive \startoldprimitive[title={\prm {hyphenation}}] The list passed to this primitive contains hyphenation exceptions that get bound to the current language. In \LUAMETATEX\ this can be managed at the \LUA\ end. Exceptions are not stored in the format file. \stopoldprimitive \startnewprimitive[title={\prm {hyphenationmin}}] This property (that also gets bond to the current language) sets the minimum length of a word that gets hyphenated. \stopnewprimitive % \startnewprimitive[title={\prm {hyphenationmode}}] % \stopnewprimitive \startoldprimitive[title={\prm {hyphenchar}}] This is one of the font related primitives: it returns the number of the hyphen set in the given font. \stopoldprimitive \startoldprimitive[title={\prm {hyphenpenalty}}] Discretionary nodes have a related default penalty. The \prm {hyphenpenalty} is injected after a regular discretionary, and \prm {exhyphenpenalty} after \type {\-} or \type {-}. The later case is called an automatic discretionary. In \LUAMETATEX\ we have two extra penalties: \prm {explicithyphenpenalty} and \prm {automatichyphenpenalty} and these are used when the related bits are set in \prm {hyphenationmode}. \stopoldprimitive \startoldprimitive[title={\prm {if}}] This traditional \TEX\ conditional checks if two character codes are the same. In order to understand unexpanded results it is good to know that internally \TEX\ groups primitives in a way that serves the implementation. Each primitive has a command code and a character code, but only for real characters the name character code makes sense. This condition only really tests for character codes when we have a character, in all other cases, the result is true. \startbuffer \def\A{A}\def\B{B} \chardef\C=`C \chardef\D=`D \def\AA{AA} [\if AA YES \else NOP \fi] [\if AB YES \else NOP \fi] [\if \A\B YES \else NOP \fi] [\if \A\A YES \else NOP \fi] [\if \C\D YES \else NOP \fi] [\if \C\C YES \else NOP \fi] [\if \count\dimen YES \else NOP \fi] [\if \AA\A YES \else NOP \fi] \stopbuffer \typebuffer The last example demonstrates that the tokens get expanded, which is why we get the extra \type {A}: {\getbuffer} \stopoldprimitive \startnewprimitive[title={\prm {ifabsdim}}] This test will negate negative dimensions before comparison, as in: \startbuffer \def\TestA#1{\ifdim #1<2pt too small\orelse\ifdim #1>4pt too large\else okay\fi} \def\TestB#1{\ifabsdim#1<2pt too small\orelse\ifabsdim#1>4pt too large\else okay\fi} \TestA {1pt}\quad\TestA {3pt}\quad\TestA {5pt}\crlf \TestB {1pt}\quad\TestB {3pt}\quad\TestB {5pt}\crlf \TestB{-1pt}\quad\TestB{-3pt}\quad\TestB{-5pt}\par \stopbuffer \typebuffer So we get this: {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {ifabsfloat}}] This test will negate negative floats before comparison, as in: \startbuffer \def\TestA#1{\iffloat #1<2.46 small\orelse\iffloat #1>4.68 large\else medium\fi} \def\TestB#1{\ifabsfloat#1<2.46 small\orelse\ifabsfloat#1>4.68 large\else medium\fi} \TestA {1.23}\quad\TestA {3.45}\quad\TestA {5.67}\crlf \TestB {1.23}\quad\TestB {3.45}\quad\TestB {5.67}\crlf \TestB{-1.23}\quad\TestB{-3.45}\quad\TestB{-5.67}\par \stopbuffer \typebuffer So we get this: {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {ifabsnum}}] This test will negate negative numbers before comparison, as in: \startbuffer \def\TestA#1{\ifnum #1<100 too small\orelse\ifnum #1>200 too large\else okay\fi} \def\TestB#1{\ifabsnum#1<100 too small\orelse\ifabsnum#1>200 too large\else okay\fi} \TestA {10}\quad\TestA {150}\quad\TestA {210}\crlf \TestB {10}\quad\TestB {150}\quad\TestB {210}\crlf \TestB{-10}\quad\TestB{-150}\quad\TestB{-210}\par \stopbuffer \typebuffer Here we get the same result each time: {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {ifarguments}}] This is a variant of \prm {ifcase} were the selector is the number of arguments picked up. For example: \startbuffer \def\MyMacro#1#2#3{\ifarguments\0\or1\or2\or3\else ?\fi} \MyMacro{A}{B}{C} \def\MyMacro#1#0#3{\ifarguments\0\or1\or2\or3\else ?\fi} \MyMacro{A}{B}{C} \def\MyMacro#1#-#2{\ifarguments\0\or1\or2\or3\else ?\fi} \MyMacro{A}{B}{C}\par \stopbuffer \typebuffer Watch the non counted, ignored, argument in the last case. Normally this test will be used in combination with \prm {ignorearguments}. {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {ifboolean}}] This tests a number (register or equivalent) and any nonzero value represents \type {true}, which is nicer than using an \type {\unless \ifcase}. \stopnewprimitive \startoldprimitive[title={\prm {ifcase}}] This numeric \TEX\ conditional takes a counter (literal, register, shortcut to a character, internal quantity) and goes to the branch that matches. \startbuffer \ifcase 3 zero\or one\or two\or three\or four\else five or more\fi \stopbuffer \typebuffer Indeed: \inlinebuffer\ equals three. In later sections we will see some \LUAMETATEX\ primitives that behave like an \prm {ifcase}. \stopoldprimitive \startoldprimitive[title={\prm {ifcat}}] Another traditional \TEX\ primitive: what happens with what gets read in depends on the catcode of a character, think of characters marked to start math mode, or alphabetic characters (letters) versus other characters (like punctuation). \startbuffer \def\A{A}\def\B{,} \chardef\C=`C \chardef\D=`, \def\AA{AA} [\ifcat $! YES \else NOP \fi] [\ifcat () YES \else NOP \fi] [\ifcat AA YES \else NOP \fi] [\ifcat AB YES \else NOP \fi] [\ifcat \A\B YES \else NOP \fi] [\ifcat \A\A YES \else NOP \fi] [\ifcat \C\D YES \else NOP \fi] [\ifcat \C\C YES \else NOP \fi] [\ifcat \count\dimen YES \else NOP \fi] [\ifcat \AA\A YES \else NOP \fi] \stopbuffer \typebuffer Close reading is needed here: {\getbuffer} This traditional \TEX\ condition as a well as the one in the previous section are hardly used in \CONTEXT, if only because they expand what follows and we seldom need to compare characters. \stopoldprimitive \startnewprimitive[title={\prm {ifchkdim}}] A variant on the checker in the previous section is a dimension checker: \startbuffer \ifchkdim oeps \or okay\else error\fi\quad \ifchkdim 12 \or okay\else error\fi\quad \ifchkdim 12pt \or okay\else error\fi\quad \ifchkdim 12pt or more\or okay\else error\fi \stopbuffer \typebuffer We get: {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {ifchkdimension}}] COntrary to \prm {ifchkdim} this test doesn't accept trailing crap: \startbuffer \ifchkdimension oeps \or okay\else error\fi\quad \ifchkdimension 12 \or okay\else error\fi\quad \ifchkdimension 12pt \or okay\else error\fi\quad \ifchkdimension 12pt or more\or okay\else error\fi \stopbuffer \typebuffer reports: {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {ifchknum}}] In \CONTEXT\ there are quite some cases where a variable can have a number or a keyword indicating a symbolic name of a number or maybe even some special treatment. Checking if a valid number is given is possible to some extend, but a native checker makes much sense too. So here is one: \startbuffer \ifchknum oeps \or okay\else error\fi\quad \ifchknum 12 \or okay\else error\fi\quad \ifchknum 12pt \or okay\else error\fi\quad \ifchknum 12pt or more\or okay\else error\fi \stopbuffer \typebuffer The result is as expected: {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {ifchknumber}}] This check is more restrictive than \prm {ifchknum} discussed in the previous section: \startbuffer \ifchknumber oeps \or okay\else error\fi\quad \ifchknumber 12 \or okay\else error\fi\quad \ifchknumber 12pt \or okay\else error\fi\quad \ifchknumber 12pt or more\or okay\else error\fi \stopbuffer \typebuffer Here we get: {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {ifcmpdim}}] This conditional compares two dimensions and the resulting \prm {ifcase} reflects their relation: \startbuffer [1pt 2pt : \ifcmpdim 1pt 2pt less\or equal\or more\fi]\quad [1pt 1pt : \ifcmpdim 1pt 1pt less\or equal\or more\fi]\quad [2pt 1pt : \ifcmpdim 2pt 1pt less\or equal\or more\fi] \stopbuffer \typebuffer This gives: {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {ifcmpnum}}] This conditional compares two numbers and the resulting \prm {ifcase} reflects their relation: \startbuffer [1 2 : \ifcmpnum 1 2 less\or equal\or more\fi]\quad [1 1 : \ifcmpnum 1 1 less\or equal\or more\fi]\quad [2 1 : \ifcmpnum 2 1 less\or equal\or more\fi] \stopbuffer \typebuffer This gives: {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {ifcondition}}] The conditionals in \TEX\ are hard coded as primitives and although it might look like \type {\newif} creates one, it actually just defined three macros. \startbuffer \newif\ifMyTest \meaning\MyTesttrue \crlf \meaning\MyTestfalse \crlf \meaning\ifMyTest \crlf \MyTesttrue \meaning\ifMyTest \par \stopbuffer \typebuffer {\tttf \getbuffer} This means that when you say: \starttyping \ifMytest ... \else ... \fi \stoptyping You actually have one of: \starttyping \iftrue ... \else ... \fi \iffalse ... \else ... \fi \stoptyping and because these are proper conditions nesting them like: \starttyping \ifnum\scratchcounter > 0 \ifMyTest A\else B\fi \fi \stoptyping will work out well too. This is not true for macros, so for instance: \starttyping \scratchcounter = 1 \unexpanded\def\ifMyTest{\iftrue} \ifnum\scratchcounter > 0 \ifMyTest A\else B\fi \fi \stoptyping will make a run fail with an error (or simply loop forever, depending on your code). This is where \prm {ifcondition} enters the picture: \starttyping \def\MyTest{\iftrue} \scratchcounter0 \ifnum\scratchcounter > 0 \ifcondition\MyTest A\else B\fi \else x \fi \stoptyping This primitive is seen as a proper condition when \TEX\ is in \quotation {fast skipping unused branches} mode but when it is expanding a branch, it checks if the next expanded token is a proper tests and if so, it deals with that test, otherwise it fails. The main condition here is that the \type {\MyTest} macro expands to a proper true or false test, so, a definition like: \starttyping \def\MyTest{\ifnum\scratchcounter<10 } \stoptyping is also okay. Now, is that neat or not? \stopnewprimitive \startoldprimitive[title={\prm {ifcsname}}] This is an \ETEX\ conditional that complements the one on the previous section: \starttyping \expandafter\ifx\csname MyMacro\endcsname\relax ... \else ... \fi \ifcsname MyMacro\endcsname ... \else ... \fi \stoptyping Here the first one has the side effect of defining the macro and defaulting it to \prm {relax}, while the second one doesn't do that. Juts think of checking a few million different names: the first one will deplete the hash table and probably string space too. In \LUAMETATEX\ the construction stops when there is no letter or other character seen (\TEX\ expands on the go so expandable macros are dealt with). Instead of an error message, the match is simply false and all tokens till the \prm {endcsname} are gobbled. \stopoldprimitive \startnewprimitive[title={\prm {ifcstok}}] A variant on the primitive mentioned in the previous section is one that operates on lists and macros: \startbuffer[a] \def\a{a} \def\b{b} \def\c{a} \stopbuffer \typebuffer[a] \startbuffer[b] \ifcstok\a\b Y\else N\fi\space \ifcstok\a\c Y\else N\fi\space \ifcstok{\a}\c Y\else N\fi\space \ifcstok{a}\c Y\else N\fi \stopbuffer This: \typebuffer[b] {\getbuffer[a]will give us: \inlinebuffer[b].} \stopnewprimitive \startoldprimitive[title={\prm {ifdefined}}] In traditional \TEX\ checking for a macro to exist was a bit tricky and therefore \ETEX\ introduced a convenient conditional. We can do this: \starttyping \ifx\MyMacro\undefined ... \else ... \fi \stoptyping but that assumes that \type {\undefined} is indeed undefined. Another test often seen was this: \starttyping \expandafter\ifx\csname MyMacro\endcsname\relax ... \else ... \fi \stoptyping Instead of comparing with \type {\undefined} we need to check with \prm {relax} because the control sequence is defined when not yet present and defaults to \prm {relax}. This is not pretty. \stopoldprimitive \startoldprimitive[title={\prm {ifdim}}] Dimensions can be compared with this traditional \TEX\ primitive. \startbuffer \scratchdimen=1pt \scratchcounter=65536 \ifdim\scratchdimen=\scratchcounter sp YES \else NOP\fi \ifdim\scratchdimen=1 pt YES \else NOP\fi \stopbuffer \typebuffer The units are mandate: {\getbuffer} \stopoldprimitive \startnewprimitive[title={\prm {ifdimexpression}}] The companion of the previous primitive is: \startbuffer \ifdimexpression 10pt > 10bp \relax do-something \fi \stopbuffer This matches when the result is non zero, and you can mix calculations and tests as with normal expressions. Contrary to the number variant units can be used and precision kicks in. \stopnewprimitive \startnewprimitive[title={\prm {ifdimval}}] This conditional is a variant on \prm {ifchkdim} and provides some more detailed information about the value: \startbuffer [-12pt : \ifdimval-12pt\or negative\or zero\or positive\else error\fi]\quad [0pt : \ifdimval 0pt\or negative\or zero\or positive\else error\fi]\quad [12pt : \ifdimval 12pt\or negative\or zero\or positive\else error\fi]\quad [oeps : \ifdimval oeps\or negative\or zero\or positive\else error\fi] \stopbuffer \typebuffer This gives: {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {ifempty}}] This conditional checks if a control sequence is empty: \starttyping is \ifempty\MyMacro \else not \fi empty \stoptyping It is basically a shortcut of: \starttyping is \ifx\MyMacro\empty \else not \fi empty \stoptyping with: \starttyping \def\empty{} \stoptyping Of course this is not empty at all: \starttyping \def\notempty#1{} \stoptyping \stopnewprimitive \startoldprimitive[title={\prm {iffalse}}] Here we have a traditional \TEX\ conditional that is always false (therefore the same is true for any macro that is \prm {let} to this primitive). \stopoldprimitive \startnewprimitive[title={\prm {ifflags}}] This test primitive relates to the various flags that one can set on a control sequence in the perspective of overload protection and classification. \startbuffer \protected\untraced\tolerant\def\foo[#1]{...#1...} \permanent\constant \def\oof{okay} \stopbuffer \typebuffer \start \getbuffer \starttabulate[|l|c|c|l|c|c|] \FL \NC flag \NC \type {\foo} \NC \type {\oof} \NC flag \NC \type {\foo} \NC \type {\oof} \NC \NR \ML \NC frozen \NC \ifflags\foo\frozen Y\else N\fi \NC \ifflags\oof\frozen Y\else N\fi \NC permanent \NC \ifflags\foo\permanent Y\else N\fi \NC \ifflags\oof\permanent Y\else N\fi \NC \NR \NC immutable \NC \ifflags\foo\immutable Y\else N\fi \NC \ifflags\oof\immutable Y\else N\fi \NC mutable \NC \ifflags\foo\mutable Y\else N\fi \NC \ifflags\oof\mutable Y\else N\fi \NC \NR \NC noaligned \NC \ifflags\foo\noaligned Y\else N\fi \NC \ifflags\oof\noaligned Y\else N\fi \NC instance \NC \ifflags\foo\instance Y\else N\fi \NC \ifflags\oof\instance Y\else N\fi \NC \NR \NC untraced \NC \ifflags\foo\untraced Y\else N\fi \NC \ifflags\oof\untraced Y\else N\fi \NC global \NC \ifflags\foo\global Y\else N\fi \NC \ifflags\oof\global Y\else N\fi \NC \NR \NC tolerant \NC \ifflags\foo\tolerant Y\else N\fi \NC \ifflags\oof\tolerant Y\else N\fi \NC constant \NC \ifflags\foo\constant Y\else N\fi \NC \ifflags\oof\constant Y\else N\fi \NC \NR \NC protected \NC \ifflags\foo\protected Y\else N\fi \NC \ifflags\oof\protected Y\else N\fi \NC semiprotected \NC \ifflags\foo\semiprotected Y\else N\fi \NC \ifflags\oof\semiprotected Y\else N\fi \NC \NR \LL \stoptabulate \stop Instead of checking against a prefix you can test against a bitset made from: \startluacode context.starttabulate { "|r|l|r|l|r|l|r|l|" } local n = 4 for k, v in table.sortedhash(tex.flagcodes) do if tonumber(k) then n = n - 1 context.NC() context("0x%X",k) context.NC() context(v) if n == 0 then context.NC() context.NR() n = 4 end end end context.stoptabulate() \stopluacode \stopnewprimitive \startnewprimitive[title={\prm {iffloat}}] This test does for floats what \prm {ifnum}, \prm {ifdim} do for numbers and dimensions: comparing two of them. \stopnewprimitive \startoldprimitive[title={\prm {iffontchar}}] This is an \ETEX\ conditional. It takes a font identifier and a character number. In modern fonts simply checking could not be enough because complex font features can swap in other ones and their index can be anything. Also, a font mechanism can provide fallback fonts and characters, so don't rely on this one too much. It just reports true when the font passed to the frontend has a slot filled. \stopoldprimitive \startnewprimitive[title={\prm {ifhaschar}}] This one is a simplified variant of the above: \startbuffer \ifhaschar !{this ! works} yes \else no \fi \stopbuffer \typebuffer and indeed we get: \inlinebuffer ! Of course the spaces in this this example code are normally not present in such a test. \stopnewprimitive \startnewprimitive[title={\prm {ifhastok}}] This conditional looks for occurrences in token lists where each argument has to be a proper list. \startbuffer \def\scratchtoks{x} \ifhastoks{yz} {xyz} Y\else N\fi\quad \ifhastoks\scratchtoks {xyz} Y\else N\fi \stopbuffer \typebuffer We get: {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {ifhastoks}}] This test compares two token lists. When a macro is passed it's meaning gets used. \startbuffer \def\x {x} \def\xyz{xyz} (\ifhastoks {x} {xyz}Y\else N\fi)\quad (\ifhastoks {\x} {xyz}Y\else N\fi)\quad (\ifhastoks \x {xyz}Y\else N\fi)\quad (\ifhastoks {y} {xyz}Y\else N\fi)\quad (\ifhastoks {yz} {xyz}Y\else N\fi)\quad (\ifhastoks {yz} {\xyz}Y\else N\fi) \stopbuffer \typebuffer {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {ifhasxtoks}}] This primitive is like the one in the previous section but this time the given lists are expanded. \startbuffer \def\x {x} \def\xyz{\x yz} (\ifhasxtoks {x} {xyz}Y\else N\fi)\quad (\ifhasxtoks {\x} {xyz}Y\else N\fi)\quad (\ifhastoks \x {xyz}Y\else N\fi)\quad (\ifhasxtoks {y} {xyz}Y\else N\fi)\quad (\ifhasxtoks {yz} {xyz}Y\else N\fi)\quad (\ifhasxtoks {yz} {\xyz}Y\else N\fi) \stopbuffer \typebuffer {\getbuffer} This primitive has some special properties. \startbuffer \edef\+{\expandtoken 9 `+} \ifhasxtoks {xy} {xyz}Y\else N\fi\quad \ifhasxtoks {x\+y} {xyz}Y\else N\fi \stopbuffer \typebuffer Here the first argument has a token that has category code \quote {ignore} which means that such a character will be skipped when seen. So the result is: {\getbuffer} This permits checks like these: \startbuffer \edef\,{\expandtoken 9 `,} \ifhasxtoks{\,x\,} {,x,y,z,}Y\else N\fi\quad \ifhasxtoks{\,y\,} {,x,y,z,}Y\else N\fi\quad \ifhasxtoks{\,z\,} {,x,y,z,}Y\else N\fi\quad \ifhasxtoks{\,x\,} {,xy,z,}Y\else N\fi \stopbuffer \typebuffer I admit that it needs a bit of a twisted mind to come up with this, but it works ok: {\getbuffer} \stopnewprimitive \startoldprimitive[title={\prm {ifhbox}}] This traditional conditional checks if a given box register or internal box variable represents a horizontal box, \stopoldprimitive \startoldprimitive[title={\prm {ifhmode}}] This traditional conditional checks we are in (restricted) horizontal mode. \stopoldprimitive \startnewprimitive[title={\prm {ifinalignment}}] As the name indicates, this primitive tests for being in an alignment. Roughly spoken, the engine is either in a state of align, handling text or dealing with math. \stopnewprimitive \startnewprimitive[title={\prm {ifincsname}}] This conditional is sort of obsolete and can be used to check if we're inside a \prm {csname} or \prm {ifcsname} construction. It's not used in \CONTEXT. \stopnewprimitive \startoldprimitive[title={\prm {ifinner}}] This traditional one can be confusing. It is true when we are in restricted horizontal mode (a box), internal vertical mode (a box), or inline math mode. \startbuffer test \ifhmode \ifinner INNER\fi HMODE\fi\crlf \hbox{test \ifhmode \ifinner INNER \fi HMODE\fi} \par \ifvmode \ifinner INNER\fi VMODE \fi\crlf \vbox{\ifvmode \ifinner INNER \fi VMODE\fi} \crlf \vbox{\ifinner INNER \ifvmode VMODE \fi \fi} \par \stopbuffer \typebuffer Watch the last line: because we typeset \type {INNER} we enter horizontal mode: {\getbuffer} \stopoldprimitive \startnewprimitive[title={\prm {ifinsert}}] This is the equivalent of \prm {ifvoid} for a given insert class. \stopnewprimitive \startnewprimitive[title={\prm {ifintervaldim}}] This conditional is true when the intervals around the values of two dimensions overlap. The first dimension determines the interval. \startbuffer [\ifintervaldim1pt 20pt 21pt \else no \fi overlap] [\ifintervaldim1pt 18pt 20pt \else no \fi overlap] \stopbuffer \typebuffer So here: \inlinebuffer \stopnewprimitive \startnewprimitive[title={\prm {ifintervalfloat}}] This one does with floats what we described under \prm {ifintervaldim}. \stopnewprimitive \startnewprimitive[title={\prm {ifintervalnum}}] This one does with integers what we described under \prm {ifintervaldim}. \stopnewprimitive \startnewprimitive[title={\prm {iflastnamedcs}}] When a \prm {csname} is constructed and succeeds the last one is remembered and can be accessed with \prm {lastnamedcs}. It can however be an undefined one. That state can be checked with this primitive. Of course it also works with the \prm {ifcsname} and \prm {begincsname} variants. \stopnewprimitive \startnewprimitive[title={\prm {ifmathparameter}}] This is an \prm {ifcase} where the value depends on if the given math parameter is zero, (\type {0}), set (\type {1}), or unset (\type {2}). \starttyping \ifmathparameter\Umathpunctclosespacing\displaystyle zero \or nonzero \or unset \fi \stoptyping \stopnewprimitive \startnewprimitive[title={\prm {ifmathstyle}}] This is a variant of \prm {ifcase} were the number is one of the seven possible styles: display, text, cramped text, script, cramped script, script script, cramped script script. \starttyping \ifmathstyle display \or text \or cramped text \else normally smaller than text \fi \stoptyping \stopnewprimitive \startoldprimitive[title={\prm {ifmmode}}] This traditional conditional checks we are in (inline or display) math mode mode. \stopoldprimitive \startoldprimitive[title={\prm {ifnum}}] This is a frequently used conditional: it compares two numbers where a number is anything that can be seen as such. \startbuffer \scratchcounter=65 \chardef\A=65 \ifnum65=`A YES \else NOP\fi \ifnum\scratchcounter=65 YES \else NOP\fi \ifnum\scratchcounter=\A YES \else NOP\fi \stopbuffer \typebuffer Unless a number is an unexpandable token it ends with a space or \prm {relax}, so when you end up in the true branch, you'd better check if \TEX\ could determine where the number ends. {\getbuffer} % When comparing integers, definitions (for instance characters) that can be seen % as such, or any converter that produces a number (like the \type {`} or \prm % {number} the usual \type {=}, \type {<} or \type {>} can be used. However, in % \LUAMETATEX\ you can negate such a comparison by \type {!}: \type {!=}, \type % {!<} or \type {!>}. Successive \type {!} toggle the negation state. On top of these \ASCII\ combinations, the engine also accepts some \UNICODE\ characters. This brings the full repertoire to: \starttabulate[|l|cT|cT|l|] \FL \BC character \BC \BC \BC operation \NC \NR \ML \NC \type {0x003C} \NC $\Uchar"003C$ \NC \NC less \NC \NR \NC \type {0x003D} \NC $\Uchar"003D$ \NC \NC equal \NC \NR \NC \type {0x003E} \NC $\Uchar"003E$ \NC \NC more \NC \NR \NC \type {0x2208} \NC $\Uchar"2208$ \NC \NC element of \NC \NR \NC \type {0x2209} \NC $\Uchar"2209$ \NC \NC not element of \NC \NR \NC \type {0x2260} \NC $\Uchar"2260$ \NC != \NC not equal \NC \NR \NC \type {0x2264} \NC $\Uchar"2264$ \NC !> \NC less equal \NC \NR \NC \type {0x2265} \NC $\Uchar"2265$ \NC !< \NC greater equal \NC \NR \NC \type {0x2270} \NC $\Uchar"2270$ \NC \NC not less equal \NC \NR \NC \type {0x2271} \NC $\Uchar"2271$ \NC \NC not greater equal \NC \NR \LL \stoptabulate This also applied to \prm {ifdim} although in the case of element we discard the fractional part (read: divide the numeric representation by 65536). \stopoldprimitive \startnewprimitive[title={\prm {ifnumexpression}}] Here is an example of a conditional using expressions: \startbuffer \ifnumexpression (\scratchcounterone > 5) and (\scratchcountertwo > 5) \relax do-something \fi \stopbuffer This matches when the result is non zero, and you can mix calculations and tests as with normal expressions. \stopnewprimitive \startnewprimitive[title={\prm {ifnumval}}] This conditional is a variant on \prm {ifchknum}. This time we get some more detail about the value: \startbuffer [-12 : \ifnumval -12\or negative\or zero\or positive\else error\fi]\quad [0 : \ifnumval 0\or negative\or zero\or positive\else error\fi]\quad [12 : \ifnumval 12\or negative\or zero\or positive\else error\fi]\quad [oeps : \ifnumval oeps\or negative\or zero\or positive\else error\fi] \stopbuffer \typebuffer This gives: {\getbuffer} \stopnewprimitive \startoldprimitive[title={\prm {ifodd}}] One reason for this condition to be around is that in a double sided layout we need test for being on an odd or even page. It scans for a number the same was as other primitives, \startbuffer \ifodd65 YES \else NO\fi & \ifodd`B YES \else NO\fi . \stopbuffer \typebuffer So: {\inlinebuffer} \stopoldprimitive \startnewprimitive[title={\prm {ifparameter}}] In a macro body \type {#1} is a reference to a parameter. You can check if one is set using a dedicated parameter condition: \startbuffer \tolerant\def\foo[#1]#*[#2]% {\ifparameter#1\or one\else no one\fi\enspace \ifparameter#2\or two\else no two\fi\emspace} \foo \foo[1] \foo[1][2] \stopbuffer \typebuffer We get: \getbuffer \stopnewprimitive \startnewprimitive[title={\prm {ifparameters}}] This is equivalent to an \prm {ifcase} with as value the number of parameters passed to the current macro. \stopnewprimitive \startnewprimitive[title={\prm {ifrelax}}] This is a convenient shortcut for \typ {\ifx\relax} and the motivation for adding this one is (as with some others) to get less tracing. \stopnewprimitive \startnewprimitive[title={\prm {iftok}}] When you want to compare two arguments, the usual way to do this is the following: \starttyping \edef\tempA{#1} \edef\tempb{#2} \ifx\tempA\tempB the same \else different \fi \stoptyping This works quite well but the fact that we need to define two macros can be considered a bit of a nuisance. It also makes macros that use this method to be not so called \quote {fully expandable}. The next one avoids both issues: \starttyping \iftok{#1}{#2} the same \else different \fi \stoptyping Instead of direct list you can also pass registers, so given: \startbuffer[a] \scratchtoks{a}% \toks0{a}% \stopbuffer \typebuffer[a] This: \startbuffer[b] \iftok 0 \scratchtoks Y\else N\fi\space \iftok{a}\scratchtoks Y\else N\fi\space \iftok\scratchtoks\scratchtoks Y\else N\fi \stopbuffer \typebuffer[b] {\getbuffer[a]gives: \inlinebuffer[b].} \stopnewprimitive \startoldprimitive[title={\prm {iftrue}}] Here we have a traditional \TEX\ conditional that is always true (therefore the same is true for any macro that is \prm {let} to this primitive). \stopoldprimitive \startoldprimitive[title={\prm {ifvbox}}] This traditional conditional checks if a given box register or internal box variable represents a vertical box, \stopoldprimitive \startoldprimitive[title={\prm {ifvmode}}] This traditional conditional checks we are in (internal) vertical mode. \stopoldprimitive \startoldprimitive[title={\prm {ifvoid}}] This traditional conditional checks if a given box register or internal box variable has any content. \stopoldprimitive \startoldprimitive[title={\prm {ifx}}] We use this traditional \TEX\ conditional a lot in \CONTEXT. Contrary to \prm {if} the two tokens that are compared are not expanded. This makes it possible to compare the meaning of two macros. Depending on the need, these macros can have their content expanded or not. A different number of parameters results in false. Control sequences are identical when they have the same command code and character code. Because a \prm {let} macro is just a reference, both let macros are the same and equal to \prm {relax}: \starttyping \let\one\relax \let\two\relax \stoptyping The same is true for other definitions that result in the same (primitive) or meaning encoded in the character field (think of \prm {chardef}s and so). \stopoldprimitive \startnewprimitive[title={\prm {ifzerodim}}] This tests for a dimen (dimension) being zero so we have: \starttyping \ifdim=0pt \ifzerodim \ifcase \stoptyping \stopnewprimitive \startnewprimitive[title={\prm {ifzerofloat}}] As the name indicated, this tests for a zero float value. \startbuffer [\scratchfloat\zerofloat \ifzerofloat\scratchfloat \else not \fi zero] [\scratchfloat\plusone \ifzerofloat\scratchfloat \else not \fi zero] [\scratchfloat 0.01 \ifzerofloat\scratchfloat \else not \fi zero] [\scratchfloat 0.0e0 \ifzerofloat\scratchfloat \else not \fi zero] [\scratchfloat \zeropoint\ifzerofloat\scratchfloat \else not \fi zero] \stopbuffer \typebuffer So: \inlinebuffer \stopnewprimitive \startnewprimitive[title={\prm {ifzeronum}}] This tests for a number (integer) being zero so we have these variants now: \starttyping \ifnum=0 \ifzeronum \ifcase \stoptyping \stopnewprimitive \startnewprimitive[title={\prm {ignorearguments}}] This primitive will quit argument scanning and start expansion of the body of a macro. The number of grabbed arguments can be tested as follows: \startbuffer \def\MyMacro[#1][#2][#3]% {\ifarguments zero\or one\or two\or three \else hm\fi} \MyMacro \ignorearguments \quad \MyMacro [1]\ignorearguments \quad \MyMacro [1][2]\ignorearguments \quad \MyMacro [1][2][3]\ignorearguments \par \stopbuffer \typebuffer {\getbuffer} {\em Todo: explain optional delimiters.} \stopnewprimitive \startnewprimitive[title={\prm {ignoredepthcriterion}}] When setting the \prm {prevdepth} (either by \TEX\ or by the current user) of the current vertical list the value 1000pt is a signal for special treatment of the skip between \quote {lines}. There is an article on that in the distribution. It also demonstrates that \prm {ignoredepthcriterion} can be used to change this special signal, just in case it is needed. \stopnewprimitive \startnewprimitive[title={\prm {ignorenestedupto}}] This primitive gobbles following tokens and can deal with nested \quote {environments}, for example: \startbuffer \def\startfoo{\ignorenestedupto\startfoo\stopfoo} (before \startfoo test \startfoo test \stopfoo {test \startfoo test \stopfoo} \stopfoo after) \stopbuffer \typebuffer delivers: \getbuffer \stopnewprimitive \startnewprimitive[title={\prm {ignorepars}}] This is a variant of \prm {ignorespaces}: following spaces {\em and} \type {\par} equivalent tokens are ignored, so for instance: \startbuffer one + \ignorepars two = \ignorepars \par three \stopbuffer \typebuffer renders as: \inlinebuffer. Traditionally \TEX\ has been sensitive to \prm {par} tokens in some of its building blocks. This has to do with the fact that it could indicate a runaway argument which in the times of slower machines and terminals was best to catch early. In \LUAMETATEX\ we no longer have long macros and the mechanisms that are sensitive can be told to accept \prm {par} tokens (and \CONTEXT\ set them such that this is the case). \stopnewprimitive \startnewprimitive[title={\prm {ignorerest}}] An example shows what this primitive does: \startbuffer \tolerant\def\foo[#1]#*[#2]% {1234 \ifparameter#1\or\else \expandafter\ignorerest \fi /#1/ \ifparameter#2\or\else \expandafter\ignorerest \fi /#2/ } \foo test \foo[456] test \foo[456][789] test \stopbuffer \typebuffer As this likely makes most sense in conditionals you need to make sure the current state is properly finished. Because \prm {expandafter} bumps the input state, here we actually quit two levels; this is because so called \quote {backed up text} is intercepted by this primitive. \getbuffer \stopnewprimitive \startoldprimitive[title={\prm {ignorespaces}}] This traditional \TEX\ primitive signals the scanner to ignore the following spaces, if any. We mention it because we show a companion in the next section. \stopoldprimitive \startnewprimitive[title={\prm {ignoreupto}}] This ignores everything upto the given token, so \startbuffer \ignoreupto \foo not this but\foo only this \stopbuffer \typebuffer will give: \inlinebuffer . \stopnewprimitive \startoldprimitive[title={\prm {immediate}}] This one has no effect unless you intercept it at the \LUA\ end and act upon it. In original \TEX\ immediate is used in combination with read from and write to file operations. So, this is an old primitive with a new meaning. \stopoldprimitive \startnewprimitive[title={\prm {immutable}}] This prefix flags what follows as being frozen and is usually applied to for instance \prm {integerdef}'d control sequences. In that respect is is like \prm {permanent} but it makes it possible to distinguish quantities from macros. \stopnewprimitive \startoldprimitive[title={\prm {indent}}] In engines other than \LUAMETATEX\ a paragraph starts with an indentation box. The width of that (empty) box is determined by \prm {parindent}. In \LUAMETATEX\ we can use a dedicated indentation skip instead (as part of paragraph normalization). An indentation can be zero'd with \prm {undent}. \stopoldprimitive \startnewprimitive[title={\prm {indexofcharacter}}] This primitive is more versatile variant of the backward quote operator, so instead of: \starttyping \number`| \number`~ \number`\a \number`\q \stoptyping you can say: \starttyping \the\indexofcharacter | \the\indexofcharacter ~ \the\indexofcharacter \a \the\indexofcharacter \q \stoptyping In both cases active characters and unknown single character control sequences are valid. In addition this also works: \starttyping \chardef \foo 128 \mathchardef\oof 130 \the\indexofcharacter \foo \the\indexofcharacter \oof \stoptyping An important difference is that \prm {indexofcharacter} returns an integer and not a serialized number. A negative value indicates no valid character. \stopnewprimitive \startnewprimitive[title={\prm {indexofregister}}] You can use this instead of \prm {number} for determining the index of a register but it also returns a number when a register value is seen. The result is an integer, not a serialized number. \stopnewprimitive \startnewprimitive[title={\prm {inherited}}] When this prefix is used in a definition using \prm {let} the target will inherit all the properties of the source. \stopnewprimitive \startnewprimitive[title={\prm {initcatcodetable}}] This initializes the catcode table with the given index. \stopnewprimitive \startnewprimitive[title={\prm {initialpageskip}}] When a page starts the value of this register are used to initialize \prm {pagetotal}, \prm {pagestretch} and \prm {pageshrink}. This make nicer code than using a \prm {topskip} with weird values. \stopnewprimitive \startnewprimitive[title={\prm {initialtopskip}}] When set this one will be used instead of \prm {topskip}. The rationale is that the \prm {topskip} is often also used for side effects and compensation. \stopnewprimitive \startoldprimitive[title={\prm {input}}] There are several ways to use this primitive: \starttyping \input test \input {test} \input "test" \input 'test' \stoptyping When no suffix is given, \TEX\ will assume the suffix is \type {.tex}. The second one is normally used. \stopoldprimitive \startoldprimitive[title={\prm {inputlineno}}] This integer holds the current linenumber but it is not always reliable. \stopoldprimitive \startoldprimitive[title={\prm {insert}}] This stores content in the insert container with the given index. In \LUAMETATEX\ inserts bubble up to outer boxes so we don't have the \quote {deeply buried insert issue}. \stopoldprimitive \startnewprimitive[title={\prm {insertbox}}] This is the accessor for the box (with results) of an insert with the given index. This is equivalent to the \prm {box} in the traditional method. \stopnewprimitive \startnewprimitive[title={\prm {insertcopy}}] This is the accessor for the box (with results) of an insert with the given index. It makes a copy so the original is kept. This is equivalent to a \prm {copy} in the traditional method. \stopnewprimitive \startnewprimitive[title={\prm {insertdepth}}] This is the (current) depth of the inserted material with the given index. It is comparable to the \prm {dp} in the traditional method. \stopnewprimitive \startnewprimitive[title={\prm {insertdistance}}] This is the space before the inserted material with the given index. This is equivalent to \prm {glue} in the traditional method. \stopnewprimitive \startnewprimitive[title={\prm {insertheight}}] This is the (current) depth of the inserted material with the given index. It is comparable to the \prm {ht} in the traditional method. \stopnewprimitive \startnewprimitive[title={\prm {insertheights}}] This is the combined height of the inserted material. \stopnewprimitive \startnewprimitive[title={\prm {insertlimit}}] This is the maximum height that the inserted material with the given index can get. This is equivalent to \prm {dimen} in the traditional method. \stopnewprimitive \startnewprimitive[title={\prm {insertmaxdepth}}] This is the maximum depth that the inserted material with the given index can get. \stopnewprimitive \startnewprimitive[title={\prm {insertmode}}] In traditional \TEX\ inserts are controlled by a \prm {box}, \prm {dimen}, \prm {glue} and \prm {count} register with the same index. The allocators have to take this into account. When this primitive is set to one a different model is followed with its own namespace. There are more abstract accessors to interface to this. \footnote {The old model might be removed at some point.} \stopnewprimitive \startnewprimitive[title={\prm {insertmultiplier}}] This is the height (contribution) multiplier for the inserted material with the given index. This is equivalent to \prm {count} in the traditional method. \stopnewprimitive \startoldprimitive[title={\prm {insertpenalties}}] This dual purpose internal counter holds the sum of penalties for insertions that got split. When we're the output routine in reports the number of insertions that is kept in store. \stopoldprimitive \startnewprimitive[title={\prm {insertpenalty}}] This is the insert penalty associated with the inserted material with the given index. \stopnewprimitive \startnewprimitive[title={\prm {insertprogress}}] This returns the current accumulated insert height of the insert with the given index. \stopnewprimitive \startnewprimitive[title={\prm {insertstorage}}] The value passed will enable (one) or disable (zero) the insert with the given index. \stopnewprimitive \startnewprimitive[title={\prm {insertstoring}}] The value passed will enable (one) or disable (zero) inserts. \stopnewprimitive \startnewprimitive[title={\prm {insertunbox}}] This is the accessor for the box (with results) of an insert with the given index. It makes a copy so the original is kept. The content is unpacked and injected. This is equivalent to an \prm {unvbox} in the traditional method. \stopnewprimitive \startnewprimitive[title={\prm {insertuncopy}}] This is the accessor for the box (with results) of an insert with the given index. It makes a copy so the original is kept. The content is unpacked and injected. This is equivalent to the \prm {unvcopy} in the traditional method. \stopnewprimitive \startnewprimitive[title={\prm {insertwidth}}] This is the (current) width of the inserted material with the given index. It is comparable to the \prm {wd} in the traditional method. \stopnewprimitive \startnewprimitive[title={\prm {instance}}] This prefix flags a macro as an instance which is mostly relevant when a macro package want to categorize macros. \stopnewprimitive \startnewprimitive[title={\prm {integerdef}}] You can alias to a count (integer) register with \prm {countdef}: \starttyping \countdef\MyCount134 \stoptyping Afterwards the next two are equivalent: \starttyping \MyCount = 99 \count1234 = 99 \stoptyping where \type {\MyCount} can be a bit more efficient because no index needs to be scanned. However, in terms of storage the value (here 99) is always in the register so \type {\MyCount} has to get there. This indirectness has the benefit that directly setting the value is reflected in the indirect accessor. \starttyping \integerdef\MyCount = 99 \stoptyping This primitive also defines a numeric equivalent but this time the number is stored with the equivalent. This means that: \starttyping \let\MyCopyOfCount = \MyCount \stoptyping will store the {\em current} value of \type {\MyCount} in \type {\MyCopyOfCount} and changing either of them is not reflected in the other. The usual \prm {advance}, \prm {multiply} and \prm {divide} can be used with these integers and they behave like any number. But compared to registers they are actually more a constant. \stopnewprimitive \startoldprimitive[title={\prm {interactionmode}}] This internal integer can be used to set or query the current interaction mode: \starttabulate[||||] \NC \type {\batchmode } \NC \the\batchmodecode \NC omits all stops and terminal output \NC \NR \NC \type {\nonstopmode } \NC \the\nonstopmodecode \NC omits all stops \NC \NR \NC \type {\scrollmode } \NC \the\scrollmodecode \NC omits error stops \NC \NR \NC \type {\errorstopmode} \NC \the\errorstopmodecode \NC stops at every opportunity to interact \NC \NR \stoptabulate % In \LUAMETATEX, for consistency, we have enabled these four as integers after % \prm {the} but we can also decide to remove them and do this. So we leave this % as an undocumented feature. It could have been an \ETEX\ way of abstracting the % numeric values. % % \untraced\permanent\protected\def\batchmode {\interactionmode\batchmodecode} % \untraced\permanent\protected\def\nonstopmode {\interactionmode\nonstopmodecode} % \untraced\permanent\protected\def\scrollmode {\interactionmode\scrollmodecode} % \untraced\permanent\protected\def\errorstopmode{\interactionmode\errorstopmodecode} \stopoldprimitive \startoldprimitive[title={\prm {interlinepenalties}}] This is a more granular variant of \prm {interlinepenalty}: an array of penalties to be put between successive line from the start of a paragraph. The list starts with the number of penalties that gets passed. \stopoldprimitive \startoldprimitive[title={\prm {interlinepenalty}}] This is the penalty that is put between lines. \stopoldprimitive \startoldprimitive[title={\prm {jobname}}] This gives the current job name without suffix: {\tttf \jobname}. \stopoldprimitive \startoldprimitive[title={\prm {kern}}] A kern is injected with the given dimension. For variants that switch to a mode we have \prm {hkern} and \prm {vkern}. \stopoldprimitive \startoldprimitive[title={\prm {language}}] Sets (or returns) the current language, a number. In \LUATEX\ and \LUAMETATEX\ the current language is stored in the glyph nodes. \stopoldprimitive \startnewprimitive[title={\prm {lastarguments}}] \startbuffer \def\MyMacro #1{\the\lastarguments (#1) } \MyMacro{1} \crlf \def\MyMacro #1#2{\the\lastarguments (#1) (#2)} \MyMacro{1}{2} \crlf \def\MyMacro#1#2#3{\the\lastarguments (#1) (#2) (#3)} \MyMacro{1}{2}{3} \par \def\MyMacro #1{(#1) \the\lastarguments} \MyMacro{1} \crlf \def\MyMacro #1#2{(#1) (#2) \the\lastarguments} \MyMacro{1}{2} \crlf \def\MyMacro#1#2#3{(#1) (#2) (#3) \the\lastarguments} \MyMacro{1}{2}{3} \par \stopbuffer \typebuffer The value of \prm {lastarguments} can only be trusted in the expansion until another macro is seen and expanded. For instance in these examples, as soon as a character (like the left parenthesis) is seen, horizontal mode is entered and \prm {everypar} is expanded which in turn can involve macros. You can see that in the second block (that is: unless we changed \prm {everypar} in the meantime). {\getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {lastatomclass}}] This returns the class number of the last atom seen in the math input parser. \stopnewprimitive \startnewprimitive[title={\prm {lastboundary}}] This primitive looks back in the list for a user boundary injected with \prm {boundary} and when seen it returns that value or otherwise zero. \stopnewprimitive \startoldprimitive[title={\prm {lastbox}}] When issued this primitive will, if possible, pull the last box from the current list. \stopoldprimitive \startnewprimitive[title={\prm {lastchkdimension}}] When the last check for a dimension with \prm {ifchkdimension} was successful this primitive returns the value. \stopnewprimitive \startnewprimitive[title={\prm {lastchknumber}}] When the last check for an integer with \prm {ifchknumber} was successful this primitive returns the value. \stopnewprimitive \startoldprimitive[title={\prm {lastkern}}] This returns the last kern seen in the list (if possible). \stopoldprimitive \startnewprimitive[title={\prm {lastleftclass}}] This variable registers the first applied math class in a formula. \stopnewprimitive \startoldprimitive[title={\prm {lastlinefit}}] The \ETEX\ manuals explains this parameter in detail but in practice it is enough to know that when set to 1000 spaces in the last line might match those in the previous line. Basically it counters the strong push of a \prm {parfillskip}. \stopoldprimitive \startnewprimitive[title={\prm {lastloopiterator}}] In addition to \prm {currentloopiterator} we have a variant that stores the value in case an unexpanded loop is used: \startbuffer \localcontrolledrepeat 8 { [\the\currentloopiterator\eq\the\lastloopiterator] } \expandedrepeat 8 { [\the\currentloopiterator\eq\the\lastloopiterator] } \unexpandedrepeat 8 { [\the\currentloopiterator\ne\the\lastloopiterator] } \stopbuffer \typebuffer \startlines \getbuffer \stoplines \stopnewprimitive \startnewprimitive[title={\prm {lastnamedcs}}] The example code in the previous section has some redundancy, in the sense that there to be looked up control sequence name \type {mymacro} is assembled twice. This is no big deal in a traditional eight bit \TEX\ but in a \UNICODE\ engine multi|-|byte sequences demand some more processing (although it is unlikely that control sequences have many multi|-|byte \UTF8\ characters). \starttyping \ifcsname mymacro\endcsname \csname mymacro\endcsname \fi \stoptyping Instead we can say: \starttyping \ifcsname mymacro\endcsname \lastnamedcs \fi \stoptyping Although there can be some performance benefits another advantage is that it uses less tokens and parsing. It might even look nicer. \stopnewprimitive \startnewprimitive[title={\prm {lastnodesubtype}}] When possible this returns the subtype of the last node in the current node list. Possible values can be queried (for each node type) via \LUA\ helpers. \stopnewprimitive \startoldprimitive[title={\prm {lastnodetype}}] When possible this returns the type of the last node in the current node list. Possible values can be queried via \LUA\ helpers. \stopoldprimitive \startnewprimitive[title={\prm {lastpageextra}}] This reports the last applied (permitted) overshoot. \stopnewprimitive \startnewprimitive[title={\prm {lastparcontext}}] When a paragraph is wrapped up the reason is reported by this state variable. Possible values are: \startcolumns[n=4] \getbuffer[engine:syntax:parcontextcodes] \stopcolumns \stopnewprimitive \startnewprimitive[title={\prm {lastpartrigger}}] There are several reasons for entering a paragraphs and some are automatic and triggered by other commands that force \TEX\ into horizontal mode. \startcolumns[n=4] \getbuffer[engine:syntax:partriggercodes] \stopcolumns \stopnewprimitive \startoldprimitive[title={\prm {lastpenalty}}] This returns the last penalty seen in the list (if possible). \stopoldprimitive \startnewprimitive[title={\prm {lastrightclass}}] This variable registers the last applied math class in a formula. \stopnewprimitive \startoldprimitive[title={\prm {lastskip}}] This returns the last glue seen in the list (if possible). \stopoldprimitive \startoldprimitive[title={\prm {lccode}}] When the \prm {lowercase} operation is applied the lowercase code of a character is used for the replacement. This primitive is used to set that code, so it expects two character number. The code is also used to determine what characters make a word suitable for hyphenation, although in \LUATEX\ we introduced the \prm {hj} code for that. \stopoldprimitive \startoldprimitive[title={\prm {leaders}}] See \prm {gleaders} for an explanation. \stopoldprimitive \startoldprimitive[title={\prm {left}}] Inserts the given delimiter as left fence in a math formula. \stopoldprimitive \startoldprimitive[title={\prm {lefthyphenmin}}] This is the minimum number of characters after the last hyphen in a hyphenated word. \stopoldprimitive \startnewprimitive[title={\prm {leftmarginkern}}] The dimension returned is the protrusion kern that has been added (if at all) to the left of the content in the given box. \stopnewprimitive \startoldprimitive[title={\prm {leftskip}}] This skip will be inserted at the left of every line. \stopoldprimitive \startoldprimitive[title={\prm {leqno}}] This primitive stores the (typeset) content (presumably a number) and when the display formula is wrapped that number will end up left of the formula. \stopoldprimitive \startoldprimitive[title={\prm {let}}] Where a \prm {def} creates a new macro, either or not with argument, a \prm {let} creates an alias. You are not limited to aliasing macros, basically everything can be aliased. \stopoldprimitive \startnewprimitive[title={\prm {letcharcode}}] Assigning a meaning to an active character can sometimes be a bit cumbersome; think of using some documented uppercase magic that one tends to forget as it's used only a few times and then never looked at again. So we have this: \startbuffer {\letcharcode 65 1 \catcode 65 13 A : \meaning A}\crlf {\letcharcode 65 2 \catcode 65 13 A : \meaning A}\par \stopbuffer \typebuffer here we define \type {A} as an active charcter with meaning \type {1} in the first line and \type {2} in the second. {\tttf \getbuffer} Normally one will assign a control sequence: \startbuffer {\letcharcode 66 \bf \catcode 66 13 {B bold}: \meaning B}\crlf {\letcharcode 73 \it \catcode 73 13 {I italic}: \meaning I}\par \stopbuffer \typebuffer Of course \type {\bf} and \type {\it} are \CONTEXT\ specific commands: {\tttf \getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {letcsname}}] It is easy to see that we save two tokens when we use this primitive. As with the \type {..defcs..} variants it also saves a push back of the composed macro name. \starttyping \expandafter\let\csname MyMacro:1\endcsname\relax \letcsname MyMacro:1\endcsname\relax \stoptyping \stopnewprimitive \startnewprimitive[title={\prm {letfrozen}}] You can explicitly freeze an unfrozen macro: \starttyping \def\MyMacro{...} \letfrozen\MyMacro \stoptyping A redefinition will now give: \starttyping ! You can't redefine a frozen macro. \stoptyping \stopnewprimitive \startnewprimitive[title={\prm {letmathatomrule}}] You can change the class for a specific style. This probably only makes sense for user classes. It's one of those features that we used when experimenting with more control. \starttyping \letmathatomrule 4 = 4 4 0 0 \letmathatomrule 5 = 5 5 0 0 \stoptyping This changes the classes~4 and~5 into class~ 0 in the two script styles and keeps them the same in display and text. We leave it to the reader to ponder how useful this is. \stopnewprimitive % \startnewprimitive[title={\prm {letmathparent}}] % \stopnewprimitive % \startnewprimitive[title={\prm {letmathspacing}}] % \stopnewprimitive \startnewprimitive[title={\prm {letprotected}}] Say that you have these definitions: \startbuffer \def \MyMacroA{alpha} \protected \def \MyMacroB{beta} \edef \MyMacroC{\MyMacroA\MyMacroB} \letprotected \MyMacroA \edef \MyMacroD{\MyMacroA\MyMacroB} \meaning \MyMacroC\crlf \meaning \MyMacroD\par \stopbuffer \typebuffer The typeset meaning in this example is: {\tttf \getbuffer} \stopnewprimitive \startnewprimitive[title={\prm {lettolastnamedcs}}] The \prm {lastnamedcs} primitive is somewhat special as it is a (possible) reference to a control sequence which is why we have a dedicated variant of \prm {let}. \startbuffer \csname relax\endcsname\let \foo\lastnamedcs \meaning\foo \csname relax\endcsname\expandafter\let\expandafter \oof\lastnamedcs \meaning\oof \csname relax\endcsname\lettolastnamedcs \ofo \meaning\ofo \stopbuffer \typebuffer % we need oneliners because intermediate csnames kick in These give the following where the first one obviously is not doing what we want and the second one is kind of cumbersome. \startlines \getbuffer \stoplines \stopnewprimitive \startnewprimitive[title={\prm {lettonothing}}] This one let's a control sequence to nothing. Assuming that \type {\empty} is indeed empty, these two lines are equivalent. \starttyping \let \foo\empty \lettonothing\oof \stoptyping \stopnewprimitive \startoldprimitive[title={\prm {limits}}] This is a modifier: it flags the previous math atom to have its scripts above and below the (summation, product, integral etc.) symbol. In \LUAMETATEX\ this can be any atom (that is: any class). In display mode the location defaults to above and below. \stopoldprimitive \startnewprimitive[title={\prm {linebreakcriterion}}] The par builder has a concept of \quote {compatible} lines, and has categories for that: loose, decent and tight. In \LUAMETATEX\ we also have semi|-|loose and semi|-|tight as intermediate categories. This parameter can set the ranges for those, using four double bytes: \starttabulate[|T|l|c|] \NC 0x7F000000 \NC semi tight \NC 12 \NC \NR \NC 0x007F0000 \NC decent \NC 12 \NC \NR \NC 0x00007F00 \NC semi loose \NC 12 \NC \NR \NC 0x0000007F \NC loose \NC 99 \NC \NR \stoptabulate The (decimal) default values are given in the last column. Don't expect a big influence from changing these and this option is mostly a side effect of experiments. \stopnewprimitive \startnewprimitive[title={\prm {linebreakoptional}}] This selects the optional text range that is to be used. Optional content is marked with {optionalboundary} nodes. \stopnewprimitive \startnewprimitive[title={\prm {linebreakpasses}}] When set to a positive value it will apply additional line break runs defined with \prm {parpasses} until the criteria set in there are met. When set to~$-1$ it will signal a final pass \stopnewprimitive \startnewprimitive[title={\prm {linedirection}}] This sets the text direction (1 for \type {r2l}) to the given value but keeps preceding glue into the range. \stopnewprimitive \startoldprimitive[title={\prm {linepenalty}}] Every line gets this penalty attached, so normally it is a small value, like here: \the \linepenalty. \stopoldprimitive \startoldprimitive[title={\prm {lineskip}}] This is the amount of glue that gets added when the distance between lines falls below \prm {lineskiplimit}. \stopoldprimitive \startoldprimitive[title={\prm {lineskiplimit}}] When the distance between two lines becomes less than \prm {lineskiplimit} a \prm {lineskip} glue item is added. \startbuffer \ruledvbox{ \lineskiplimit 0pt \lineskip3pt \baselineskip0pt \ruledhbox{line 1} \ruledhbox{line 2} \ruledhbox{\tx line 3} } \stopbuffer \typebuffer Normally the \prm {baselineskip} kicks in first but here we've set that to zero, so we get two times a 3pt glue injected. \startlocallinecorrection \getbuffer \stoplocallinecorrection \stopoldprimitive % \startnewprimitive[title={\prm {localbrokenpenalty}}] % \stopnewprimitive \startnewprimitive[title={\prm {localcontrol}}] This primitive takes a single token: \startbuffer \edef\testa{\scratchcounter123 \the\scratchcounter} \edef\testc{\testa \the\scratchcounter} \edef\testd{\localcontrol\testa \the\scratchcounter} \stopbuffer \typebuffer The three meanings are: \start \getbuffer \starttabulate[|T|T|] \NC \string\testa \NC \meaning\testa \NC \NR \NC \string\testc \NC \meaning\testc \NC \NR \NC \string\testd \NC \meaning\testd \NC \NR \stoptabulate \stop The \prm {localcontrol} makes that the following token gets expanded so we don't see the yet to be expanded assignment show up in the macro body. \stopnewprimitive \startnewprimitive[title={\prm {localcontrolled}}] The previously described local control feature comes with two extra helpers. The \prm {localcontrolled} primitive takes a token list and wraps this into a local control sidetrack. For example: \startbuffer \edef\testa{\scratchcounter123 \the\scratchcounter} \edef\testb{\localcontrolled{\scratchcounter123}\the\scratchcounter} \stopbuffer \typebuffer The two meanings are: \start \getbuffer \starttabulate[|T|T|] \NC \string\testa \NC \meaningfull\testa \NC \NR \NC \string\testb \NC \meaningfull\testb \NC \NR \stoptabulate \stop The assignment is applied immediately in the expanded definition. \stopnewprimitive \startnewprimitive[title={\prm {localcontrolledendless}}] As the name indicates this will loop forever. You need to explicitly quit the loop with \prm {quitloop} or \prm {quitloopnow}. The first quitter aborts the loop at the start of a next iteration, the second one tries to exit immediately, but is sensitive for interference with for instance nested conditionals. \stopnewprimitive \startnewprimitive[title={\prm {localcontrolledloop}}] As with more of the primitives discussed here, there is a manual in the \quote {lowlevel} subset that goes into more detail. So, here a simple example has to do: \startbuffer \localcontrolledloop 1 100 1 {% \ifnum\currentloopiterator>6\relax \quitloop \else [\number\currentloopnesting:\number\currentloopiterator] \localcontrolledloop 1 8 1 {% (\number\currentloopnesting:\number\currentloopiterator) }\par \fi } \stopbuffer \typebuffer Here we see the main loop primitive being used nested. The code shows how we can \prm {quitloop} and have access to the \prm {currentloopiterator} as well as the nesting depth \prm {currentloopnesting}. \startpacked \getbuffer \stoppacked Be aware of the fact that \prm {quitloop} will end the loop at the {\em next} iteration so any content after it will show up. Normally this one will be issued in a condition and we want to end that properly. Also keep in mind that because we use local control (a nested \TEX\ expansion loop) anything you feed back can be injected out of order. The three numbers can be separated by an equal sign which is a trick to avoid look ahead issues that can result from multiple serialized numbers without spaces that indicate the end of sequence of digits. \stopnewprimitive \startnewprimitive[title={\prm {localcontrolledrepeat}}] This one takes one instead three arguments which looks a bit better in simple looping. \stopnewprimitive % \startnewprimitive[title={\prm {localinterlinepenalty}}] % \stopnewprimitive \startnewprimitive[title={\prm {localleftbox}}] This sets the box that gets injected at the left of every line. \stopnewprimitive \startnewprimitive[title={\prm {localleftboxbox}}] This returns the box set with \prm {localleftbox}. \stopnewprimitive \startnewprimitive[title={\prm {localmiddlebox}}] This sets the box that gets injected at the left of every line but its width is ignored. \stopnewprimitive \startnewprimitive[title={\prm {localmiddleboxbox}}] This returns the box set with \prm {localmiddlebox}. \stopnewprimitive % \startnewprimitive[title={\prm {localpretolerance}}] % \stopnewprimitive \startnewprimitive[title={\prm {localrightbox}}] This sets the box that gets injected at the right of every line. \stopnewprimitive \startnewprimitive[title={\prm {localrightboxbox}}] This returns the box set with \prm {localrightbox}. \stopnewprimitive % \startnewprimitive[title={\prm {localtolerance}}] % \stopnewprimitive \startoldprimitive[title={\prm {long}}][obsolete=yes] This original prefix gave the macro being defined the property that it could not have \prm {par} (or the often equivalent empty lines) in its arguments. It was mostly a protection against a forgotten right curly brace, resulting in a so called run|-|away argument. That mattered on a paper terminal or slow system where such a situation should be catched early. In \LUATEX\ it was already optional, and in \LUAMETATEX\ we dropped this feature completely (so that we could introduce others). \stopoldprimitive \startoldprimitive[title={\prm {looseness}}] The number fo lines in the current paragraph will be increased by given number of lines. For this to succeed there need to be enough stretch in the spacing to make that happen. There is some wishful thinking involved. \stopoldprimitive \startoldprimitive[title={\prm {lower}}] This primitive takes two arguments, a dimension and a box. The box is moved down. The operation only succeeds in horizontal mode. \stopoldprimitive \startoldprimitive[title={\prm {lowercase}}] This token processor converts character tokens to their lowercase counterparts as defined per \prm {lccode}. In order to permit dirty tricks active characters are also processed. We don't really use this primitive in \CONTEXT, but for consistency we let it respond to \prm {expand}: \footnote {Instead of providing \type {\lowercased} and \type {\uppercased} primitives that would clash with macros anyway.} \startbuffer \edef \foo {\lowercase{tex TeX \TEX}} \meaningless\foo \lowercase{\edef\foo {tex TeX \TEX}} \meaningless\foo \edef \foo{\expand\lowercase{tex TeX \TEX}} \meaningless\foo \stopbuffer \typebuffer Watch how \prm {lowercase} is not expandable but can be forced to. Of course, as the logo macro is protected the \TEX\ logo remains mixed case. \startlines \getbuffer \stoplines \stopoldprimitive \startnewprimitive[title={\prm {lpcode}}] This one can be used to set the left protrusion factor of a glyph in a font and takes three arguments: font, character code and factor. It is kind of obsolete because we can set up vectors at definition time and tweaking from \TEX\ can have side effects because it globally adapts the font. \stopnewprimitive \startnewprimitive[title={\prm {luabytecode}}] This behaves like \prm {luafunction} but here the number is a byte code register. These bytecodes are in the \typ {lua.bytecode} array. \stopnewprimitive \startnewprimitive[title={\prm {luabytecodecall}}] This behaves like \prm {luafunctioncall} but here the number is a byte code register. These bytecodes are in the \typ {lua.bytecode} array. \stopnewprimitive \startnewprimitive[title={\prm {luacopyinputnodes}}] When set to a positive value this will ensure that when nodes are printed from \LUA\ to \TEX\ copies are used. \stopnewprimitive \startnewprimitive[title={\prm {luadef}}] % \edef\foocode{\ctxlua{ % context( % context.functions.register( % function() context("!") end % ) % ) % }} This command relates a (user) command to a \LUA\ function registered in the \typ {lua.lualib_get_functions_table()}, so after: \starttyping \luadef\foo123 \stoptyping the \type {\foo} command will trigger the function at index 123. Of course a macro package has to make sure that these definitions are unique. \footnote {Plain \TEX\ established a norm for allocating registers, like \typ {\newdimen} but there is no such convention for \LUA\ functions.} This command is accompanied by \prm {luafunctioncall} and \prm {luafunction}. When we have funciton 123 defined as \starttyping function() tex.sprint("!") end \stoptyping the following: \starttyping (\luafunctioncall \foocode ?) (\normalluafunction\foocode ?) (\foo ?) \stoptyping gives three times \type {(!?)}. But this: \starttyping \edef\oof{\foo } \meaning\oof % protected \edef\oof{\luafunctioncall \foocode} \meaning\oof % protected \edef\oof{\normalluafunction\foocode} \meaning\oof % expands \stoptyping returns: \starttyping macro:! macro:\luafunctioncall 1740 macro:! \stoptyping Because the definition command is like any other \starttyping \permanent\protected\luadef\foo123 \stoptyping boils down to: \starttyping permanent protected luacall 123 \stoptyping \stopnewprimitive \startnewprimitive[title={\prm {luaescapestring}}] This command converts the given (token) list into something that is acceptable for \LUA. It is inherited from \LUATEX\ and not used in \CONTEXT. \startbuffer \directlua { tex.print ("\luaescapestring {{\tt This is a "test".}}") } \stopbuffer \typebuffer Results in: \inlinebuffer\space (Watch the grouping.) \stopnewprimitive \startnewprimitive[title={\prm {luafunction}}] The integer passed to this primitive is the index in the table returned by \typ {lua.lualib_get_functions_table()}. Of course a macro package has to provide reliable management for this. This is a so called convert command so it expands in an expansion context (like an \prm {edef}). \stopnewprimitive \startnewprimitive[title={\prm {luafunctioncall}}] The integer passed to this primitive is the index in the table returned by \typ {lua.lualib_get_functions_table()}. Of course a macro package has to provide reliable management for this. This primitive doesn't expand in an expansion context (like an \prm {edef}). \stopnewprimitive \startnewprimitive[title={\prm {luatexbanner}}] This gives: {\tttf \luatexbanner}. \stopnewprimitive \startnewprimitive[title={\prm {luatexrevision}}] This is an integer. The current value is: {\tttf \number\luatexrevision}. \stopnewprimitive \startnewprimitive[title={\prm {luatexversion}}] This is an integer. The current value is: {\tttf \number\luatexversion}. \stopnewprimitive \startoldprimitive[title={\prm {mark}}][obsolete=yes] The given token list is stored in a node in the current list and might become content of \prm {topmark}, \prm {botmark} or \prm {firstmark} when a page split off, or in the case of a box split in \prm {splitbotmark} or \prm {splitfirstmark}. In \LUAMETATEX\ deeply burried marks bubbly up to an outer box level. \stopoldprimitive \startoldprimitive[title={\prm {marks}}] This command is similar to \prm {mark} but first expects a number of a mark register. Multiple marks were introduced in \ETEX. \stopoldprimitive \startoldprimitive[title={\prm {mathaccent}}][obsolete=yes] This takes a number and a math object to put the accent on. The four byte number has a dummy class byte, a family byte and two index bytes. It is replaced by \prm {Umathaccent} that handles wide fonts. \stopoldprimitive \startnewprimitive[title={\prm {mathatom}}] This operation wraps following content in a atom with the given class. It is part of \LUAMETATEX's extended math support. There are three class related key|/|values: \type {class}, \typ {leftclass} and \typ {rightclass} (or \type {all} for all of them). When none is given this command expects a class number before scanning the content. The \type {options} key expects a bitset but there are also direct option keys, like \type {limits}, \typ {nolimits}, \type {unpack}, \type {unroll}, \type {single}, \type {nooverflow}, \type {void} and \type {phantom}. A \type {source} id can be set, one or more \type {attr} assigned, and for specific purposes \typ {textfont} and \typ {mathfont} directives are accepted. Features like this are discussed in dedicated manuals. \stopnewprimitive % \startnewprimitive[title={\prm {mathatomglue}}] % \stopnewprimitive % \startnewprimitive[title={\prm {mathatomskip}}] % \stopnewprimitive % \startnewprimitive[title={\prm {mathbackwardpenalties}}] % \stopnewprimitive \startnewprimitive[title={\prm {mathbeginclass}}] This variable can be set to signal the class that starts the formula (think of an imaginary leading atom). \stopnewprimitive \startoldprimitive[title={\prm {mathbin}}] This operation wraps following content in a atom with class \quote {binary}. \stopoldprimitive % \startnewprimitive[title={\prm {mathboundary}}] % \stopnewprimitive \startoldprimitive[title={\prm {mathchar}}][obsolete=yes] Replaced by \prm {Umathchar} this old one takes a four byte number: one byte for the class, one for the family an two for the index. The specified character is appended to to the list. \stopoldprimitive \startnewprimitive[title={\prm {mathcharclass}}] Returns the slot (in the font) of the given math character. \startbuffer \the\mathcharclass\Umathchar 4 2 123 \stopbuffer \typebuffer The first passed number is the class, so we get: \inlinebuffer. \stopnewprimitive \startoldprimitive[title={\prm {mathchardef}}][obsolete=yes] Replaced by \prm {Umathchardef} this primitive relates a control sequence with a four byte number: one byte for the class, one for the family an two for the index. The defined command will insert that character. \stopoldprimitive \startnewprimitive[title={\prm {mathcharfam}}] Returns the family number of the given math character. \startbuffer \the\mathcharfam\Umathchar 4 2 123 \stopbuffer \typebuffer The second passed number is the family, so we get: \inlinebuffer. \stopnewprimitive \startnewprimitive[title={\prm {mathcharslot}}] Returns the slot (or index in the font) of the given math character. \startbuffer \the\mathcharslot\Umathchar 4 2 123 \stopbuffer \typebuffer The third passed number is the slot, so we get: \inlinebuffer. \stopnewprimitive % \startnewprimitive[title={\prm {mathcheckfencesmode}}] % \stopnewprimitive \startoldprimitive[title={\prm {mathchoice}}] This command expects four subformulas, for display, text, script and scriptscript and it will eventually use one of them depending on circumstances later on. Keep in mind that a formula is first scanned and when that is finished the analysis and typesetting happens. \stopoldprimitive \startnewprimitive[title={\prm {mathclass}}] This primitive expects a class number and a valid character number or math character and inserts the symbol as if it were of the given class; so the original class is replaced. \startbuffer \ruledhbox{$(x)$} and \ruledhbox{$\mathclass 1 `(x\mathclass 1 `)$} \stopbuffer \typebuffer Changing the class is likely to change the spacing, compare \inlinebuffer. \stopnewprimitive \startoldprimitive[title={\prm {mathclose}}] This operation wraps following content in a atom with class \quote {close}. \stopoldprimitive \startoldprimitive[title={\prm {mathcode}}][obsolete=yes] This maps a character to one in a family: the assigned value has one byte for the class, one for the family and two for the index. It has little use in an \OPENTYPE\ math setup. \stopoldprimitive % \startnewprimitive[title={\prm {mathdictgroup}}] % \stopnewprimitive % \startnewprimitive[title={\prm {mathdictionary}}] % \stopnewprimitive % \startnewprimitive[title={\prm {mathdictproperties}}] % \stopnewprimitive \startnewprimitive[title={\prm {mathdirection}}] When set to 1 this will result in \type {r2l} typeset math formulas but of course you then also need to set up math accordingly (which is the case in \CONTEXT). \stopnewprimitive % \startnewprimitive[title={\prm {mathdiscretionary}}] % \stopnewprimitive \startnewprimitive[title={\prm {mathdisplaymode}}] Display mode is entered with two dollars (other characters can be used but the dollars are a convention). Mid paragraph display formulas get a different treatment with respect to the width and indentation than stand alone. When \prm {mathdisplaymode} is larger than zero the double dollars (or equivalents) will behave as inline formulas starting out in \prm {displaystyle} and with \prm {everydisplay} expanded. \stopnewprimitive % \startnewprimitive[title={\prm {mathdisplaypenaltyfactor}}] % \stopnewprimitive % \startnewprimitive[title={\prm {mathdisplayskipmode}}] % \stopnewprimitive % \startnewprimitive[title={\prm {mathdoublescriptmode}}] % \stopnewprimitive \startnewprimitive[title={\prm {mathendclass}}] This variable can be set to signal the class that ends the formula (think of an imaginary trailing atom). \stopnewprimitive \startnewprimitive[title={\prm {matheqnogapstep}}] The display formula number placement heuristic puts the number on the same line when there is place and then separates it by a quad. In \LUATEX\ we decided to keep that quantity as it can be tight into the math font metrics but introduce a multiplier \prm {matheqnogapstep} that defaults to 1000. \stopnewprimitive % \startnewprimitive[title={\prm {mathfontcontrol}}] % \stopnewprimitive % \startnewprimitive[title={\prm {mathforwardpenalties}}] % \stopnewprimitive \startnewprimitive[title={\prm {mathgluemode}}] We can influence the way math glue is handled. By default stretch and shrink is applied but this variable can be used to change that. The limit option ensures that the stretch and shrink doesn't go beyond their natural values. \getbuffer[engine:syntax:mathgluecodes] \stopnewprimitive \startnewprimitive[title={\prm {mathgroupingmode}}] Normally a \type {{}} or \type {\bgroup}|-|\type {\egroup} pair in math create a math list. However, users are accustomed to using it also for grouping and then a list being created might not be what a user wants. As an alternative to the more verbose \prm {begingroup}|-|\prm {endgroup} or even less sensitive \prm {beginmathgroup}|-|\prm {endmathgroup} you can set the math grouping mode to a non zero value which makes curly braces (and the aliases) behave as expected. \stopnewprimitive % \startnewprimitive[title={\prm {mathinlinepenaltyfactor}}] % \stopnewprimitive \startoldprimitive[title={\prm {mathinner}}] This operation wraps following content in a atom with class \quote {inner}. In \LUAMETATEX\ we have more classes and this general wrapper one is therefore kind of redundant. \stopoldprimitive \startnewprimitive[title={\prm {mathleftclass}}] When set this class will be used when a formula starts. \stopnewprimitive % \startnewprimitive[title={\prm {mathlimitsmode}}] % \stopnewprimitive % \startnewprimitive[title={\prm {mathmainstyle}}] % \stopnewprimitive % \startnewprimitive[title={\prm {mathnolimitsmode}}] % \stopnewprimitive \startoldprimitive[title={\prm {mathop}}] This operation wraps following content in a atom with class \quote {operator}. \stopoldprimitive \startoldprimitive[title={\prm {mathopen}}] This operation wraps following content in a atom with class \quote {open}. \stopoldprimitive \startoldprimitive[title={\prm {mathord}}] This operation wraps following content in a atom with class \quote {ordinary}. \stopoldprimitive % \startnewprimitive[title={\prm {mathpenaltiesmode}}] % \stopnewprimitive \startnewprimitive[title={\prm {mathpretolerance}}] This is used instead of \prm {pretolerance} when a breakpoint is calculated when a math formula starts. \stopnewprimitive \startoldprimitive[title={\prm {mathpunct}}] This operation wraps following content in a atom with class \quote {punctuation}. \stopoldprimitive \startoldprimitive[title={\prm {mathrel}}] This operation wraps following content in a atom with class \quote {relation}. \stopoldprimitive \startnewprimitive[title={\prm {mathrightclass}}] When set this class will be used when a formula ends. \stopnewprimitive % \startnewprimitive[title={\prm {mathrulesfam}}] % \stopnewprimitive % \startnewprimitive[title={\prm {mathrulesmode}}] % \stopnewprimitive \startnewprimitive[title={\prm {mathscale}}] In \LUAMETATEX\ we can either have a family of three (text, script and scriptscript) fonts or we can use one font that we scale and where we also pass information about alternative shapes for the smaller sizes. When we use this more compact mode this primitive reflects the scale factor used. \startbuffer \im { \textstyle \the\mathscale\textfont \fam\enspace \scriptstyle \the\mathscale\scriptfont \fam\enspace \scriptscriptstyle\the\mathscale\scriptscriptfont\fam\enspace \textstyle \the\mathscale\textfont \fam\enspace \scriptstyle \the\mathscale\textfont \fam\enspace \scriptscriptstyle\the\mathscale\textfont \fam } \stopbuffer What gets reported depends on how math is implemented, where in \CONTEXT\ we can have either normal or compact mode: \inlinebuffer. In compact mode we have the same font three times so then it doesn't matter which of the three is passed. \stopnewprimitive % \startnewprimitive[title={\prm {mathscriptsmode}}] % \stopnewprimitive % \startnewprimitive[title={\prm {mathslackmode}}] % \stopnewprimitive % \startnewprimitive[title={\prm {mathspacingmode}}] % \stopnewprimitive % \startnewprimitive[title={\prm {mathstack}}] % \stopnewprimitive % \startnewprimitive[title={\prm {mathstackstyle}}] % \stopnewprimitive \startnewprimitive[title={\prm {mathstyle}}] This returns the current math style, so \type {$\the\mathstyle$} gives $\the\mathstyle$. \stopnewprimitive % \startnewprimitive[title={\prm {mathstylefontid}}] % \stopnewprimitive \startoldprimitive[title={\prm {mathsurround}}] The kern injected before and after an inline math formula. In practice it will be set to zero, if only because otherwise nested math will also get that space added. We also have \prm {mathsurroundskip} which, when set, takes precedence. Spacing is controlled by \prm {mathsurroundmode}. \stopoldprimitive \startnewprimitive[title={\prm {mathsurroundmode}}] The possible ways to control spacing around inline math formulas in other manuals and mostly serve as playground. \stopnewprimitive \startnewprimitive[title={\prm {mathsurroundskip}}] When set this one wins over \prm {mathsurround}. \stopnewprimitive % \startnewprimitive[title={\prm {maththreshold}}] % \stopnewprimitive \startnewprimitive[title={\prm {mathtolerance}}] This is used instead of \prm {tolerance} when a breakpoint is calculated when a math formula starts. \stopnewprimitive \startoldprimitive[title={\prm {maxdeadcycles}}] When the output routine is called this many times and no page is shipped out an error will be triggered. You therefore need to reset its companion counter \prm {deadcycles} if needed. Keep in mind that \LUAMETATEX\ has no real \prm {shipout} because providing a backend is up to the macro package. \stopoldprimitive \startoldprimitive[title={\prm {maxdepth}}] The depth of the page is limited to this value. \stopoldprimitive \startoldprimitive[title={\prm {meaning}}] We start with a primitive that will be used in the following sections. The reported meaning can look a bit different than the one reported by other engines which is a side effect of additional properties and more extensive argument parsing. \startbuffer \tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaning\foo \stopbuffer \typebuffer \getbuffer \stopoldprimitive \startnewprimitive[title={\prm {meaningasis}}] Although it is not really round trip with the original due to information being lost this primitive tries to return an equivalent definition. \startbuffer \tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaningasis\foo \stopbuffer \typebuffer \getbuffer \stopnewprimitive \startnewprimitive[title={\prm {meaningful}}] This one reports a bit less than \prm {meaningful}. \startbuffer \tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaningful\foo \stopbuffer \typebuffer \getbuffer \stopnewprimitive \startnewprimitive[title={\prm {meaningfull}}] This one reports a bit more than \prm {meaning}. \startbuffer \tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaningfull\foo \stopbuffer \typebuffer \getbuffer \stopnewprimitive \startnewprimitive[title={\prm {meaningles}}] This one reports a bit less than \prm {meaningless}. \startbuffer \tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaningles\foo \stopbuffer \typebuffer \getbuffer \stopnewprimitive \startnewprimitive[title={\prm {meaningless}}] This one reports a bit less than \prm {meaning}. \startbuffer \tolerant\permanent\protected\gdef\foo[#1]#*[#2]{(#1)(#2)} \meaningless\foo \stopbuffer \typebuffer \getbuffer \stopnewprimitive \startoldprimitive[title={\prm {medmuskip}}] A predefined mu skip register that can be used in math (inter atom) spacing. The current value is {\tt \the\medmuskip}. In traditional \TEX\ most inter atom spacing is hard coded using the predefined registers. \stopoldprimitive \startoldprimitive[title={\prm {message}}] Prints the serialization of the (tokenized) argument to the log file and|/|or console. \stopoldprimitive \startoldprimitive[title={\prm {middle}}] Inserts the given delimiter as middle fence in a math formula. In \LUAMETATEX\ it is a full blown fence and not (as in \ETEX) variation of \prm {open}. \stopoldprimitive \startoldprimitive[title={\prm {mkern}}] This one injects a kern node in the current (math) list and expects a value in so called mu units. \stopoldprimitive \startoldprimitive[title={\prm {month}}] This internal number starts out with the month that the job started. \stopoldprimitive \startoldprimitive[title={\prm {moveleft}}] This primitive takes two arguments, a dimension and a box. The box is moved to the left. The operation only succeeds in vertical mode. \stopoldprimitive \startoldprimitive[title={\prm {moveright}}] This primitive takes two arguments, a dimension and a box. The box is moved to the right. The operation only succeeds in vertical mode. \stopoldprimitive \startoldprimitive[title={\prm {mskip}}] The given math glue (in \type {mu} units) is injected in the horizontal list. For this to succeed we need to be in math mode. \stopoldprimitive \startoldprimitive[title={\prm {muexpr}}] This is a companion of \prm {glueexpr} so it handles the optional stretch and shrink components. Here math units (\type {mu}) are expected. \stopoldprimitive \startnewprimitive[title={\prm {mugluespecdef}}] A variant of \prm {gluespecdef} that expects \type {mu} units is: \starttyping \mugluespecdef\MyGlue = 3mu plus 2mu minus 1mu \stoptyping The properties are comparable to the ones described in the previous sections. \stopnewprimitive \startoldprimitive[title={\prm {multiply}}] The given quantity is multiplied by the given integer (that can be preceded by the keyword \quote {by}, like: \starttyping \scratchdimen=10pt \multiply\scratchdimen by 3 \stoptyping \stopoldprimitive \startnewprimitive[title={\prm {multiplyby}}] This is slightly more efficient variant of \prm {multiply} that doesn't look for \type {by}. See previous section. \stopnewprimitive \startoldprimitive[title={\prm {muskip}}] This is the accessor for an indexed muskip (muglue) register. \stopoldprimitive \startoldprimitive[title={\prm {muskipdef}}] This command associates a control sequence with a muskip (math skip) register (accessed by number). \stopoldprimitive \startnewprimitive[title={\prm {mutable}}] This prefix flags what follows can be adapted and is not subjected to overload protection. \stopnewprimitive \startoldprimitive[title={\prm {mutoglue}}] The sequence \typ {\the \mutoglue 20mu plus 10mu minus 5mu} gives \the \mutoglue 20mu plus 10mu minus 5mu. \stopoldprimitive \startnewprimitive[title={\prm {nestedloopiterator}}] This is one of the accessors of loop iterators: \startbuffer \expandedrepeat 2 {% \expandedrepeat 3 {% (n=\the\nestedloopiterator 1, p=\the\previousloopiterator1, c=\the\currentloopiterator) }% }% \stopbuffer \typebuffer Gives: \getbuffer Where a nested iterator starts relative to innermost loop, the previous one is relative to the outer loop (which is less predictable because we can already be in a loop). \stopnewprimitive \startoldprimitive[title={\prm {newlinechar}}] When something is printed to one of the log channels the character with this code will trigger a linebreak. That also resets some counters that deal with suppressing redundant ones and possible indentation. Contrary to other engines \LUAMETATEX\ doesn't bother about the length of lines. \stopoldprimitive \startoldprimitive[title={\prm {noalign}}] The token list passed to this primitive signals that we don't enter a table row yet but for instance in a \prm {halign} do something between the lines: some calculation or injecting inter-row material. In \LUAMETATEX\ this primitive can be used nested. \stopoldprimitive \startnewprimitive[title={\prm {noaligned}}] The alignment mechanism is kind of special when it comes to expansion because it has to look ahead for a \prm {noalign}. This interferes with for instance protected macros, but using this prefix we get around that. Among the reasons to use protected macros inside an alignment is that they behave better inside for instance \prm {expanded}. \stopnewprimitive \startnewprimitive[title={\prm {noatomruling}}] Spacing in math is based on classes and this primitive inserts a signal that there is no ruling in place here. Basically we have a zero skip glue tagged as non breakable because in math mode glue is not a valid breakpoint unless we have configured inter|-|class penalties. \stopnewprimitive \startnewprimitive[title={\prm {noboundary}}] This inserts a boundary node with no specific property. It can still serve as boundary but is not interpreted in special ways, like the others. \stopnewprimitive \startoldprimitive[title={\prm {noexpand}}] This prefix prevents expansion in a context where expansion happens. Another way to prevent expansion is to define a macro as \prm {protected}. \startbuffer \def\foo{foo} \edef\oof{we expanded \foo} \meaning\oof \def\foo{foo} \edef\oof{we keep \noexpand\foo} \meaning\oof \protected\def\foo{foo} \edef\oof{we keep \foo} \meaning\oof \stopbuffer \typebuffer \startlines \getbuffer \stoplines \stopoldprimitive \startnewprimitive[title={\prm {nohrule}}] This is a rule but flagged as empty which means that the dimensions kick in as for a normal rule but the backend can decide not to show it. \stopnewprimitive \startoldprimitive[title={\prm {noindent}}] This starts a paragraph. In \LUATEX\ (and \LUAMETATEX) a paragraph starts with a so called par node (see \prm {indent} on how control that. After that comes either \prm {parindent} glue or a horizontal box. The \prm {indent} makes gives them some width, while \prm {noindent} keeps that zero. \stopoldprimitive \startoldprimitive[title={\prm {nolimits}}] This is a modifier: it flags the previous math atom to have its scripts after the the atom (contrary to \prm {limits}. In \LUAMETATEX\ this can be any atom (that is: any class). In display mode the location defaults to above and below. \stopoldprimitive \startoldprimitive[title={\prm {nonscript}}] This prevents \TEX\ from adding inter|-|atom glue at this spot in script or scriptscript mode. It actually is a special glue itself that serves as signal. \stopoldprimitive \startoldprimitive[title={\prm {nonstopmode}}] This directive omits all stops. \stopoldprimitive \startnewprimitive[title={\prm {norelax}}] The rationale for this command can be shown by a few examples: \startbuffer \dimen0 1pt \dimen2 1pt \dimen4 2pt \edef\testa{\ifdim\dimen0=\dimen2\norelax N\else Y\fi} \edef\testb{\ifdim\dimen0=\dimen2\relax N\else Y\fi} \edef\testc{\ifdim\dimen0=\dimen4\norelax N\else Y\fi} \edef\testd{\ifdim\dimen0=\dimen4\relax N\else Y\fi} \edef\teste{\norelax} \stopbuffer \typebuffer The five meanings are: \start \getbuffer \starttabulate[|T|T|] \NC \string\testa \NC \meaning\testa \NC \NR \NC \string\testb \NC \meaning\testb \NC \NR \NC \string\testc \NC \meaning\testc \NC \NR \NC \string\testd \NC \meaning\testd \NC \NR \NC \string\teste \NC \meaning\teste \NC \NR \stoptabulate \stop So, the \prm {norelax} acts like \prm {relax} but is not pushed back as usual (in some cases). \stopnewprimitive \startnewprimitive[title={\prm {normalizelinemode}}] The \TEX\ engine was not designed to be opened up, and therefore the result of the linebreak effort can differ depending on the conditions. For instance not every line gets the left- or rightskip. The first and last lines have some unique components too. When \LUATEX\ made it possible too get the (intermediate) result manipulating the result also involved checking what one encountered, for instance glue and its origin. In \LUAMETATEX\ we can normalize lines so that they have for instance balanced skips. \startcolumns[n=2] \getbuffer[engine:syntax:normalizelinecodes] \stopcolumns The order in which the skips get inserted when we normalize is as follows: \starttabulate \NC \prm {lefthangskip} \NC the hanging indentation (or zero) \NC \NR \NC \prm {leftskip} \NC the value even when zero \NC \NR \NC \prm {parfillleftskip} \NC only on the last line \NC \NR \NC \prm {parinitleftskip} \NC only on the first line \NC \NR \NC \prm {indentskip} \NC the amount of indentation \NC \NR \NC \unknown \NC the (optional) content \NC \NR \NC \prm {parinitrightskip} \NC only on the first line \NC \NR \NC \prm {parfillrightskip} \NC only on the last line \NC \NR \NC \prm {correctionskip} \NC the correction needed to stay within the \prm {hsize} \NC \NR \NC \prm {rightskip} \NC the value even when zero \NC \NR \NC \prm {righthangskip} \NC the hanging indentation (or zero) \NC \NR \stoptabulate The init and fill skips can both show up when we have a single line. The correction skip replaces the traditional juggling with the right skip and shift of the boxed line. For now we leave the other options to your imagination. Some of these can be achieved by callbacks (as we did in older versions of \CONTEXT) but having the engine do the work we get a better performance. \stopnewprimitive \startnewprimitive[title={\prm {normalizeparmode}}] For now we just mention the few options available. It is also worth mentioning that \LUAMETATEX\ tries to balance the direction nodes. \startcolumns[n=2] \getbuffer[engine:syntax:normalizeparcodes] \stopcolumns \stopnewprimitive \startnewprimitive[title={\prm {nospaces}}] When \prm {nospaces} is set to~1 no spaces are inserted, when its value is~2 a zero space is inserted. The default value is~0 which means that spaces become glue with properties depending on the font, specific parameters and|/|or space factors determined preceding characters. \stopnewprimitive \startnewprimitive[title={\prm {nosubprescript}}] This processes the given script in the current style, so: \startbuffer $ x__2 + x\nosubprescript{2} + x\subprescript{2} $ \stopbuffer comes out as: \inlinebuffer. \stopnewprimitive \startnewprimitive[title={\prm {nosubscript}}] This processes the given script in the current style, so: \startbuffer $ x__2 + x\nosubscript{2} + x\subscript{2} $ \stopbuffer comes out as: \inlinebuffer. \stopnewprimitive \startnewprimitive[title={\prm {nosuperprescript}}] This processes the given script in the current style, so: \startbuffer $ x__2 + x\nosuperprescript{2} + x\superprescript{2} $ \stopbuffer comes out as: \inlinebuffer. \stopnewprimitive \startnewprimitive[title={\prm {nosuperscript}}] This processes the given script in the current style, so: \startbuffer $ x__2 + x\nosuperprescript{2} + x\superprescript{2} $ \stopbuffer comes out as: \inlinebuffer. \stopnewprimitive \startnewprimitive[title={\prm {novrule}}] This is a rule but flagged as empty which means that the dimensions kick in as for a normal rule but the backend can decide not to show it. \stopnewprimitive \startoldprimitive[title={\prm {nulldelimiterspace}}] In fenced math delimiters can be invisible in which case this parameter determines the amount of space (width) that ghost delimiter takes. \stopoldprimitive \startoldprimitive[title={\prm {nullfont}}] This a symbolic reference to a font with no glyphs and a minimal set of font dimensions. \stopoldprimitive \startoldprimitive[title={\prm {number}}] This \TEX\ primitive serializes the next token into a number, assuming that it is indeed a number, like \starttyping \number`A \number65 \number\scratchcounter \stoptyping For counters and such the \prm {the} primitive does the same, but when you're not sure if what follows is a verbose number or (for instance) a counter the \prm {number} primitive is a safer bet, because \type {\the 65} will not work. \stopoldprimitive \startnewprimitive[title={\prm {numericscale}}] This primitive can best be explained by a few examples: \startbuffer \the\numericscale 1323 \the\numericscale 1323.0 \the\numericscale 1.323 \the\numericscale 13.23 \stopbuffer \typebuffer In several places \TEX\ uses a scale but due to the lack of floats it then uses 1000 as 1.0 replacement. This primitive can be used for \quote {real} scales: \startlines \getbuffer \stoplines \stopnewprimitive \startnewprimitive[title={\prm {numericscaled}}] This is a variant if \prm {numericscale}: \startbuffer \scratchcounter 1000 \the\numericscaled 1323 \scratchcounter \the\numericscaled 1323.0 \scratchcounter \the\numericscaled 1.323 \scratchcounter \the\numericscaled 13.23 \scratchcounter \stopbuffer \typebuffer The second number gets multiplied by the first fraction: \startlines \getbuffer \stoplines \stopnewprimitive \startoldprimitive[title={\prm {numexpr}}] This primitive was introduced by \ETEX\ and supports a simple expression syntax: \startbuffer \the\numexpr 10 * (1 + 2 - 5) / 2 \relax \stopbuffer \typebuffer gives: \inlinebuffer. You can mix in symbolic integers and dimensions. \stopoldprimitive \startnewprimitive[title={\prm {numexpression}}] The normal \prm {numexpr} primitive understands the \type {+}, \type {-}, \type {*} and \type {/} operators but in \LUAMETATEX\ we also can use \type {:} for a non rounded integer division (think of \LUA's \type {//}). if you want more than that, you can use the new expression primitive where you can use the following operators. \starttabulate[||cT|cT|] \BC add \NC + \NC \NC \NR \BC subtract \NC - \NC \NC \NR \BC multiply \NC * \NC \NC \NR \BC divide \NC / : \NC \NC \NR \BC mod \NC \letterpercent \NC mod \NC \NR \BC band \NC & \NC band \NC \NR \BC bxor \NC ^ \NC bxor \NC \NR \BC bor \NC \letterbar \space v \NC bor \NC \NR \BC and \NC && \NC and \NC \NR \BC or \NC \letterbar\letterbar \NC or \NC \NR \BC setbit \NC \NC bset \NC \NR \BC resetbit \NC \NC breset \NC \NR \BC left \NC << \NC \NC \NR \BC right \NC >> \NC \NC \NR \BC less \NC < \NC \NC \NR \BC lessequal \NC <= \NC \NC \NR \BC equal \NC = == \NC \NC \NR \BC moreequal \NC >= \NC \NC \NR \BC more \NC > \NC \NC \NR \BC unequal \NC <> != \lettertilde = \NC \NC \NR \BC not \NC ! \lettertilde \NC not \NC \NR \stoptabulate An example of the verbose bitwise operators is: \starttyping \scratchcounter = \numexpression "00000 bor "00001 bor "00020 bor "00400 bor "08000 bor "F0000 \relax \stoptyping In the table you might have notices that some operators have equivalents. This makes the scanner a bit less sensitive for catcode regimes. When \prm {tracingexpressions} is set to one or higher the intermediate \quote {reverse polish notation} stack that is used for the calculation is shown, for instance: \starttyping 4:8: {numexpression rpn: 2 5 > 4 5 > and} \stoptyping When you want the output on your console, you need to say: \starttyping \tracingexpressions 1 \tracingonline 1 \stoptyping \stopnewprimitive \startoldprimitive[title={\prm {omit}}] This primitive cancels the template set for the upcoming cell. Often it is used in combination with \prm {span}. \stopoldprimitive \startnewprimitive[title={\prm {optionalboundary}}] This boundary is used to mark optional content. An positive \prm {optionalboundary} starts a range and a zero one ends it. Nesting is not supported. Optional content is considered when an additional paragraph pass enables it as part of its recipe. \stopnewprimitive \startoldprimitive[title={\prm {or}}] This traditional primitive is part of the condition testing mechanism and relates to an \prm {ifcase} test (or a similar test to be introduced in later sections). Depending on the value, \TEX\ will do a fast scanning till the right \prm {or} is seen, then it will continue expanding till it sees a \prm {or} or \prm {else} or \prm {orelse} (to be discussed later). It will then do a fast skipping pass till it sees an \prm {fi}. \stopoldprimitive \startnewprimitive[title={\prm {orelse}}] This primitive provides a convenient way to flatten your conditional tests. So instead of \starttyping \ifnum\scratchcounter<-10 too small \else\ifnum\scratchcounter>10 too large \else just right \fi\fi \stoptyping You can say this: \starttyping \ifnum\scratchcounter<-10 too small \orelse\ifnum\scratchcounter>10 too large \else just right \fi \stoptyping You can mix tests and even the case variants will work in most cases \footnote {I just play safe because there are corner cases that might not work yet.} \starttyping \ifcase\scratchcounter zero \or one \or two \orelse\ifnum\scratchcounter<10 less than ten \else ten or more \fi \stoptyping Performance wise there are no real benefits although in principle there is a bit less housekeeping involved than with nested checks. However you might like this: \starttyping \ifnum\scratchcounter<-10 \expandafter\toosmall \orelse\ifnum\scratchcounter>10 \expandafter\toolarge \else \expandafter\justright \fi \stoptyping over: \starttyping \ifnum\scratchcounter<-10 \expandafter\toosmall \else\ifnum\scratchcounter>10 \expandafter\expandafter\expandafter\toolarge \else \expandafter\expandafter\expandafter\justright \fi\fi \stoptyping or the more \CONTEXT\ specific: \starttyping \ifnum\scratchcounter<-10 \expandafter\toosmall \else\ifnum\scratchcounter>10 \doubleexpandafter\toolarge \else \doubleexpandafter\justright \fi\fi \stoptyping But then, some \TEX ies like complex and obscure code and throwing away working old code that took ages to perfect and get working and also showed that one masters \TEX\ might hurt. \stopnewprimitive \startnewprimitive[title={\prm {orphanpenalties}}] This an (single entry) array parameter: first the size is given followed by that amount of penalties. These penalties are injected before spaces, going backward from the end of a paragraph. When we see a math node with a penalty set then we take the max and jump over a (preceding) skip. \stopnewprimitive \startnewprimitive[title={\prm {orphanpenalty}}] This penalty is inserted before the last space in a paragraph, unless \prm {orphanpenalties} mandates otherwise. \stopnewprimitive \startnewprimitive[title={\prm {orunless}}] This is the negated variant of \prm {orelse} (prefixing that one with \tex {unless} doesn't work well. \stopnewprimitive \startoldprimitive[title={\prm {outer}}][obsolete=yes] An outer macro is one that can only be used at the outer level. This property is no longer supported. Like \prm {long}, the \prm {outer} prefix is now an no|-|op (and we don't expect this to have unfortunate side effects). \stopoldprimitive \startoldprimitive[title={\prm {output}}] This token list register holds the code that will be expanded when \TEX\ enters the output routine. That code is supposed to do something with the content in the box with number \prm {outputbox}. By default this is box 255 but that can be changed with \prm {outputbox}. \stopoldprimitive \startnewprimitive[title={\prm {outputbox}}] This is where the split off page contend ends up when the output routine is triggered. \stopnewprimitive \startoldprimitive[title={\prm {outputpenalty}}] This is the penalty that triggered the output routine. \stopoldprimitive \startoldprimitive[title={\prm {over}}][obsolete=yes] This math primitive is actually a bit of a spoiler for the parser as it is one of the few that looks back. The \prm {Uover} variant is different and takes two arguments. We leave it to the user to predicts the results of: \starttyping $ {1} \over {x} $ $ 1 \over x $ $ 12 \over x / y $ $ a + 1 \over {x} $ \stoptyping and: \starttyping $ \textstyle 1 \over x $ $ {\textstyle 1} \over x $ $ \textstyle {1 \over x} $ \stoptyping It's one of the reasons why macro packages provide \type {\frac}. \stopoldprimitive \startoldprimitive[title={\prm {overfullrule}}] When an overfull box is encountered a rule can be shown in the margin and this parameter sets its width. For the record: \CONTEXT\ does it different. \stopoldprimitive \startoldprimitive[title={\prm {overline}}] This is a math specific primitive that draws a line over the given content. It is a poor mans replacement for a delimiter. The thickness is set with \prm {Umathoverbarrule}, the distance between content and rule is set by \prm {Umathoverbarvgap} and \prm {Umathoverbarkern} is added above the rule. The style used for the content under the rule can be set with \prm {Umathoverlinevariant}. Because \CONTEXT\ set up math in a special way, the following example: \startbuffer[demo] \normaloverline { \blackrule[color=red, height=1ex,depth=0ex,width=2cm]% \kern-2cm \blackrule[color=blue,height=0ex,depth=.5ex,width=2cm] x + x } \stopbuffer \typebuffer[demo] gives: \ruledhbox {$\getbuffer[demo]$}, while: \startbuffer[setup] \mathfontcontrol\zerocount \Umathoverbarkern\allmathstyles10pt \Umathoverbarvgap\allmathstyles5pt \Umathoverbarrule\allmathstyles2.5pt \Umathoverlinevariant\textstyle\scriptstyle \stopbuffer \typebuffer[setup] gives this: \ruledhbox {$\getbuffer[setup,demo]$}. We have to disable the related \prm {mathfontcontrol} bits because otherwise the thickness is taken from the font. The variant is just there to overload the (in traditional \TEX\ engines) default. \stopoldprimitive \startnewprimitive[title={\prm {overloaded}}] This prefix can be used to overload a frozen macro. \stopnewprimitive \startnewprimitive[title={\prm {overloadmode}}] The overload protection mechanism can be used to prevent users from redefining a control sequence. The mode can have several values, the higher the more strict we are: \starttabulate[||||||||] \NC \NC \NC immutable \NC permanent \NC primitive \NC frozen \NC instance \NC \NR \NC 1 \NC warning \NC + \NC + \NC + \NC \NC \NC \NR \NC 2 \NC error \NC + \NC + \NC + \NC \NC \NC \NR \NC 3 \NC warning \NC + \NC + \NC + \NC + \NC \NC \NR \NC 4 \NC error \NC + \NC + \NC + \NC + \NC \NC \NR \NC 5 \NC warning \NC + \NC + \NC + \NC + \NC + \NC \NR \NC 6 \NC error \NC + \NC + \NC + \NC + \NC + \NC \NR \stoptabulate When you set a high error value, you can of course temporary lower or even zero the mode. In \CONTEXT\ all macros and quantities are tagged so there setting the mode to~6 gives a proper protection against overloading. We need to zero the mode when we load for instance tikz, so when you use that generic package, you loose some. \stopnewprimitive \startnewprimitive[title={\prm {overshoot}}] This primitive is a companion to \prm {badness} and reports how much a box overflows. \startbuffer \setbox0\hbox to 1em {mmm} \the\badness\quad\the\overshoot \setbox0\hbox {mm} \the\badness\quad\the\overshoot \setbox0\hbox to 3em {m} \the\badness\quad\the\overshoot \stopbuffer \typebuffer This reports: \startlines \getbuffer \stoplines When traditional \TEX\ wraps up the lines in a paragraph it uses a mix of shift (a box property) to position the content suiting the hanging indentation and|/|or paragraph shape, and fills up the line using right skip glue, also in order to silence complaints in packaging. In \LUAMETATEX\ the lines can be normalized so that they all have all possible skips to the left and right (even if they're zero). The \prm {overshoot} primitive fits into this picture and is present as a compensation glue. This all fits better in a situation where the internals are opened up via \LUA. \stopnewprimitive \startoldprimitive[title={\prm {overwithdelims}}][obsolete=yes] This is a variant of \prm {over} but with delimiters. It has a more advanced upgrade in \prm {Uoverwithdelims}. \stopoldprimitive \startnewprimitive[title={\prm {pageboundary}}] In order to avoid side effects of triggering the page builder with a specific penalty we can use this primitive which expects a value that actually gets inserted as zero penalty before triggering the page builder callback. Think of adding a no|-|op to the contribution list. We fake a zero penalty so that all gets processed. The main rationale is that we get a better indication of what we do. Of course a callback can remove this node so that it is never seen. Triggering from the callback is not doable. Consider this experimental code (which is actually used in \CONTEXT\ anyway). \stopnewprimitive \startnewprimitive[title={\prm {pagedepth}}] This page property holds the depth of the page. \stopnewprimitive \startoldprimitive[title={\prm {pagediscards}}] The left|-|overs after a page is split of the main vertical list when glue and penalties are normally discarded. The discards can be pushed back in (for instance) trial runs. \stopoldprimitive \startnewprimitive[title={\prm {pageexcess}}] This page property hold the amount of overflow when a page break occurs. \stopnewprimitive \startnewprimitive[title={\prm {pageextragoal}}] This (experimental) dimension will be used when the page overflows but a bit of overshoot is considered okay. \stopnewprimitive \startoldprimitive[title={\prm {pagefilllstretch}}] The accumulated amount of third order stretch on the current page. \stopoldprimitive \startoldprimitive[title={\prm {pagefillstretch}}] The accumulated amount of second order stretch on the current page. \stopoldprimitive \startoldprimitive[title={\prm {pagefilstretch}}] The accumulated amount of first order stretch on the current page. \stopoldprimitive \startnewprimitive[title={\prm {pagefistretch}}] The accumulated amount of zero order stretch on the current page. \stopnewprimitive \startoldprimitive[title={\prm {pagegoal}}] The target height of a page (the running text). This value will be decreased by the height of inserts something to keep into mind when messing around with this and other (pseudo) page related parameters like \prm {pagetotal}. \stopoldprimitive \startnewprimitive[title={\prm {pagelastdepth}}] The accumulated depth of the current page. \stopnewprimitive \startnewprimitive[title={\prm {pagelastfilllstretch}}] The accumulated amount of third order stretch on the current page. Contrary to \prm {pagefilllstretch} this is the really contributed amount, not the upcoming. \stopnewprimitive \startnewprimitive[title={\prm {pagelastfillstretch}}] The accumulated amount of second order stretch on the current page. Contrary to \prm {pagefillstretch} this is the really contributed amount, not the upcoming. \stopnewprimitive \startnewprimitive[title={\prm {pagelastfilstretch}}] The accumulated amount of first order stretch on the current page. Contrary to \prm {pagefilstretch} this is the really contributed amount, not the upcoming. \stopnewprimitive \startnewprimitive[title={\prm {pagelastfistretch}}] The accumulated amount of zero order stretch on the current page. Contrary to \prm {pagefistretch} this is the really contributed amount, not the upcoming. \stopnewprimitive \startnewprimitive[title={\prm {pagelastheight}}] The accumulated height of the current page. \stopnewprimitive \startnewprimitive[title={\prm {pagelastshrink}}] The accumulated amount of shrink on the current page. Contrary to \prm {pageshrink} this is the really contributed amount, not the upcoming. \stopnewprimitive \startnewprimitive[title={\prm {pagelaststretch}}] The accumulated amount of stretch on the current page. Contrary to \prm {pagestretch} this is the really contributed amount, not the upcoming. \stopnewprimitive \startoldprimitive[title={\prm {pageshrink}}] The accumulated amount of shrink on the current page. \stopoldprimitive \startoldprimitive[title={\prm {pagestretch}}] The accumulated amount of stretch on the current page. \stopoldprimitive \startoldprimitive[title={\prm {pagetotal}}] The accumulated page total (height) of the current page. \stopoldprimitive \startnewprimitive[title={\prm {pagevsize}}] This parameter, when set, is used as the target page height. This lessens the change of \prm {vsize} interfering. \stopnewprimitive \startoldprimitive[title={\prm {par}}] This is the explicit \quote {finish paragraph} command. Internally we distinguish a par triggered by a new line, as side effect of another primitive or this \prm {par} command. \stopoldprimitive \startnewprimitive[title={\prm {parametercount}}] The number of parameters passed to the current macro. \stopnewprimitive \startnewprimitive[title={\prm {parameterdef}}] Here is an example of binding a variable to a parameter. The alternative is of course to use an \prm {edef}. \startbuffer \def\foo#1#2% {\parameterdef\MyIndexOne\plusone % 1 \parameterdef\MyIndexTwo\plustwo % 2 \oof{P}\oof{Q}\oof{R}\norelax} \def\oof#1% {<1:\MyIndexOne><1:\MyIndexOne>% #1% <2:\MyIndexTwo><2:\MyIndexTwo>} \foo{A}{B} \stopbuffer \typebuffer The outcome is: \getbuffer \stopnewprimitive \startnewprimitive[title={\prm {parameterindex}}] This gives the zero based position on the parameter stack. One reason for introducing \prm {parameterdef} is that the position remains abstract so there we don't need to use \prm {parameterindex}. \stopnewprimitive \startnewprimitive[title={\prm {parametermark}}] This is an equivalent for \type {#}. \stopnewprimitive \startnewprimitive[title={\prm {parametermode}}] Setting this internal integer to a positive value (best use~1 because future versions might use bit set) will enable the usage of \type {#} for escaped in the main text and body of macros. \stopnewprimitive \startnewprimitive[title={\prm {parattribute}}] This primitive takes an attribute index and value and sets that attribute on the current paragraph. \stopnewprimitive \startnewprimitive[title={\prm {pardirection}}] This set the text direction for the whole paragraph which in the case of \type {r2l} (1) makes the right edge the starting point. \stopnewprimitive \startnewprimitive[title={\prm {parfillleftskip}}] The glue inserted at the start of the last line. \stopnewprimitive \startnewprimitive[title={\prm {parfillrightskip}}] The glue inserted at the end of the last line (aka \prm {parfillskip}). \stopnewprimitive \startoldprimitive[title={\prm {parfillskip}}] The glue inserted at the end of the last line. \stopoldprimitive \startoldprimitive[title={\prm {parindent}}] The amount of space inserted at the start of the first line. When bit \tobit \parindentskipnormalizecode\ is set in \prm {normalizelinemode} a glue is inserted, otherwise an empty \prm {hbox} with the given width is inserted. \stopoldprimitive \startnewprimitive[title={\prm {parinitleftskip}}] The glue inserted at the start of the first line. \stopnewprimitive \startnewprimitive[title={\prm {parinitrightskip}}] The glue inserted at the end of the first line. \stopnewprimitive \startnewprimitive[title={\prm {parpasses}}] Specifies one or more recipes for additional second linebreak passes. Examples can be found in the \CONTEXT\ distribution. \stopnewprimitive \startoldprimitive[title={\prm {parshape}}] Stores a shape specification. The first argument is the length of the list, followed by that amount of indentation|-|width pairs (two dimensions). \stopoldprimitive \startoldprimitive[title={\prm {parshapedimen}}] This oddly named (\ETEX) primitive returns the width component (dimension) of the given entry (an integer). Obsoleted by \prm {parshapewidth}. \stopoldprimitive \startoldprimitive[title={\prm {parshapeindent}}] Returns the indentation component (dimension) of the given entry (an integer). \stopoldprimitive \startoldprimitive[title={\prm {parshapelength}}] Returns the number of entries (an integer). \stopoldprimitive \startnewprimitive[title={\prm {parshapewidth}}] Returns the width component (dimension) of the given entry (an integer). \stopnewprimitive \startoldprimitive[title={\prm {parskip}}] This is the amount of glue inserted before a new paragraph starts. \stopoldprimitive \startoldprimitive[title={\prm {patterns}}] The argument to this primitive contains hyphenation patterns that are bound to the current language. In \LUATEX\ and \LUAMETATEX\ we can also manage this at the \LUA\ end. In \LUAMETATEX\ we don't store patterns in te format file \stopoldprimitive \startoldprimitive[title={\prm {pausing}}][obsolete=yes] In \LUAMETATEX\ this variable is ignored but in other engines it can be used to single step thought the input file by setting it to a positive value. \stopoldprimitive \startoldprimitive[title={\prm {penalty}}] The given penalty (a number) is inserted at the current spot in the horizontal or vertical list. We also have \prm {vpenalty} and \prm {hpenalty} that first change modes. \stopoldprimitive \startnewprimitive[title={\prm {permanent}}] This is one of the prefixes that is part of the overload protection mechanism. It is normally used to flag a macro as being at the same level as a primitive: don't touch it. primitives are flagged as such but that property cannot be set on regular macros. The similar \prm {immutable} flag is normally used for variables. \stopnewprimitive \startnewprimitive[title={\prm {pettymuskip}}] A predefined mu skip register that can be used in math (inter atom) spacing. The current value is {\tt \the\pettymuskip}. This one complements \prm {thinmuskip}, \prm {medmuskip}, \prm {thickmuskip} and the new \prm {tinymuskip}. \stopnewprimitive \startnewprimitive[title={\prm {positdef}}] The engine uses 32 bit integers for various purposes and has no (real) concept of a floating point quantity. We get around this by providing a floating point data type based on 32 bit unums (posits). These have the advantage over native floats of more precision in the lower ranges but at the cost of a software implementation. The \prm {positdef} primitive is the floating point variant of \prm {integerdef} and \prm {dimensiondef}: an efficient way to implement named quantities other than registers. \startbuffer \positdef \MyFloatA 5.678 \positdef \MyFloatB 567.8 [\the\MyFloatA] [\todimension\MyFloatA] [\tointeger\MyFloatA] [\the\MyFloatB] [\todimension\MyFloatB] [\tointeger\MyFloatB] \stopbuffer \typebuffer For practical reasons we can map posit (or float) onto an integer or dimension: \startlines \getbuffer \stoplines % {\em I might eventually decide to go for 32 bit floats but it all depends on how % unums evolve cq. become native to \CCODE.} \stopnewprimitive \startoldprimitive[title={\prm {postdisplaypenalty}}] This is the penalty injected after a display formula. \stopoldprimitive \startnewprimitive[title={\prm {postexhyphenchar}}] This primitive expects a language number and a character code. A negative character code is equivalent to ignore. In case of an explicit discretionary the character is injected at the beginning of a new line. \stopnewprimitive \startnewprimitive[title={\prm {posthyphenchar}}] This primitive expects a language number and a character code. A negative character code is equivalent to ignore. In case of an automatic discretionary the character is injected at the beginning of a new line. \stopnewprimitive \startnewprimitive[title={\prm {postinlinepenalty}}] When set this penalty is inserted after an inline formula unless we have a short formula and \prm {postshortinlinepenalty} is set. \stopnewprimitive \startnewprimitive[title={\prm {postshortinlinepenalty}}] When set this penalty is inserted after a short inline formula. The criterium is set by \prm {shortinlinemaththreshold} but only applied when it is enabled for the class involved. \stopnewprimitive \startnewprimitive[title={\prm {prebinoppenalty}}] This internal quantity is a compatibility feature because normally we will use the inter atom spacing variables. \stopnewprimitive \startoldprimitive[title={\prm {predisplaydirection}}] This is the direction that the math sub engine will take into account when dealing with right to left typesetting. \stopoldprimitive \startnewprimitive[title={\prm {predisplaygapfactor}}] The heuristics related to determine if the previous line in a formula overlaps with a (display) formula are hard coded but in \LUATEX\ to be two times the quad of the current font. This parameter is a multiplier set to 2000 and permits you to change the overshoot in this heuristic. \stopnewprimitive \startoldprimitive[title={\prm {predisplaypenalty}}] This is the penalty injected before a display formula. \stopoldprimitive \startoldprimitive[title={\prm {predisplaysize}}] This parameter holds the length of the last line in a paragraph when a display formula is part of it. \stopoldprimitive \startnewprimitive[title={\prm {preexhyphenchar}}] This primitive expects a language number and a character code. A negative character code is equivalent to ignore. In case of an explicit discretionary the character is injected at the end of the line. \stopnewprimitive \startnewprimitive[title={\prm {prehyphenchar}}] This primitive expects a language number and a character code. A negative character code is equivalent to ignore. In case of an automatic discretionary the character is injected at the end of the line. \stopnewprimitive \startnewprimitive[title={\prm {preinlinepenalty}}] When set this penalty is inserted before an inline formula unless we have a short formula and \prm {preshortinlinepenalty} is set. \stopnewprimitive \startnewprimitive[title={\prm {prerelpenalty}}] This internal quantity is a compatibility feature because normally we will use the inter atom spacing variables. \stopnewprimitive \startnewprimitive[title={\prm {preshortinlinepenalty}}] When set this penalty is inserted before a short inline formula. The criterium is set by \prm {shortinlinemaththreshold} but only applied when it is enabled for the class involved. \stopnewprimitive \startoldprimitive[title={\prm {pretolerance}}] When the badness of a line in a paragraph exceeds this value a second linebreak pass will be enabled. \stopoldprimitive \startoldprimitive[title={\prm {prevdepth}}] The depth of current list. It can also be set to special (signal) values in order to inhibit line corrections. It is not an internal dimension but a (current) list property. \stopoldprimitive \startoldprimitive[title={\prm {prevgraf}}] The number of lines in a previous paragraph. \stopoldprimitive \startnewprimitive[title={\prm {previousloopiterator}}] \startbuffer \edef\testA{ \expandedrepeat 2 {% \expandedrepeat 3 {% (\the\previousloopiterator1:\the\currentloopiterator) }% }% } \edef\testB{ \expandedrepeat 2 {% \expandedrepeat 3 {% (#P:#I) % #G is two levels up }% }% } \stopbuffer \typebuffer \getbuffer These give the same result: \startlines \tt \meaningasis\testA \meaningasis\testB \stoplines The number indicates the number of levels we go up the loop chain. \stopnewprimitive \startnewprimitive[title={\prm {primescript}}] This is a math script primitive dedicated to primes (which are somewhat troublesome on math). It complements the six script primitives (like \prm {subscript} and \prm {presuperscript}). \stopnewprimitive \startoldprimitive[title={\prm {protected}}] A protected macro is one that doesn't get expanded unless it is time to do so. For instance, inside an \prm {edef} it just stays what it is. It often makes sense to pass macros as|-|is to (multi|-|pass) file (for tables of contents). In \CONTEXT\ we use either \prm {protected} or \prm {unexpanded} because the later was the command we used to achieve the same results before \ETEX\ introduced this protection primitive. Originally the \prm {protected} macro was also defined but it has been dropped. \stopoldprimitive \startnewprimitive[title={\prm {protecteddetokenize}}] This is a variant of \prm {protecteddetokenize} that uses some escapes encoded as body parameters, like \type {#H} for a hash. \stopnewprimitive \startnewprimitive[title={\prm {protectedexpandeddetokenize}}] This is a variant of \prm {expandeddetokenize} that uses some escapes encoded as body parameters, like \type {#H} for a hash. \stopnewprimitive \startnewprimitive[title={\prm {protrudechars}}] This variable controls protrusion (into the margin). A value~2 is comparable with other engines, while a value of~3 does a bit more checking when we're doing right|-|to|-|left typesetting. \stopnewprimitive \startnewprimitive[title={\prm {protrusionboundary}}] This injects a boundary with the given value: \getbuffer[engine:syntax:protrusionboundarycodes] This signal makes the protrusion checker skip over a node. \stopnewprimitive \startnewprimitive[title={\prm {pxdimen}}] The current numeric value of this dimension is \tointeger \pxdimen, \todimension \pxdimen: one \type {bp}. We kept it around because it was introduced in \PDFTEX\ and made it into \LUATEX, where it relates to the resolution of included images. In \CONTEXT\ it is not used. \stopnewprimitive \startnewprimitive[title={\prm {quitloop}}] There are several loop primitives and they can be quit with \prm {quitloop} at the next the {\em next} iteration. An immediate quit is possible with \prm {quitloopnow}. An example is given with \prm {localcontrolledloop}. \stopnewprimitive \startnewprimitive[title={\prm {quitloopnow}}] There are several loop primitives and they can be quit with \prm {quitloopnow} at the spot. \stopnewprimitive \startnewprimitive[title={\prm {quitvmode}}] This primitive forces horizontal mode but has no side effects when we're already in that mode. \stopnewprimitive \startoldprimitive[title={\prm {radical}}][obsolete=yes] This old school radical constructor is replaced by \prm {Uradical}. It takes a number where the first byte is the small family, the next two index of this symbol from that family, and the next three the family and index of the first larger variant. \stopoldprimitive \startoldprimitive[title={\prm {raise}}] This primitive takes two arguments, a dimension and a box. The box is moved up. The operation only succeeds in horizontal mode. \stopoldprimitive \startnewprimitive[title={\prm {rdivide}}] This is variant of \prm {divide} that rounds the result. For integers the result is the same as \prm {edivide}. \startbuffer \the\dimexpr .4999pt : 2 \relax =.24994pt \the\dimexpr .4999pt / 2 \relax =.24995pt \scratchdimen.4999pt \divide \scratchdimen 2 \the\scratchdimen =.24994pt \scratchdimen.4999pt \edivide\scratchdimen 2 \the\scratchdimen =.24995pt \scratchdimen 4999pt \rdivide\scratchdimen 2 \the\scratchdimen =2500.0pt \scratchdimen 5000pt \rdivide\scratchdimen 2 \the\scratchdimen =2500.0pt \the\numexpr 1001 : 2 \relax =500 \the\numexpr 1001 / 2 \relax =501 \scratchcounter1001 \divide \scratchcounter 2 \the\scratchcounter=500 \scratchcounter1001 \edivide\scratchcounter 2 \the\scratchcounter=501 \scratchcounter1001 \rdivide\scratchcounter 2 \the\scratchcounter=501 \stopbuffer \typebuffer \startlines \getbuffer \stoplines \stopnewprimitive \startnewprimitive[title={\prm {rdivideby}}] This is the \type {by}|-|less companion to \prm {rdivide}. \stopnewprimitive \startoldprimitive[title={\prm {relax}}] This primitive does nothing and is often used to end a verbose number or dimension in a comparison, for example: \starttyping \ifnum \scratchcounter = 123\relax \stoptyping which prevents a lookahead. A variant would be: \starttyping \ifnum \scratchcounter = 123 % \stoptyping assuming that spaces are not ignored. Another application is finishing an expression like \prm {numexpr} or \prm {dimexpr}. I is also used to prevent lookahead in cases like: \starttyping \vrule height 3pt depth 2pt width 5pt\relax \hskip 5pt plus 3pt minus 2pt\relax \stoptyping Because \prm {relax} is not expandable the following: \startbuffer \edef\foo{\relax} \meaningfull\foo \edef\oof{\norelax} \meaningfull\oof \stopbuffer \typebuffer gives this: \startlines \getbuffer \stoplines A \prm {norelax} disappears here but in the previously mentioned scenarios it has the same function as \prm {relax}. It will not be pushed back either in cases where a lookahead demands that. \stopoldprimitive \startoldprimitive[title={\prm {relpenalty}}] This internal quantity is a compatibility feature because normally we will use the inter atom spacing variables. \stopoldprimitive % \startnewprimitive[title={\prm {resetmathspacing}}] % \stopnewprimitive \startnewprimitive[title={\prm {retained}}] When a value is assigned inside a group \TEX\ pushes the current value on the save stack in order to be able to restore the original value after the group has ended. You can reach over a group by using the \prm {global} prefix. A mix between local and global assignments can be achieved with the \prm {retained} primitive. \newdimension\MyDim \startbuffer[one] \MyDim 15pt \bgroup \the\MyDim \space \bgroup \bgroup \bgroup \advance\MyDim10pt \the\MyDim \egroup\space \bgroup \advance\MyDim10pt \the\MyDim \egroup\space \egroup \bgroup \bgroup \advance\MyDim10pt \the\MyDim \egroup\space \bgroup \advance\MyDim10pt \the\MyDim \egroup\space \egroup \egroup \egroup \the\MyDim \stopbuffer \startbuffer[two] \MyDim 15pt \bgroup \the\MyDim \space \bgroup \bgroup \bgroup \global\advance\MyDim10pt \the\MyDim \egroup\space \bgroup \global\advance\MyDim10pt \the\MyDim \egroup\space \egroup \bgroup \bgroup \global\advance\MyDim10pt \the\MyDim \egroup\space \bgroup \global\advance\MyDim10pt \the\MyDim \egroup\space \egroup \egroup \egroup \the\MyDim \stopbuffer \startbuffer[three] \MyDim 15pt \bgroup \the\MyDim \space \constrained\MyDim\zeropoint \bgroup \bgroup \retained\advance\MyDim10pt \the\MyDim \egroup\space \bgroup \retained\advance\MyDim10pt \the\MyDim \egroup\space \egroup \bgroup \bgroup \retained\advance\MyDim10pt \the\MyDim \egroup\space \bgroup \retained\advance\MyDim10pt \the\MyDim \egroup\space \egroup \egroup \the\MyDim \stopbuffer \typebuffer[one,two,three] These lines result in: \startlines \hbox{\getbuffer[one]} \hbox{\getbuffer[two]} \hbox{\getbuffer[three]} \stoplines Because \LUAMETATEX\ avoids redundant stack entries and reassignments this mechanism is a bit fragile but the \prm {constrained} prefix makes sure that we do have a stack entry. If it is needed depends on the usage pattern. \stopnewprimitive \startnewprimitive[title={\prm {retokenized}}] This is a companion of \prm {tokenized} that accepts a catcode table, so the whole repertoire is: \startbuffer \tokenized {test $x$ test: current} \tokenized catcodetable \ctxcatcodes {test $x$ test: context} \tokenized catcodetable \vrbcatcodes {test $x$ test: verbatim} \retokenized \ctxcatcodes {test $x$ test: context} \retokenized \vrbcatcodes {test $x$ test: verbatim} \stopbuffer \typebuffer Here we pass the numbers known to \CONTEXT\ and get: \startlines \getbuffer \stoplines \stopnewprimitive \startoldprimitive[title={\prm {right}}] Inserts the given delimiter as right fence in a math formula. \stopoldprimitive \startoldprimitive[title={\prm {righthyphenmin}}] This is the minimum number of characters before the first hyphen in a hyphenated word. \stopoldprimitive \startnewprimitive[title={\prm {rightmarginkern}}] The dimension returned is the protrusion kern that has been added (if at all) to the left of the content in the given box. \stopnewprimitive \startoldprimitive[title={\prm {rightskip}}] This skip will be inserted at the right of every line. \stopoldprimitive \startoldprimitive[title={\prm {romannumeral}}] This converts a number into a sequence of characters representing a roman numeral. Because the Romans had no zero, a zero will give no output, a fact that is sometimes used for hacks and showing off ones macro coding capabilities. A large number will for sure result in a long string because after thousand we start duplicating. \stopoldprimitive \startnewprimitive[title={\prm {rpcode}}] This is the companion of \prm {lpcode} (see there) and also takes three arguments: font, character code and factor. \stopnewprimitive \startnewprimitive[title={\prm {savecatcodetable}}] This primitive stores the currently set catcodes in the current table. \stopnewprimitive \startoldprimitive[title={\prm {savinghyphcodes}}] When set to non|-|zero, this will trigger the setting of \prm {hjcode}s from \prm {lccode}s for the current font. These codes determine what characters are taken into account when hyphenating words. \stopoldprimitive \startoldprimitive[title={\prm {savingvdiscards}}] When set to a positive value the page builder will store the discarded items (like glues) so that they can later be retrieved and pushed back if needed with \prm {pagediscards} or \prm {splitdiscards}. \stopoldprimitive \startnewprimitive[title={\prm {scaledemwidth}}] Returns the current (font specific) emwidth scaled according to \prm {glyphscale} and \prm {glyphxscale}. \stopnewprimitive \startnewprimitive[title={\prm {scaledexheight}}] Returns the current (font specific) exheight scaled according to \prm {glyphscale} and \prm {glyphyscale}. \stopnewprimitive \startnewprimitive[title={\prm {scaledextraspace}}] Returns the current (font specific) extra space value scaled according to \prm {glyphscale} and \prm {glyphxscale}. \stopnewprimitive \startnewprimitive[title={\prm {scaledfontcharba}}] Returns the bottom accent position of the given font|-|character pair scaled according to \prm {glyphscale} and \prm {glyphyscale}. \stopnewprimitive \startnewprimitive[title={\prm {scaledfontchardp}}] Returns the depth of the given font|-|character pair scaled according to \prm {glyphscale} and \prm {glyphyscale}. \stopnewprimitive \startnewprimitive[title={\prm {scaledfontcharht}}] Returns the height of the given font|-|character pair scaled according to \prm {glyphscale} and \prm {glyphyscale}. \stopnewprimitive \startnewprimitive[title={\prm {scaledfontcharic}}] Returns the italic correction of the given font|-|character pair scaled according to \prm {glyphscale} and \prm {glyphxscale}. This property is only real for traditional fonts. \stopnewprimitive \startnewprimitive[title={\prm {scaledfontcharta}}] Returns the top accent position of the given font|-|character pair scaled according to \prm {glyphscale} and \prm {glyphxscale}. \stopnewprimitive \startnewprimitive[title={\prm {scaledfontcharwd}}] Returns width of the given font|-|character pair scaled according to \prm {glyphscale} and \prm {glyphxscale}. \stopnewprimitive \startnewprimitive[title={\prm {scaledfontdimen}}] Returns value of a (numeric) font dimension of the given font|-|character pair scaled according to \prm {glyphscale} and \prm {glyphxscale} and|/|or \prm {glyphyscale}. \stopnewprimitive \startnewprimitive[title={\prm {scaledinterwordshrink}}] Returns the current (font specific) shrink of a space value scaled according to \prm {glyphscale} and \prm {glyphxscale}. \stopnewprimitive \startnewprimitive[title={\prm {scaledinterwordspace}}] Returns the current (font specific) space value scaled according to \prm {glyphscale} and \prm {glyphxscale}. \stopnewprimitive \startnewprimitive[title={\prm {scaledinterwordstretch}}] Returns the current (font specific) stretch of a space value scaled according to \prm {glyphscale} and \prm {glyphxscale}. \stopnewprimitive \startnewprimitive[title={\prm {scaledmathaxis}}] This primitive returns the math axis of the given math style. It's a dimension. \stopnewprimitive \startnewprimitive[title={\prm {scaledmathemwidth}}] Returns the emwidth of the given style scaled according to \prm {glyphscale} and \prm {glyphxscale}. \stopnewprimitive \startnewprimitive[title={\prm {scaledmathexheight}}] Returns the exheight of the given style scaled according to \prm {glyphscale} and \prm {glyphyscale}. \stopnewprimitive \startnewprimitive[title={\prm {scaledmathstyle}}] This command inserts a signal in the math list that tells how to scale the (upcoming) part of the formula. \startbuffer $ x + {\scaledmathstyle900 x} + x$ \stopbuffer \typebuffer We get: \inlinebuffer. Of course using this properly demands integration in the macro packages font system. \stopnewprimitive \startnewprimitive[title={\prm {scaledslantperpoint}}] This primitive is equivalent to \typ {\scaledfontdimen1\font} where \quote {scaled} means that we multiply by the glyph scales. \stopnewprimitive \startnewprimitive[title={\prm {scantextokens}}] This primitive scans the input as if it comes from a file. In the next examples the \prm {detokenize} primitive turns tokenized code into verbatim code that is similar to what is read from a file. \startbuffer \edef\whatever{\detokenize{This is {\bf bold} and this is not.}} \detokenize {This is {\bf bold} and this is not.}\crlf \scantextokens{This is {\bf bold} and this is not.}\crlf \scantextokens{\whatever}\crlf \scantextokens\expandafter{\whatever}\par \stopbuffer \typebuffer This primitive does not have the end|-|of|-|file side effects of its precursor \prm {scantokens}. {\getbuffer} \stopnewprimitive \startoldprimitive[title={\prm {scantokens}}] Just forget about this \ETEX\ primitive, just take the one in the next section. \stopoldprimitive \startoldprimitive[title={\prm {scriptfont}}] This primitive is like \prm {font} but with a family number as (first) argument so it is specific for math. It is the middle one of the three family members; its relatives are \prm {textfont} and \prm {scriptscriptfont}. \stopoldprimitive \startoldprimitive[title={\prm {scriptscriptfont}}] This primitive is like \prm {font} but with a family number as (first) argument so it is specific for math. It is the smallest of the three family members; its relatives are \prm {textfont} and \prm {scriptfont}. \stopoldprimitive \startoldprimitive[title={\prm {scriptscriptstyle}}] One of the main math styles, normally one size smaller than \prm {scriptstyle}: integer representation: \the\scriptscriptstyle. \stopoldprimitive \startoldprimitive[title={\prm {scriptspace}}] The math engine will add this amount of space after subscripts and superscripts. It can be seen as compensation for the often too small widths of characters (in the traditional engine italic correction is used too). It prevents scripts from running into what follows. \stopoldprimitive \startoldprimitive[title={\prm {scriptstyle}}] One of the main math styles, normally one size smaller than \prm {displaystyle} and \prm {textstyle}; integer representation: \the\scriptstyle. \stopoldprimitive \startoldprimitive[title={\prm {scrollmode}}] This directive omits error stops. \stopoldprimitive \startnewprimitive[title={\prm {semiexpand}}] This command expands the next macro when it is protected with \prm {semprotected}. See that primitive there for an example. \stopnewprimitive \startnewprimitive[title={\prm {semiexpanded}}] This command expands the tokens in the given list including the macros protected by with \prm {semprotected}. See that primitive there for an example. \stopnewprimitive \startnewprimitive[title={\prm {semiprotected}}] \startbuffer \def\TestA{A} \semiprotected\def\TestB{B} \protected\def\TestC{C} \edef\TestD{\TestA \TestB \TestC} \edef\TestE{\TestA\semiexpand\TestB\semiexpand\TestC} \edef\TestF{\TestA\expand \TestB\expand \TestC} \edef\TestG{\normalexpanded {\TestA\TestB\TestC}} \edef\TestH{\normalsemiexpanded{\TestA\TestB\TestC}} \stopbuffer The working of this prefix can best be explained with an example. We define a few macros first: \typebuffer \getbuffer The meaning of the macros that are made from the other three are: \startbuffer \meaningless\TestD \meaningless\TestE \meaningless\TestF \meaningless\TestG \meaningless\TestH \stopbuffer Here we use the \type {\normal..} variants because (currently) we still have the macro with the \type {\expanded} in the \CONTEXT\ core. \startlines \tttf \getbuffer \stoplines \stopnewprimitive \startoldprimitive[title={\prm {setbox}}] This important primitive is used to set a box register. It expects a number and a box, like \prm {hbox} or \prm {box}. There is no \type {\boxdef} primitive (analogue to other registers) because it makes no sense but numeric registers or equivalents are okay as register value. \stopoldprimitive % \startnewprimitive[title={\prm {setdefaultmathcodes}}] % \stopnewprimitive \startnewprimitive[title={\prm {setfontid}}] Internally a font instance has a number and this number is what gets assigned to a glyph node. You can get the number with \prm {fontid} an set it with \prm {setfontid}. \starttyping \setfontid\fontid\font \stoptyping The code above shows both primitives and effectively does nothing useful but shows the idea. \stopnewprimitive \startoldprimitive[title={\prm {setlanguage}}] In \LUATEX\ and \LUAMETATEX\ this is equivalent to \prm {language} because we carry the language in glyph nodes instead of putting triggers in the list. \stopoldprimitive \startnewprimitive[title={\prm {setmathatomrule}}] The math engine has some built in logic with respect to neighboring atoms that change the class. The following combinations are intercepted and remapped: \starttabulate[|c|c|c|c|] \BC old first \BC old second \NC new first \NC new second \NC \NR \ML \NC begin \NC binary \NC ordinary \NC ordinary \NC \NR \NC \NC \NC \NC \NC \NR \NC operator \NC binary \NC operator \NC ordinary \NC \NR \NC open \NC binary \NC open \NC ordinary \NC \NR \NC punctuation \NC binary \NC punctuation \NC ordinary \NC \NR \NC \NC \NC \NC \NC \NR \NC binary \NC end \NC ordinary \NC ordinary \NC \NR \NC binary \NC binary \NC binary \NC ordinary \NC \NR \NC binary \NC close \NC ordinary \NC close \NC \NR \NC binary \NC punctuation \NC ordinary \NC punctuation \NC \NR \NC binary \NC relation \NC ordinary \NC relation \NC \NR \NC \NC \NC \NC \NC \NR \NC relation \NC binary \NC relation \NC ordinary \NC \NR \NC relation \NC close \NC ordinary \NC close \NC \NR \NC relation \NC punctuation \NC ordinary \NC punctuation \NC \NR \stoptabulate You can change this logic if needed, for instance: \starttyping \setmathatomrule 1 2 \allmathstyles 1 1 \stoptyping Keep in mind that the defaults are what users expect. You might set them up for additional classes that you define but even then you probably clone an existing class and patch its properties. Most extra classes behave like ordinary anyway. \stopnewprimitive \startnewprimitive[title={\prm {setmathdisplaypostpenalty}}] This penalty is inserted after an item of a given class but only in inline math when display style is used, for instance: \starttyping \setmathdisplayprepenalty 2 750 \stoptyping \stopnewprimitive \startnewprimitive[title={\prm {setmathdisplayprepenalty}}] This penalty is inserted before an item of a given class but only in inline math when display style is used, for instance: \starttyping \setmathdisplayprepenalty 2 750 \stoptyping \stopnewprimitive \startnewprimitive[title={\prm {setmathignore}}] You can flag a math parameter to be ignored, like: \starttyping \setmathignore \Umathxscale 2 \setmathignore \Umathyscale 2 \setmathignore \Umathspacebeforescript 1 \setmathignore \Umathspaceafterscript 1 \stoptyping A value of two will not initialize the variable, so its old value (when set) is kept. This is somewhat experimental and more options might show up. \stopnewprimitive \startnewprimitive[title={\prm {setmathoptions}}] This primitive expects a class (number) and a bitset. \testpage[2] \startcolumns \getbuffer[engine:syntax:mathcontrol] % weird: one liner at endof page \stopcolumns \stopnewprimitive \startnewprimitive[title={\prm {setmathpostpenalty}}] This penalty is inserted after an item of a given class but only in inline math when text, script or scriptscript style is used, for instance: \starttyping \setmathpostpenalty 2 250 \stoptyping \stopnewprimitive \startnewprimitive[title={\prm {setmathprepenalty}}] This penalty is inserted before an item of a given class but only in inline math when text, script or scriptscript style is used, for instance: \starttyping \setmathprepenalty 2 250 \stoptyping \stopnewprimitive % \startnewprimitive[title={\prm {setmathspacing}}] % \stopnewprimitive \startoldprimitive[title={\prm {sfcode}}] You can set a space factor on a character. That factor is used when a space factor is applied (as part of spacing). It is (mostly) used for adding a different space (glue) after punctuation. In some languages different punctuation has different factors. \stopoldprimitive \startnewprimitive[title={\prm {shapingpenaltiesmode}}] Shaping penalties are inserted after the lines of a \prm {parshape} and accumulate according to this mode, a bitset of: \getbuffer[engine:syntax:shapingpenaltiescodes] \stopnewprimitive \startnewprimitive[title={\prm {shapingpenalty}}] In order to prevent a \prm {parshape} to break in unexpected ways we can add a dedicated penalty, specified by this parameter. \stopnewprimitive \startnewprimitive[title={\prm {shiftedsubprescript}}] This primitive (or \type {____}) influences the alignment of scripts: \startbuffer $ x \shiftedsuperprescript{2} \subprescript {2} + x \superprescript {2} \shiftedsubprescript{2} + x \superprescript {2} ____ {2} = x \superprescript {2} \subprescript {2} $ \stopbuffer \typebuffer Gives: \inlinebuffer. \stopnewprimitive \startnewprimitive[title={\prm {shiftedsubscript}}] This primitive (or \type {___}) influences the alignment of scripts: \startbuffer $ x \shiftedsuperscript{2} \subscript {2} + x \superscript {2} \shiftedsubscript{2} + x \superscript {2} ___ {2} = x \superscript {2} \subscript {2} $ \stopbuffer \typebuffer Gives: \inlinebuffer. \stopnewprimitive \startnewprimitive[title={\prm {shiftedsuperprescript}}] This primitive (or \type {^^^^}) influences the alignment of scripts: \startbuffer $ x \shiftedsuperprescript{2} \subprescript {2} + x ^^^^ {2} \subprescript {2} + x \superprescript {2} \shiftedsubprescript{2} = x \superprescript {2} \subprescript {2} $ \stopbuffer \typebuffer Gives: \inlinebuffer. \stopnewprimitive \startnewprimitive[title={\prm {shiftedsuperscript}}] This primitive (or \type {^^^}) influences the alignment of scripts: \startbuffer $ x \shiftedsuperscript{2} \subscript {2} + x ^^^ {2} \subscript {2} + x \superscript {2} \shiftedsubscript{2} = x \superscript {2} \subscript {2} $ \stopbuffer \typebuffer Gives: \inlinebuffer. \stopnewprimitive \startoldprimitive[title={\prm {shipout}}][obsolete=yes] Because there is no backend, this is not supposed to be used. As in traditional \TEX\ a box is grabbed but instead of it being processed it gets shown and then wiped. There is no real benefit of turning it into a callback. \stopoldprimitive \startnewprimitive[title={\prm {shortinlinemaththreshold}}] This parameter determines when an inline formula is considered to be short. This criterium is used for for \prm {preshortinlinepenalty} and \prm {postshortinlinepenalty}. \stopnewprimitive \startnewprimitive[title={\prm {shortinlineorphanpenalty}}] Short formulas at the end of a line are normally not followed by something other than punctuation. This penalty will discourage a break before a short inline formula. In practice one can set this penalty to e.g. a relatively low 200 to get the desired effect. \stopnewprimitive \startoldprimitive[title={\prm {show}}] Prints to the console (and/or log) what the token after it represents. \stopoldprimitive \startoldprimitive[title={\prm {showbox}}] The given box register is shown in the log and on te console (depending on \prm {tracingonline}. How much is shown depends on \prm {showboxdepth} and \prm {showboxbreadth}. In \LUAMETATEX\ we show more detailed information than in the other engines; some specific information is provided via callbacks. \stopoldprimitive \startoldprimitive[title={\prm {showboxbreadth}}] This primitives determine how much of a box is shown when asked for or when tracing demands it. \stopoldprimitive \startoldprimitive[title={\prm {showboxdepth}}] This primitives determine how deep tracing a box goes into the box. Some boxes, like the ones that has the assembled page. \stopoldprimitive \startoldprimitive[title={\prm {showgroups}}] This primitive reports the group nesting. At this spot we have a not so impressive nesting: \starttyping 2:3: simple group entered at line 9375: 1:3: semisimple group: \begingroup 0:3: bottomlevel \stoptyping \stopoldprimitive \startoldprimitive[title={\prm {showifs}}] This primitive will show the conditional stack in the log file or on the console (assuming \prm {tracingonline} being non|-|zero). The shown data is different from other engines because we have more conditionals and also support a more flat nesting model \stopoldprimitive \startoldprimitive[title={\prm {showlists}}] This shows the currently built list. \stopoldprimitive \startoldprimitive[title={\prm {shownodedetails}}] When set to a positive value more details will be shown of nodes when applicable. Values larger than one will also report attributes. What gets shown depends on related callbacks being set. \stopoldprimitive \startoldprimitive[title={\prm {showstack}}] This tracer is only useful for low level debugging of macros, for instance when you run out of save space or when you encounter a performance hit. \starttyping test\scratchcounter0 \showstack {test\scratchcounter1 \showstack} {{test\scratchcounter1 \showstack}} \stoptyping reports \starttyping 1:3: [savestack size 0] 1:3: [savestack bottom] 2:3: [savestack size 2] 2:3: [1: restore, level 1, cs \scratchcounter=integer 1] 2:3: [0: boundary, group 'bottomlevel', boundary 0, attrlist 3600, line 0] 2:3: [savestack bottom] 3:3: [savestack size 3] 3:3: [2: restore, level 1, cs \scratchcounter=integer 1] 3:3: [1: boundary, group 'simple', boundary 0, attrlist 3600, line 12] 3:3: [0: boundary, group 'bottomlevel', boundary 0, attrlist 3600, line 0] 3:3: [savestack bottom] \stoptyping while \starttyping test\scratchcounter1 \showstack {test\scratchcounter1 \showstack} {{test\scratchcounter1 \showstack}} \stoptyping shows this: \starttyping 1:3: [savestack size 0] 1:3: [savestack bottom] 2:3: [savestack size 1] 2:3: [0: boundary, group 'bottomlevel', boundary 0, attrlist 3600, line 0] 2:3: [savestack bottom] 3:3: [savestack size 2] 3:3: [1: boundary, group 'simple', boundary 0, attrlist 3600, line 16] 3:3: [0: boundary, group 'bottomlevel', boundary 0, attrlist 3600, line 0] 3:3: [savestack bottom] \stoptyping Because in the second example the value of \type {\scratchcounter} doesn't really change inside the group there is no need for a restore entry on the stack. In \LUAMETATEX\ there are checks for that so that we consume less stack space. We also store some states (like the line number and current attribute list pointer) in a stack boundary. \stopoldprimitive \startoldprimitive[title={\prm {showthe}}] Prints to the console (and/or log) the value of token after it. \stopoldprimitive \startoldprimitive[title={\prm {showtokens}}] This command expects a (balanced) token list, like \starttyping \showtokens{a few tokens} \stoptyping Depending on what you want to see you need to expand: \starttyping \showtokens\expandafter{\the\everypar} \stoptyping which is equivalent to \typ {\showthe \everypar}. It is an \ETEX\ extension. \stopoldprimitive \startnewprimitive[title={\prm {singlelinepenalty}}] This is a penalty that gets injected before a paragraph that has only one line. It is a one|-|shot parameter, so like \prm {looseness} it only applies to the upcoming (or current) paragraph. \stopnewprimitive \startoldprimitive[title={\prm {skewchar}}][obsolete=yes] This is an (imaginary) character that is used in math fonts. The kerning pair between this character and the current one determines the top anchor of a possible accent. In \OPENTYPE\ there is a dedicated character property for this (but for some reason not for the bottom anchor). \stopoldprimitive \startoldprimitive[title={\prm {skip}}] This is the accessor for an indexed skip (glue) register. \stopoldprimitive \startoldprimitive[title={\prm {skipdef}}] This command associates a control sequence with a skip register (accessed by number). \stopoldprimitive \startnewprimitive[title={\prm {snapshotpar}}] There are many parameters involved in typesetting a paragraph. One complication is that parameters set in the middle might have unpredictable consequences due to grouping, think of: \starttyping text text text text \par text {text text } text \par \stoptyping This makes in traditional \TEX\ because there is no state related to the current paragraph. But in \LUATEX\ we have the initial so called par node that remembers the direction as well as local boxes. In \LUAMETATEX\ we store way more when this node is created. That means that later settings no longer replace the stored ones. The \prm {snapshotpar} takes a bitset that determine what stored parameters get updated to the current values. \startcolumns[n=3] \getbuffer[engine:syntax:frozenparcodes] \stopcolumns One such value covers multiple values, so for instance \type {skip} is good for storing the current \prm {leftskip} and \prm {rightskip} values. More about this feature can be found in the \CONTEXT\ documentation. The list of parameters that gets reset after a paragraph is longer than for \PDFTEX\ and \LUAMETATEX: \prm {emergencyleftskip}, \prm {emergencyrightskip}, \prm {hangafter}, \prm {hangindent}, \prm {interlinepenalties}, \prm {localbrokenpenalty}, \prm {localinterlinepenalty}, \prm {localpretolerance}, \prm {localtolerance}, \prm {looseness}, \prm {parshape} and \prm {singlelinepenalty}. \stopnewprimitive \startoldprimitive[title={\prm {spacefactor}}] The space factor is a somewhat complex feature. When during scanning a character is appended that has a \prm {sfcode} other than 1000, that value is saved. When the time comes to insert a space triggered glue, and that factor is 2000 or more, and when \prm {xspaceskip} is nonzero, that value is used and we're done. If these criteria are not met, and \prm {spaceskip} is nonzero, that value is used, otherwise the space value from the font is used. Now, it if the space factor is larger than 2000 the extra space value from the font is added to the set value. Next the engine is going to tweak the stretch and shrink if that value and in \LUAMETATEX\ that can be done in different ways, depending on \prm {spacefactormode}, \prm {spacefactorstretchlimit} and \prm {spacefactorshrinklimit}. First the stretch. When the set limit is 1000 or more and the saved space factor is also 1000 or more, we multiply the stretch by the limit, otherwise the saved space factor is used. Shrink is done differently. When the shrink limit and space factor are both 1000 or more, we will scale the shrink component by the limit, otherwise we multiply by the saved space factor but here we have three variants, determined by the value of \prm {spacefactormode}. In the first case, when the limit kicks in, a mode value~1 will multiply by limit and divides by 1000. A value of~2 multiplies by 2000 and divides by the limit. Other mode values multiply by 1000 and divide by the limit. When the limit is not used, the same happens but with the saved space factor. If this sounds complicated, here is what regular \TEX\ does: stretch is multiplied by the factor and divided by 1000 while shrink is multiplied by 1000 and divided by the saved factor. The (new) mode driven alternatives are the result of extensive experiments done in the perspective of enhancing the rendering of inline math as well as additional par builder passes. For sure alternative strategies are possible and we can always add more modes. A better explanation of the default strategy around spaces can be found in (of course) The \TEX book and \TEX\ by Topic. \stopoldprimitive \startnewprimitive[title={\prm {spacefactormode}}] Its setting determines the way the glue components (currently only shrink) adapts itself to the current space factor (determined by by the character preceding a space). \stopnewprimitive \startnewprimitive[title={\prm {spacefactorshrinklimit}}] This limit is used when \prm {spacefactormode} is set. See \prm {spacefactor} for a bit more explanation. \stopnewprimitive \startnewprimitive[title={\prm {spacefactorstretchlimit}}] This limit is used when \prm {spacefactormode} is set. See \prm {spacefactor} for a bit more explanation. \stopnewprimitive \startoldprimitive[title={\prm {spaceskip}}] Normally the glue inserted when a space is encountered is taken from the font but this parameter can overrule that. \stopoldprimitive \startoldprimitive[title={\prm {span}}] This primitive combined two upcoming cells into one. Often it is used in combination with \prm {omit}. \stopoldprimitive \startoldprimitive[title={\prm {splitbotmark}}][obsolete=yes] This is a reference to the last mark on the currently split off box, it gives back tokens. \stopoldprimitive \startoldprimitive[title={\prm {splitbotmarks}}] This is a reference to the last mark with the given id (a number) on the currently split off box, it gives back tokens. \stopoldprimitive \startoldprimitive[title={\prm {splitdiscards}}] When a box is split off, items like glue are discarded. This internal register keeps the that list so that it can be pushed back if needed. \stopoldprimitive \startoldprimitive[title={\prm {splitfirstmark}}][obsolete=yes] This is a reference to the first mark on the currently split off box, it gives back tokens. \stopoldprimitive \startoldprimitive[title={\prm {splitfirstmarks}}] This is a reference to the first mark with the given id (a number) on the currently split off box, it gives back tokens. \stopoldprimitive \startoldprimitive[title={\prm {splitmaxdepth}}] The depth of the box that results from a \prm {vsplit}. \stopoldprimitive \startoldprimitive[title={\prm {splittopskip}}] This is the amount of glue that is added to the top of a (new) split of part of a box when \prm {vsplit} is applied. \stopoldprimitive \startnewprimitive[title={\prm {srule}}] This inserts a rule with no width. When a \type {font} and a \type {char} are given the height and depth of that character are taken. Instead of a font \type {fam} is also accepted so that we can use it in math mode. \stopnewprimitive \startoldprimitive[title={\prm {string}}] We mention this original primitive because of the one in the next section. It expands the next token or control sequence as if it was just entered, so normally a control sequence becomes a backslash followed by characters and a space. \stopoldprimitive \startnewprimitive[title={\prm {subprescript}}] Instead of two characters with catcode \the\subscriptcatcode\ (like \type {__}) this primitive can be used. It will add the following argument as lower left script to the nucleus. \stopnewprimitive \startnewprimitive[title={\prm {subscript}}] Instead of a character with catcode \the\subscriptcatcode\ (normally \type {_}) this primitive can be used. It will add the following argument as lower right script to the nucleus. \stopnewprimitive \startnewprimitive[title={\prm {superprescript}}] Instead of two characters with catcode \the\superscriptcatcode\ (like \type {^^}) this primitive can be used. It will add the following argument as upper left script to the nucleus. \stopnewprimitive \startnewprimitive[title={\prm {superscript}}] Instead of a character with catcode \the\superscriptcatcode\ (normally \type {^}) this primitive can be used. It will add the following argument as upper right script to the nucleus. \stopnewprimitive \startnewprimitive[title={\prm {supmarkmode}}] As in other languages, \TEX\ has ways to escape characters and get whatever character needed into the input. By default multiple \type {^} are used for this. The dual \type {^^} variant is a bit weird as it is not continuous but \type {^^^^} and \type {^^^^^^} provide four or six byte hexadecimal references ot characters. The single \type {^} is also used for superscripts but because we support prescripts and indices we get into conflicts with the escapes. When this internal quantity is set to zero, multiple \type {^}'s are interpreted in the input and produce characters. Other values disable the multiple parsing in text and|/|or math mode: \startbuffer \normalsupmarkmode0 $ X^58 \quad X^^58 $ ^^58 \normalsupmarkmode1 $ X^58 \quad X^^58 $ ^^58 \normalsupmarkmode2 $ X^58 \quad X^^58 $ % ^^58 : error \stopbuffer \typebuffer In \CONTEXT\ we default to one but also have the \prm {catcode} set to \the \catcode`^ and the \prm {amcode} to \the \amcode `^. \startlines \catcode`^=\superscriptcatcode % to make sure we handle it in math \amcode `^=\superscriptcatcode \getbuffer \stoplines \stopnewprimitive \startnewprimitive[title={\prm {swapcsvalues}}] Because we mention some \type {def} and \type {let} primitives here, it makes sense to also mention a primitive that will swap two values (meanings). This one has to be used with care. Of course that what gets swapped has to be of the same type (or at least similar enough not to cause issues). Registers for instance store their values in the token, but as soon as we are dealing with token lists we also need to keep an eye on reference counting. So, to some extend this is an experimental feature. \stopnewprimitive \startnewprimitive[title={\prm {tabsize}}] This primitive can be used in the preamble of an alignment and sets the size of a column, as in: \startbuffer \halign{% \aligncontent \aligntab \aligncontent\tabsize 3cm \aligntab \aligncontent \aligntab \aligncontent\tabsize 0cm \cr 1 \aligntab 111\aligntab 1111\aligntab 11\cr 222\aligntab 2 \aligntab 2222\aligntab 22\cr } \stopbuffer \typebuffer As with \prm {tabskip} you need to reset the value explicitly, so that is why we get two wide columns: \blank {\showboxes \getbuffer} \blank \stopnewprimitive \startoldprimitive[title={\prm {tabskip}}] This traditional primitive can be used in the preamble of an alignment and sets the space added between columns, for example: \startbuffer \halign{% \aligncontent \aligntab \aligncontent\tabskip 3cm \aligntab \aligncontent \aligntab \aligncontent\tabskip 0cm \cr 1 \aligntab 111\aligntab 1111\aligntab 11\cr 222\aligntab 2 \aligntab 2222\aligntab 22\cr } \stopbuffer \typebuffer You need to reset the skip explicitly, which is why we get it applied twice here: \blank {\showboxes \getbuffer} \blank \stopoldprimitive \startnewprimitive[title={\prm {textdirection}}] This set the text direction to \type {l2r} (0) or \type {r2l} (1). It also triggers additional checking for balanced flipping in node lists. \stopnewprimitive \startoldprimitive[title={\prm {textfont}}] This primitive is like \prm {font} but with a family number as (first) argument so it is specific for math. It is the largest one of the three family members; its relatives are \prm {scriptfont} and \prm {scriptscriptfont}. \stopoldprimitive \startoldprimitive[title={\prm {textstyle}}] One of the main math styles; integer representation: \the\textstyle. \stopoldprimitive \startoldprimitive[title={\prm {the}}] The \prm {the} primitive serializes the following token, when applicable: integers, dimensions, token registers, special quantities, etc. The catcodes of the result will be according to the current settings, so in \type {\the \dimen0}, the \type {pt} will have catcode \quote {letter} and the number and period will become \quote {other}. \stopoldprimitive \startnewprimitive[title={\prm {thewithoutunit}}] The \prm{the} primitive, when applied to a dimension variable, adds a \type {pt} unit. because dimensions are the only traditional unit with a fractional part they are sometimes used as pseudo floats in which case \prm {thewithoutunit} can be used to avoid the unit. This is more convenient than stripping it off afterwards (via an expandable macro). \stopnewprimitive \startoldprimitive[title={\prm {thickmuskip}}] A predefined mu skip register that can be used in math (inter atom) spacing. The current value is {\tt \the\thickmuskip}. In traditional \TEX\ most inter atom spacing is hard coded using the predefined registers. \stopoldprimitive \startoldprimitive[title={\prm {thinmuskip}}] A predefined mu skip register that can be used in math (inter atom) spacing. The current value is {\tt \the\thinmuskip}. In traditional \TEX\ most inter atom spacing is hard coded using the predefined registers. \stopoldprimitive \startoldprimitive[title={\prm {time}}] This internal number starts out with minute (starting at midnight) that the job started. \stopoldprimitive \startnewprimitive[title={\prm {tinymuskip}}] A predefined mu skip register that can be used in math (inter atom) spacing. The current value is {\tt \the\tinymuskip}. This one complements \prm {thinmuskip}, \prm {medmuskip}, \prm {thickmuskip} and the new \prm {pettymuskip} \stopnewprimitive \startnewprimitive[title={\prm {tocharacter}}] The given number is converted into an \UTF-8 sequence. In \LUATEX\ this one is named \type {\Uchar}. \stopnewprimitive \startnewprimitive[title={\prm {todimension}}] \startbuffer \scratchdimen = 1234pt \todimension\scratchdimen \stopbuffer The following code gives this: {\nospacing\inlinebuffer} and like its numeric counterparts accepts anything that resembles a number this one goes beyond (user, internal or pseudo) registers values too. \typebuffer \stopnewprimitive \startnewprimitive[title={\prm {tohexadecimal}}] \startbuffer \scratchcounter = 1234 \tohexadecimal\scratchcounter \stopbuffer The following code gives this: {\nospacing\inlinebuffer} with uppercase letters. \typebuffer \stopnewprimitive \startnewprimitive[title={\prm {tointeger}}] \startbuffer \scratchcounter = 1234 \tointeger\scratchcounter \stopbuffer The following code gives this: {\nospacing\inlinebuffer} and is equivalent to \prm {number}. \typebuffer \stopnewprimitive \startnewprimitive[title={\prm {tokenized}}] Just as \prm {expanded} has a counterpart \prm {unexpanded}, it makes sense to give \prm {detokenize} a companion: \startbuffer \edef\foo{\detokenize{\inframed{foo}}} \edef\oof{\detokenize{\inframed{oof}}} \meaning\foo \crlf \dontleavehmode\foo \edef\foo{\tokenized{\foo\foo}} \meaning\foo \crlf \dontleavehmode\foo \dontleavehmode\tokenized{\foo\oof} \stopbuffer \typebuffer {\tttf \getbuffer} This primitive is similar to: \starttyping \def\tokenized#1{\scantextokens\expandafter{\normalexpanded{#1}}} \stoptyping and should be more efficient, not that it matters much as we don't use it that much (if at all). \stopnewprimitive \startoldprimitive[title={\prm {toks}}] This is the accessor of a token register so it expects a number or \prm {toksdef}'d macro. \stopoldprimitive \startnewprimitive[title={\prm {toksapp}}] One way to append something to a token list is the following: \starttyping \scratchtoks\expandafter{\the\scratchtoks more stuff} \stoptyping This works all right, but it involves a copy of what is already in \type {\scratchtoks}. This is seldom a real issue unless we have large token lists and many appends. This is why \LUATEX\ introduced: \starttyping \toksapp\scratchtoks{more stuff} \toksapp\scratchtoksone\scratchtokstwo \stoptyping At some point, when working on \LUAMETATEX, I realized that primitives like this one and the next appenders and prependers to be discussed were always on the radar of Taco and me. Some were even implemented in what we called \type {eetex}: extended \ETEX, and we even found back the prototypes, dating from pre|-|\PDFTEX\ times. \stopnewprimitive \startoldprimitive[title={\prm {toksdef}}] The given name (control sequence) will be bound to the given token register (a number). Often this primitive is hidden in a high level macro that manages allocation. \stopoldprimitive \startnewprimitive[title={\prm {tokspre}}] Where appending something is easy because of the possible \prm {expandafter} trickery a prepend would involve more work, either using temporary token registers and|/|or using a mixture of the (no)expansion added by \ETEX, but all are kind of inefficient and cumbersome. \starttyping \tokspre\scratchtoks{less stuff} \tokspre\scratchtoksone\scratchtokstwo \stoptyping This prepends the token list that is provided. \stopnewprimitive \startoldprimitive[title={\prm {tolerance}}] When the par builder runs into a line with a badness larger than this value and when \prm {emergencystretch} is set a third pass is enabled. In \LUAMETATEX\ we can have more than one second pass and there are more parameters that influence the process. \stopoldprimitive \startnewprimitive[title={\prm {tolerant}}] This prefix tags the following macro as being tolerant with respect to the expected arguments. It only makes sense when delimited arguments are used or when braces are mandate. \startbuffer \tolerant\def\foo[#1]#*[#2]{(#1)(#2)} \stopbuffer \typebuffer \getbuffer This definition makes \type {\foo} tolerant for various calls: \startbuffer \foo \foo[1] \foo [1] \foo[1] [2] \foo [1] [2] \stopbuffer \typebuffer these give: \inlinebuffer. The spaces after the first call disappear because the macro name parser gobbles it, while in the second case the \type {#*} gobbles them. Here is a variant: \startbuffer \tolerant\def\foo[#1]#,[#2]{!#1!#2!} \foo[?] x \foo[?] [?] x \tolerant\def\foo[#1]#*[#2]{!#1!#2!} \foo[?] x \foo[?] [?] x \stopbuffer \typebuffer We now get the following: \getbuffer Here the \type {#,} remembers that spaces were gobbles and they will be put back when there is no further match. These are just a few examples of this tolerant feature. More details can be found in the lowlevel manuals. \stopnewprimitive \startnewprimitive[title={\prm {tomathstyle}}] Internally math styles are numbers, where \prm {displaystyle} is \tomathstyle \displaystyle \space and \prm {crampedscriptscriptstyle} is \tomathstyle \crampedscriptscriptstyle. You can convert the verbose style to a number with \prm {tomathstyle}. \stopnewprimitive \startoldprimitive[title={\prm {topmark}}][obsolete=yes] This is a reference to the last mark on the previous (split off) page, it gives back tokens. \stopoldprimitive \startoldprimitive[title={\prm {topmarks}}] This is a reference to the last mark with the given id (a number) on the previous page, it gives back tokens. \stopoldprimitive This is a reference to the first mark on the (split off) page, it gives back tokens. This is a reference to the first mark with the given id (a number) on the (split off) page, it gives back tokens. \startoldprimitive[title={\prm {topskip}}] This is the amount of glue that is added to the top of a (new) page. \stopoldprimitive \startnewprimitive[title={\prm {toscaled}}] \startbuffer \scratchdimen = 1234pt \toscaled\scratchdimen \stopbuffer The following code gives this: {\nospacing\inlinebuffer} is similar to \prm {todimension} but omits the \type {pt} so that we don't need to revert to some nasty stripping code. \typebuffer \stopnewprimitive \startnewprimitive[title={\prm {tosparsedimension}}] \startbuffer \scratchdimen = 1234pt \tosparsedimension\scratchdimen \stopbuffer The following code gives this: {\nospacing\inlinebuffer} where \quote {sparse} indicates that redundant trailing zeros are not shown. \typebuffer \stopnewprimitive \startnewprimitive[title={\prm {tosparsescaled}}] \startbuffer \scratchdimen = 1234pt \tosparsescaled\scratchdimen \stopbuffer The following code gives this: {\nospacing\inlinebuffer} where \quote {sparse} means that redundant trailing zeros are omitted. \typebuffer \stopnewprimitive \startnewprimitive[title={\prm {tpack}}] This primitive is like \prm {vtop} but without the callback overhead. \stopnewprimitive \startnewprimitive[title={\prm {tracingadjusts}}] In \LUAMETATEX\ the adjust feature has more functionality and also is carried over. When set to a positive values \prm {vadjust} processing reports details. The higher the number, the more you'll get. \stopnewprimitive \startnewprimitive[title={\prm {tracingalignments}}] When set to a positive value the alignment mechanism will keep you informed about what is done in various stages. Higher values unleash more information, including what callbacks kick in. \stopnewprimitive \startoldprimitive[title={\prm {tracingassigns}}] When set to a positive values assignments to parameters and variables are reported on the console and|/|or in the log file. Because \LUAMETATEX\ avoids redundant assignments these don't get reported. \stopoldprimitive \startoldprimitive[title={\prm {tracingcommands}}] When set to a positive values the commands (primitives) are reported on the console and|/|or in the log file. \stopoldprimitive \startnewprimitive[title={\prm {tracingexpressions}}] The extended expression commands like \prm {numexpression} and \prm {dimexpression} can be traced by setting this parameter to a positive value. \stopnewprimitive \startnewprimitive[title={\prm {tracingfullboxes}}] When set to a positive value the box will be shown in case of an overfull box. When a quality callback is set this will not happen as all reporting is then delegated. \stopnewprimitive \startoldprimitive[title={\prm {tracinggroups}}] When set to a positive values grouping is reported on the console and|/|or in the log file. \stopoldprimitive \startnewprimitive[title={\prm {tracinghyphenation}}] When set to a positive values the hyphenation process is reported on the console and|/|or in the log file. \stopnewprimitive \startoldprimitive[title={\prm {tracingifs}}] When set some details of what gets tested and what results are seen is reported. \stopoldprimitive \startnewprimitive[title={\prm {tracinginserts}}] A positive value enables tracing where values larger than~1 will report more details. \stopnewprimitive \startnewprimitive[title={\prm {tracinglevels}}] The lines in a log file can be prefixed with some details, depending on the bits set: \starttabulate[|T|l|] \NC 0x1 \NC current group \NC \NR \NC 0x2 \NC current input \NC \NR \NC 0x4 \NC catcode table \NC \NR \stoptabulate \stopnewprimitive \startnewprimitive[title={\prm {tracinglists}}] At various stages the lists being processed can be shown. This is mostly an option for developers. \stopnewprimitive \startoldprimitive[title={\prm {tracinglostchars}}] When set to one characters not present in a font will be reported in the log file, a value of two will also report this on the console. \stopoldprimitive \startoldprimitive[title={\prm {tracingmacros}}] This parameter controls reporting of what macros are seen and expanded. \stopoldprimitive \startnewprimitive[title={\prm {tracingmarks}}] Marks are information blobs that track states that can be queried when a page is handled over to the shipout routine. They travel through the system in a bit different than traditionally: like like adjusts and inserts deeply buried ones bubble up to outer level boxes. This parameters controls what progress gets reported. \stopnewprimitive \startnewprimitive[title={\prm {tracingmath}}] The higher the value, the more information you will get about the various stages in rendering math. Because tracing of nodes is rather verbose you need to know a bit what this engine does. Conceptually there are differences between the \LUAMETATEX\ and traditional engine, like more passes, inter-atom spacing, different low level mechanisms. This feature is mostly meant for developers who tweak the many available parameters. \stopnewprimitive \startoldprimitive[title={\prm {tracingnesting}}] A positive value triggers log messages about the current level. \stopoldprimitive \startnewprimitive[title={\prm {tracingnodes}}] When set to a positive value more details about nodes (in boxes) will be reported. Because this is also controlled by callbacks what gets reported is macro package dependent. \stopnewprimitive \startoldprimitive[title={\prm {tracingonline}}] The engine has two output channels: the log file and the console and by default most tracing (when enabled) goes to the log file. When this parameter is set to a positive value tracing will also happen in the console. Messages from the \LUA\ end can be channeled independently. \stopoldprimitive \startoldprimitive[title={\prm {tracingoutput}}] Values larger than one result in some information about what gets passed to the output routine. \stopoldprimitive \startoldprimitive[title={\prm {tracingpages}}] Values larger than one result in some information about the page building process. In \LUAMETATEX\ there is more info for higher values. \stopoldprimitive \startoldprimitive[title={\prm {tracingparagraphs}}] Values larger than one result in some information about the par building process. In \LUAMETATEX\ there is more info for higher values. \stopoldprimitive \startnewprimitive[title={\prm {tracingpasses}}] In \LUAMETATEX\ you can configure additional second stage par builder passes and this parameter controls what gets reported on the console and|/|or in the log file. \stopnewprimitive \startnewprimitive[title={\prm {tracingpenalties}}] This setting triggers reporting of actions due to special penalties in the page builder. \stopnewprimitive \startoldprimitive[title={\prm {tracingrestores}}] When set to a positive values (re)assignments after grouping to parameters and variables are reported on the console and|/|or in the log file. Because \LUAMETATEX\ avoids redundant assignments these don't get reported. \stopoldprimitive \startoldprimitive[title={\prm {tracingstats}}] This parameter is a dummy in \LUAMETATEX. There are anyway some statistic reported when the format is made but for a regular run it is up to the macro package to come up with useful information. \stopoldprimitive \startnewprimitive[title={\prm {tsplit}}] This splits like \prm {vsplit} but it returns a \prm {vtop} box instead. \stopnewprimitive \startoldprimitive[title={\prm {uccode}}] When the \prm {uppercase} operation is applied the uppercase code of a character is used for the replacement. This primitive is used to set that code, so it expects two character number. \stopoldprimitive \startoldprimitive[title={\prm {uchyph}}] When set to a positive number words that start with a capital will be hyphenated. \stopoldprimitive \startnewprimitive[title={\prm {uleaders}}] This leader adapts itself after a paragraph has been typeset. Here are a few examples: \startbuffer test \leaders \hbox {x}\hfill\ test test \uleaders \hbox{x x x x}\hfill\ test test \hbox{x x x x}\hskip 3cm plus 1cm\ test test \uleaders \hbox{x x x x}\hskip 3cm plus 1cm\ test \stopbuffer \typebuffer When an \prm {uleaders} is used the glue in the given box will be adapted to the available space. \startlines \getbuffer \stoplines \startsetups adaptive:test \setbox\usedadaptivebox\hbox to \usedadaptivewidth yoffset -\usedadaptivedepth \bgroup \externalfigure [cow.pdf] [width=\usedadaptivewidth, height=\dimexpr\usedadaptiveheight+\usedadaptivedepth\relax]% \egroup \stopsetups Optionally the \type {callback} followed by a number can be given, in which case a callback kicks in that gets that the node, a group identifier, and the number passed. It permits (for instance) adaptive graphics: \dostepwiserecurse {1} {100} {5} {\hbox {#1=\romannumerals{#1}} {\adaptivebox [strut=yes, setups=adaptive:test]{}} }. \stopnewprimitive \startoldprimitive[title={\prm {unboundary}}] When possible a preceding boundary node will be removed. \stopoldprimitive \startnewprimitive[title={\prm {undent}}] When possible the already added indentation will be removed. \stopnewprimitive \startoldprimitive[title={\prm {underline}}] This is a math specific primitive that draws a line under the given content. It is a poor mans replacement for a delimiter. The thickness is set with \prm {Umathunderbarrule}, the distance between content and rule is set by \prm {Umathunderbarvgap} and \prm {Umathunderbarkern} is added above the rule. The style used for the content under the rule can be set with \prm {Umathunderlinevariant}. See \prm {overline} for what these parameters do. \stopoldprimitive \startoldprimitive[title={\prm {unexpanded}}] This is an \ETEX\ enhancement. The content will not be expanded in a context where expansion is happening, like in an \prm {edef}. In \CONTEXT\ you need to use \prm {normalunexpanded} because we already had a macro with that name. \startbuffer \def \A{!} \meaning\A \def \B{?} \meaning\B \edef\C{\A\B} \meaning\C \edef\C{\normalunexpanded{\A}\B} \meaning\C \stopbuffer \typebuffer \startlines \tttf \getbuffer \stoplines \stopoldprimitive \startnewprimitive[title={\prm {unexpandedendless}}] This one loops forever so you need to quit explicitly. \stopnewprimitive \startnewprimitive[title={\prm {unexpandedloop}}] As follow up on \prm {expandedloop} we now show its counterpart: \startbuffer \edef\whatever {\unexpandedloop 1 10 1 {\scratchcounter=\the\currentloopiterator\relax}} \meaningasis\whatever \stopbuffer \typebuffer \start \veryraggedright \tt\tfx \getbuffer \stop \blank The difference between the (un)expanded loops and a local controlled one is shown here. Watch the out of order injection of \type {A}'s. \startbuffer \edef\TestA{\localcontrolledloop 1 5 1 {A}} % out of order \edef\TestB{\expandedloop 1 5 1 {B}} \edef\TestC{\unexpandedloop 1 5 1 {C\relax}} \stopbuffer \typebuffer \getbuffer We show the effective definition as well as the outcome of using them \startbuffer \meaningasis\TestA \meaningasis\TestB \meaningasis\TestC A: \TestA B: \TestB C: \TestC \stopbuffer \typebuffer \startlines \tttf \getbuffer \stoplines Watch how because it is empty \type {\TestA} has become a constant macro because that's what deep down empty boils down to. \stopnewprimitive \startnewprimitive[title={\prm {unexpandedrepeat}}] This one takes one instead of three arguments which looks better in simple loops. \stopnewprimitive \startoldprimitive[title={\prm {unhbox}}] A box is a packaged list and once packed travels through the system as a single object with properties, like dimensions. This primitive injects the original list and discards the wrapper. \stopoldprimitive \startoldprimitive[title={\prm {unhcopy}}] This is like \prm {unhbox} but keeps the original. It is one of the more costly operations. \stopoldprimitive \startnewprimitive[title={\prm {unhpack}}] This primitive is like \prm {unhbox} but without the callback overhead. \stopnewprimitive \startoldprimitive[title={\prm {unkern}}] This removes the last kern, if possible. \stopoldprimitive \startoldprimitive[title={\prm {unless}}] This \ETEX\ prefix will negate the test (when applicable). \starttyping \ifx\one\two YES\else NO\fi \unless\ifx\one\two NO\else YES\fi \stoptyping This primitive is hardly used in \CONTEXT\ and we probably could get rid of these few cases. \stopoldprimitive \startnewprimitive[title={\prm {unletfrozen}}] A frozen macro cannot be redefined: you get an error. But as nothing in \TEX\ is set in stone, you can do this: \starttyping \frozen\def\MyMacro{...} \unletfrozen\MyMacro \stoptyping and \type {\MyMacro} is no longer protected from overloading. It is still undecided to what extend \CONTEXT\ will use this feature. \stopnewprimitive \startnewprimitive[title={\prm {unletprotected}}] The complementary operation of \prm {letprotected} can be used to unprotect a macro, so that it gets expandable. \startbuffer \def \MyMacroA{alpha} \protected \def \MyMacroB{beta} \edef \MyMacroC{\MyMacroA\MyMacroB} \unletprotected \MyMacroB \edef \MyMacroD{\MyMacroA\MyMacroB} \meaning \MyMacroC\crlf \meaning \MyMacroD\par \stopbuffer \typebuffer Compare this with the example in the previous section: {\tttf \getbuffer} \stopnewprimitive \startoldprimitive[title={\prm {unpenalty}}] This removes the last penalty, if possible. \stopoldprimitive \startoldprimitive[title={\prm {unskip}}] This removes the last glue, if possible. \stopoldprimitive \startnewprimitive[title={\prm {untraced}}] Related to the meaning providers is the \prm {untraced} prefix. It marks a macro as to be reported by name only. It makes the macro look like a primitive. \starttyping \def\foo{} \untraced\def\oof{} \scratchtoks{\foo\foo\oof\oof} \tracingall \the\scratchtoks \tracingnone \stoptyping This will show up in the log as follows: \starttyping 1:4: {\the} 1:5: \foo -> 1:5: \foo -> 1:5: \oof 1:5: \oof \stoptyping This is again a trick to avoid too much clutter in a log. Often it doesn't matter to users what the meaning of a macro is (if they trace at all). \footnote {An earlier variant could also hide the expansion completely but that was just confusing.} \stopnewprimitive \startoldprimitive[title={\prm {unvbox}}] A box is a packaged list and once packed travels through the system as a single object with properties, like dimensions. This primitive injects the original list and discards the wrapper. \stopoldprimitive \startoldprimitive[title={\prm {unvcopy}}] This is like \prm {unvbox} but keeps the original. It is one of the more costly operations. \stopoldprimitive \startnewprimitive[title={\prm {unvpack}}] This primitive is like \prm {unvbox} but without the callback overhead. \stopnewprimitive \startoldprimitive[title={\prm {uppercase}}] See its counterpart \prm {lowercase} for an explanation. \stopoldprimitive \startoldprimitive[title={\prm {vadjust}}] This injects a node that stores material that will injected before or after the line where it has become part of. In \LUAMETATEX\ there are more features, driven by keywords. \stopoldprimitive \startoldprimitive[title={\prm {valign}}] This command starts vertically aligned material. Its counterpart \prm {halign} is used more frequently. Most macro packages provide wrappers around these commands. First one specifies a preamble which is then followed by entries (rows and columns). \stopoldprimitive \startnewprimitive[title={\prm {variablefam}}] In traditional \TEX\ sets the family of what are considered variables (class 7) to the current family (which often means that they adapt to the current alphabet) and then injects a math character of class ordinary. This parameter can be used to obey the given class when the family set for a character is the same as this parameter. So we then use the given class with the current family. It is mostly there for compatibility with \LUATEX\ and experimenting (outside \CONTEXT). \stopnewprimitive \startoldprimitive[title={\prm {vbadness}}] This sets the threshold for reporting a (vertical) badness value, its current value is \the \badness. \stopoldprimitive \startoldprimitive[title={\prm {vbox}}] This creates a vertical box. In the process callbacks can be triggered that can preprocess the content, influence line breaking as well as assembling the resulting paragraph. More can be found in dedicated manuals. The baseline is at the bottom. \stopoldprimitive \startoldprimitive[title={\prm {vcenter}}] In traditional \TEX\ this box packer is only permitted in math mode but in \LUAMETATEX\ it also works in text mode. The content is centered in the vertical box. \stopoldprimitive \startoldprimitive[title={\prm {vfil}}] This is a shortcut for \typ {\vskip plus 1 fil} (first order filler). \stopoldprimitive \startoldprimitive[title={\prm {vfill}}] This is a shortcut for \typ {\vskip plus 1 fill} (second order filler). \stopoldprimitive \startoldprimitive[title={\prm {vfilneg}}] This is a shortcut for \typ {\vskip plus - 1 fil} so it can compensate \prm {vfil}. \stopoldprimitive \startoldprimitive[title={\prm {vfuzz}}] This dimension sets the threshold for reporting vertical boxes that are under- or overfull. The current value is \the \vfuzz. \stopoldprimitive \startnewprimitive[title={\prm {virtualhrule}}] This is a horizontal rule with zero dimensions from the perspective of the frontend but the backend can access them as set. \stopnewprimitive \startnewprimitive[title={\prm {virtualvrule}}] This is a vertical rule with zero dimensions from the perspective of the frontend but the backend can access them as set. \stopnewprimitive \startoldprimitive[title={\prm {vkern}}] This primitive is like \prm {kern} but will force the engine into vertical mode if it isn't yet. \stopoldprimitive \startnewprimitive[title={\prm {vpack}}] This primitive is like \prm {vbox} but without the callback overhead. \stopnewprimitive \startnewprimitive[title={\prm {vpenalty}}] This primitive is like \prm {penalty} but will force the engine into vertical mode if it isn't yet. \stopnewprimitive \startoldprimitive[title={\prm {vrule}}] This creates a vertical rule. Unless the height and depth are set they will stretch to fix the available space. In addition to the traditional \type {width}, \type {height} and \type {depth} specifiers some more are accepted. These are discussed in other manuals. See \prm {hrule} for a simple example. \stopoldprimitive \startoldprimitive[title={\prm {vsize}}] This sets (or gets) the current vertical size. While setting the \prm {hsize} inside a \prm {vbox} has consequences, setting the \prm {vsize} mostly makes sense at the outer level (the page). \stopoldprimitive \startoldprimitive[title={\prm {vskip}}] The given glue is injected in the vertical list. If possible vertical mode is entered. \stopoldprimitive \startoldprimitive[title={\prm {vsplit}}] This operator splits a given amount from a vertical box. In \LUAMETATEX\ we can split \type {to} but also \type {upto}, so that we don't have to repack the result in order to see how much is actually in there. \stopoldprimitive \startoldprimitive[title={\prm {vss}}] This is the vertical variant of \prm {hss}. See there for what it means. \stopoldprimitive \startoldprimitive[title={\prm {vtop}}] This creates a vertical box. In the process callbacks can be triggered that can preprocess the content, influence line breaking as well as assembling the resulting paragraph. More can be found in dedicated manuals. The baseline is at the top. \stopoldprimitive \startoldprimitive[title={\prm {wd}}] Returns the width of the given box. \stopoldprimitive \startoldprimitive[title={\prm {widowpenalties}}] This is an array of penalty put before the last lines in a paragraph. High values discourage (or even prevent) a lone line at the beginning of a next page. This command expects a count value indicating the number of entries that will follow. The first entry is ends up before the last line. \stopoldprimitive \startoldprimitive[title={\prm {widowpenalty}}] This is the penalty put before a widow line in a paragraph. High values discourage (or even prevent) a lone line at the beginning of a next page. \stopoldprimitive \startnewprimitive[title={\prm {wordboundary}}] The hypenation routine has to decide where a word begins and ends. If you want to make sure that there is a proper begin or end of a word you can inject this boundary. \stopnewprimitive \startnewprimitive[title={\prm {wrapuppar}}] What this primitive does can best be shown with an example: \startbuffer some text\wrapuppar{one} and some\wrapuppar{two} more \stopbuffer \typebuffer We get: \blank \getbuffer \blank So, it is a complementary command to \prm {everypar}. It can only be issued inside a paragraph. \stopnewprimitive \startoldprimitive[title={\prm {xdef}}] This is an alternative for \type {\global \edef}: \starttyping \xdef\MyMacro{...} \stoptyping \stopoldprimitive \startnewprimitive[title={\prm {xdefcsname}}] This is the companion of \prm {xdef}: \starttyping \expandafter\xdef\csname MyMacro:1\endcsname{...} \xdefcsname MyMacro:1\endcsname{...} \stoptyping \stopnewprimitive \startoldprimitive[title={\prm {xleaders}}] See \prm {gleaders} for an explanation. \stopoldprimitive \startoldprimitive[title={\prm {xspaceskip}}] Normally the glue inserted when a space is encountered after a character with a space factor other than 1000 is taken from the font (fontdimen 7) unless this parameter is set in which case its value is added. \stopoldprimitive \startnewprimitive[title={\prm {xtoks}}] This is the global variant of \prm {etoks}. \stopnewprimitive \startnewprimitive[title={\prm {xtoksapp}}] This is the global variant of \prm {etoksapp}. \stopnewprimitive \startnewprimitive[title={\prm {xtokspre}}] This is the global variant of \prm {etokspre}. \stopnewprimitive \startoldprimitive[title={\prm {year}}] This internal number starts out with the year that the job started. \stopoldprimitive \stopsubject \startsubject[title=Obsolete] The \LUAMETATEX\ engine has more than its \LUATEX\ ancestor but it also has less. Because in the end the local control mechanism performed quite okay I decided to drop the \prm {immediateassignment} and \prm {immediateassigned} variants. They sort of used the same trick so there isn't much to gain and it was less generic (read: error prone). % \startnewprimitive[title={\prm {immediateassignment}}] % % Assignments are not expandable which means that you cannot define fully % expandable macros that have assignments. But, there is a way out of this: % % \startbuffer % \scratchcounter = 10 % \edef\whatever{% % (\the\scratchcounter) % \immediateassignment\scratchcounter\numexpr\scratchcounter+10\relax % \immediateassignment\advance\scratchcounter -5 % (\the\scratchcounter) % } % \meaning\whatever % \stopbuffer % % \typebuffer % % Don't expect miracles: you can't mix|-|in content or unexpandable tokens as they % will either show up or quit the scanning. % % {\getbuffer} % % \stopnewprimitive % % \startnewprimitive[title={\prm {immediateassigned}}] % % This is the multi|-|token variant of the primitive mentioned in the previous % section. % % \startbuffer % \scratchcounter = 10 % \edef\whatever{% % (\the\scratchcounter) % \immediateassigned{ % \scratchcounter\numexpr\scratchcounter+10\relax % \advance\scratchcounter -5 % }% % (\the\scratchcounter) % } % \meaning\whatever % \stopbuffer % % \typebuffer % % The results are the same as in the previous section: % % {\getbuffer} % % \stopnewprimitive \stopsubject \page \definehead [Syntax] [subsection] % [style=\tta\bf, % numberwidth=2fs, % after=\blank\startpacked, % aftersection=\stoppacked] \startsubject[title=Syntax] \startpagecolumns[page=no] \startluacode moduledata.engine.allspecifications() \stopluacode \stoppagecolumns \stopsubject \page % % It doesn't make sense to typeset this, also because it makes me feel old. % % \startsubject[title=A few notes on extensions] % ,placeholder=todo] % % This is a companion to the regular \LUAMETATEX\ reference manual, which is mostly % a concise summary of the program and its features. They don't replace each other, % and none of them claims completeness. There might be more manuals that discuss % specific kind of extensions in the future. First some comments on extensions. % % The starting point of all \TEX\ engines is \TEX. The first follow up was \TEX\ % with support for 8 bit and languages. After that it took some time, but then two % projects started that extended \TEX: \ETEX\ and \OMEGA. In the end the first % brought some extensions to the macro machinery, more registers, a simple right to % left typesetting feature, some more tracing, etc. The second was more ambitious % and has input translation mechanisms, larger fonts, and multi directional % typesetting. By the time \ETEX\ became stable, the \PDFTEX\ engine had showed up % and at some point it integrated \ETEX. But \PDFTEX\ itself also extended the % several components that make up \TEX. The \NTS\ project was started as follow up % on \ETEX\ but although an engine written in \JAVA\ was the result it never was % used for extensions; this project was fully funded by the german language user % group. % % The \CONTEXT\ macro package was an early adopter of the \ETEX\ and \PDFTEX\ % extensions. Probably the most significant effect was that we got more registers % (some other features were already kind of present in macro form). In between % these engines we played with \type {eetex} (extended \ETEX) because we had some % wishes of our own. We also explored extensions to the \DVI\ format but in the end % \PDF\ won that race. An example of a new mechanism that we introduced in % \CONTEXT\ was position tracking: marking positions that can be saved when the % output is created and used in a second run. This started as a \DVI\ postprocessor % in \PERL\ written by me, later turned into a \CLANGUAGE\ program by Taco, and % eventually integrated in \PDFTEX\ by Thanh (\PDFTEX\ was a phd project). At some % point \XETEX\ was developed, funded and driven by an organization that did high % end multi lingual typesetting; it was based on \ETEX\ and uses a \DVI\ to \PDF\ % backend processor. Both \PDFTEX\ and \XETEX\ are supported by \CONTEXT\ \MKII, % and both engines are basically stable and frozen. % % At some point Hartmut and I started playing with \LUA\ in \PDFTEX\ but soon Taco, % Hartmut and I decided to start a follow up project. All the work on \LUATEX\ (and % later \LUAMETATEX) is done whenever there is time and without financial % compensation, so we have a slow but steady development track. Early in the % \LUATEX\ development there has been some funding for the initial transition (by % Taco) from \PDFTEX\ to what became the early versions of \LUATEX . You can read % more about the oriental \TEX\ project in other documents and articles in user % group journals. There has been some funded development of a library subsystem % (which for some reason never took off) as well as \LUAJIT\ integration (by % Luigi). The initial \METAPOST\ library (also done by Taco) was funded by a couple % of user groups. Then there are the (ongoing) font projects by GUST that got % funded by user groups as these were much needed for the \UNICODE\ engines. % % After the jump start, most work was and is still done in the usual \TEX\ spirit, % on a voluntary basis, by folks from the \CONTEXT\ community, and after a decades % we reached the stable version 1.00. It's one of the engines in \TEXLIVE\ and % Luigi makes sure it integrates well in there. We did continue and around 1.10 the % more of less final version was reached and \LUAMETATEX\ took off. In \LUATEX\ % only bugs get fixed, occasionally some helpers can get added, and we might port % some of \LUAMETATEX\ back to its parent, when it doesn't harm compatibility. % % Already early in development some primitives were added that enhance the macro % language. More were added later. It's these extensions that are discussed in this % document. There are several documents in the \CONTEXT\ distribution that discuss % the (ongoing) development, right from the start, and these often contain % examples. For instance some of the new primitives have been introduced there, % complete with a rationale and examples of usage. % % Just for the record: the \CONTEXT\ group runs the build farm that is used to % generate binaries for all sorts of platforms. We make sure that there are always % versions that can be used for real production jobs. You can expect regular % updates as long as there are developments (of course, eventually we're done). % % \stopsubject \startsubject[title=Rationale] % ,placeholder=todo] Some words about the why and how it came. One of the early adopters of \CONTEXT\ was Taco Hoekwater and we spent numerous trips to \TEX\ meetings all over the globe. He was also the only one I knew who had read the \TEX\ sources. Because \CONTEXT\ has always been on the edge of what is possible and at that time we both used it for rather advanced rendering, we also ran into the limitations. I'm not talking of \TEX\ features here. Naturally old school \TEX\ is not really geared for dealing with images of all kind, colors in all kind of color spaces, highly interactive documents, input methods like \XML, etc. The nice thing is that it offers some escapes, like specials and writes and later execution of programs that opened up lots of possibilities, so in practice there were no real limitations to what one could do. But coming up with a consistent and extensible (multi lingual) user interface was non trivial, because it had an impact in memory usage and performance. A lot could be done given some programming, as \CONTEXT\ \MKII\ proves, but it was not always pretty under the hood. The move to \LUATEX\ and \MKIV\ transferred some action to \LUA, and because \LUATEX\ effectively was a \CONTEXT\ related project, we could easily keep them in sync. Our traveling together, meeting several times per year, and eventually email and intense \LUATEX\ developments (lots of Skype sessions) for a couple of years, gave us enough opportunity to discuss all kind of nice features not present in the engine. The previous century we discussed lots of them, rejected some, stayed with others, and I admit that forgot about most of the arguments already. Some that we did was already explored in \type {eetex}, some of those ended up in \LUATEX, and eventually what we have in \LUAMETATEX\ can been seen as the result of years of programming in \TEX, improving macros, getting more performance and efficiency out of existing \CONTEXT\ code and inspiration that we got out of the \CONTEXT\ community, a demanding lot, always willing to experiment with us. Once I decided to work on \LUAMETATEX\ and bind its source to the \CONTEXT\ distribution so that we can be sure that it won't get messed up and might interfere with the \CONTEXT\ expectations, some more primitives saw their way into it. It is very easy to come up with all kind of bells and whistles but it is equally easy to hurt performance of an engine and what might go unnoticed in simple tests can really affect a macro package that depends on stability. So, what I did was mostly looking at the \CONTEXT\ code and wondering how to make some of the low level macros look more natural, also because I know that there are users who look into these sources. We spend a lot of time making them look consistent and nice and the nicer the better. Getting a better performance was seldom an argument because much is already as fast as can be so there is not that much to gain, but less clutter in tracing was an argument for some new primitives. Also, the fact that we soon might need to fall back on our phones to use \TEX\ a smaller memory footprint and less byte shuffling also was a consideration. The \LUAMETATEX\ memory footprint is somewhat smaller than the \LUATEX\ footprint. By binding \LUAMETATEX\ to \CONTEXT\ we can also guarantee that the combinations works as expected. I'm aware of the fact that \CONTEXT\ is in a somewhat unique position. First of all it has always been kind of cutting edge so its users are willing to experiment. There are users who immediately update and run tests, so bugs can and will be fixed fast. Already for a long time the community has an convenient infrastructure for updating and the build farm for generating binaries (also for other engines) is running smoothly. Then there is the \CONTEXT\ user interface that is quite consistent and permits extensions with staying backward compatible. Sometimes users run into old manuals or examples and then complain that \CONTEXT\ is not compatible but that then involves obsolete technology: we no longer need font and input encodings and font definitions are different for \OPENTYPE\ fonts. We always had an abstract backend model, but nowadays \PDF\ is kind of dominant and drives a lot of expectations. So, some of the \MKII\ commands are gone and \MKIV\ has some more. Also, as \METAPOST\ evolved that department in \CONTEXT\ also evolved. Think of it like cars: soon all are electric so one cannot expect a hole to poor in some fluid but gets a (often incompatible) plug instead. And buttons became touch panels. There is no need to use much force to steer or brake. Navigation is different, as are many controls. And do we need to steer ourselves a decade from now? So, just look at \TEX\ and \CONTEXT\ in the same way. A system from the nineties in the previous century differs from one three decades later. Demands differ, input differs, resources change, editing and processing moves on, and so on. Manuals, although still being written are seldom read from cover to cover because online searching replaced them. And who buys books about programming? So \LUAMETATEX, while still being \TEX\ also moves on, as do the way we do our low level coding. This makes sense because the original \TEX\ ecosystem was not made with a huge and complex macro package in mind, that just happened. An author was supposed to make a style for each document. An often used argument for using another macro package over \CONTEXT\ was that the later evolved and other macro packages would work the same forever and not change from the perspective of the user. In retrospect those arguments were somewhat strange because the world, computers, users etc.\ do change. Standards come and go, as do software politics and preferences. In many aspects the \TEX\ community is not different from other large software projects, operating system wars, library devotees, programming language addicts, paradigm shifts. But, don't worry, if you don't like \LUAMETATEX\ and its new primitives, just forget about them. The other engines will be there forever and are a safe bet, although \LUATEX\ already stirred up the pot I guess. But keep in mind that new features in the latest greatest \CONTEXT\ version will more and more rely on \LUAMETATEX\ being used; after all that is where it's made for. And this manual might help understand its users why, where and how the low level code differs between \MKII, \MKIV\ and \LMTX. Can we expect more new primitives than the ones introduced here? Given the amount of time I spent on experimenting and considering what made sense and what not, the answer probably is \quotation {no}, or at least \quotation {not that much}. As in the past no user ever requested the kind of primitives that were added, I don't expect users to come up with requests in the future either. Of course, those more closely related to \CONTEXT\ development look at it from the other end. Because it's there where the low level action really is, demands might still evolve. Basically there are wo areas where the engine can evolve: the programming part and the rendering. In this manual we focus on the programming and writing the manual sort of influences how details get filled in. Rendering in more complex because there heuristics and usage plays a more dominant role. Good examples are the math, par and page builder. They were extended and features were added over time but improved rendering came later. Not all extensions are critical, some are there (and got added) in order to write more readable code but there is only so much one can do in that area. Occasionally a feature pops up that is a side effect of a challenge. No matter what gets added it might not affect complexity too much and definitely not impact performance significantly! Hans Hagen \crlf Hasselt NL \stopsubject \popoverloadmode \startluacode local match = string.match local find = string.match function document.CheckCompleteness() local primitives = token.getprimitives() local luametatex = { } local indexed = { } local everything = { } for i=1,#primitives do local prim = primitives[i] local name = prim[3] if prim[4] == 4 then if find(name,"U") or find(name,"math") then -- ignore luametatex[name] = nil everything[name] = false else luametatex[name] = false end else everything[name] = true end end local function collect(index) if index then local data = index.entries for i=1,#data do local name = match(data[i].list[1][1],"\\tex%s*{(.-)}") or "" if luametatex[name] == false then luametatex[name] = true end indexed[name] = true everything[name] = nil end end end collect(structures.registers.collected and structures.registers.collected.index) context.startsubject { title = "To be checked primitives (new)" } context.blank() context.startcolumns { n = 2 } for k, v in table.sortedhash(luametatex) do if not v then context.dontleavehmode() context.type(k) context.crlf() end end context.stopcolumns() context.page() context.stopsubject() everything[""] = nil everything[" "] = nil context.startsubject { title = "To be checked primitives (math)" } context.blank() context.startcolumns { n = 2 } for k, v in table.sortedhash(everything) do if not v then context.dontleavehmode() context.type(k) context.crlf() end end context.stopcolumns() context.page() context.stopsubject() context.startsubject { title = "To be checked primitives (old)" } context.blank() context.startcolumns { n = 2 } for k, v in table.sortedhash(everything) do if v then context.dontleavehmode() context.type(k) context.crlf() end end context.stopcolumns() context.page() context.stopsubject() context.startsubject { title = "Indexed primitives" } context.blank() context.startcolumns { n = 2 } for k, v in table.sortedhash(indexed) do context.dontleavehmode() if luametatex[k] == true then context("\\color[darkgreen]{\\tttf %s}",k) elseif luametatex[k] == false then context("\\color[darkred]{\\tttf %s}",k) else context("{\\tttf %s}",k) end context.crlf() end context.stopcolumns() context.page() context.stopsubject() end \stopluacode \startmode[atpragma] \startluacode context.page() document.CheckCompleteness() \stopluacode % Run \type {s-system-syntax.mkxl} for a complete overview of the \LUAMETATEX\ % primitives. \stopmode \stopbodymatter \stoptext % disk and math options: orphaned