%D \module %D [ file=math-ini, %D version=2008.01.02, %D title=\CONTEXT\ Math Macros, %D subtitle=Initializations, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. \writestatus{loading}{ConTeXt Math Macros / Initializations} %D This module provides namespaces for math fonts, thereby permitting mixed usage of %D math fonts. Although not strictly needed, we also provide a family name mapping %D mechanism as used in the (original) AMS math definition files, but here these %D names can recursively be remapped and if needed, dynamically be changed. We've %D tried to minimize the number of definition commands and use plain \TEX\ %D definitions as fallback. We've tried to follow a couple of conventions from plain %D and AMS math in order to achieve backward compatinility. We also kept an eye on %D future usage of these modules in the perspective of MathML and unicode fonts. %D There is a subtle issue with grouping: the \type {\begingroup} method will not %D restore a changed mathstyle so best avoid that one. However, there are cases where %D we really need to use such grouping. % Weird, these fail, maybe amp is solved in a later state from char noads (needs a % fix in luatex): % % $\char"26$ % $\a$ % $\string&$ % mathop applied to characters centers it vertically \unprotect %D We move these definitions into the format: % test [[\char948 \cldcontext{utf.char(948)}]] % test $[[\char948 \cldcontext{utf.char(948)}]]$ \registerctxluafile{math-ini}{1.001} \registerctxluafile{math-dim}{1.001} \registerctxluafile{math-act}{1.001} \registerctxluafile{math-ext}{1.001} \registerctxluafile{math-vfu}{1.001} \registerctxluafile{math-ttv}{1.001} \registerctxluafile{math-map}{1.001} \registerctxluafile{math-ren}{1.001} \registerctxluafile{math-noa}{1.001} \registerctxluafile{math-tag}{1.001} \registerctxluafile{math-fbk}{1.001} \registerctxluafile{math-dir}{1.001} %D A few compatibility helpers: \def\Umathbotaccent{\Umathaccent \s!bottom } \def\Umathaccents {\Umathaccent \s!both } %D The attributes that we will use: \definesystemattribute[mathalphabet] [public] \definesystemattribute[mathsize] [public] \definesystemattribute[mathpunctuation][public] \definesystemattribute[mathgreek] [public] % will become generic \definesystemattribute[mathalternate] [public] \definesystemattribute[mathrendering] [public] \definesystemattribute[mathcategory] [public] \definesystemattribute[mathmode] [public] \definesystemattribute[mathitalics] [public] \definesystemattribute[mathbidi] [public] \definesystemattribute[displaymath] [public] \appendtoks \attribute\mathmodeattribute\plusone \to \everydisplay \appendtoks \attribute\mathmodeattribute\plusone \to \everybeforedisplayformula \appendtoksonce \attribute\displaymathattribute\plusone \to \everybeforedisplayformula \setnewconstant\defaultmathfamily \zerocount % 255 \unexpanded\def\resetmathattributes{\ctxcommand{resetmathattributes()}} % \unexpanded\def\rawmathcharacter#1% slow but only for tracing % {\begingroup % \ifmmode % \resetmathattributes\Uchar#1% % \else % \startimath\resetmathattributes\Uchar#1\stopimath % \fi % \endgroup} \unexpanded\def\rawmathematics#1% slow but only for tracing {\begingroup \ifmmode \resetmathattributes#1% \else \startimath\resetmathattributes#1\stopimath \fi \endgroup} %D Some measures (maybe spac-mth): % \def\mathskipsmall {\mskip\thinmuskip} % \def\mathskipmedium{\mskip\medmuskip} % \def\mathskipbig {\mskip\thickmuskip} %D \macros %D {setupmathematics} %D %D Configuration for integrals. (If needed we can speed this up and make it %D installable; no processaction is needed then). \installcorenamespace{mathematics} \installswitchcommandhandler \??mathematics {mathematics} \??mathematics \unexpanded\def\startmathematics % no grouping, if ever then also an optional second {\doifnextoptionalcselse\math_mathematics_start_yes\math_mathematics_start_nop} \unexpanded\def\math_mathematics_start_yes[#1]% {\pushmacro\currentmathematics \edef\currentmathematics{#1}% check for valid \the\everyswitchmathematics} \unexpanded\def\math_mathematics_start_nop {\pushmacro\currentmathematics \let\currentmathematics\empty \the\everyswitchmathematics} \unexpanded\def\stopmathematics {\popmacro\currentmathematics \the\everyswitchmathematics} \definemathematics[\v!default] % not needed, but nicer when nesting back to normal % Normally this is applied to only one character. % % $ABC$ $\cal ABC$ $\mathaltcal ABC$ % todo: only in mmode % these commands are semi-public but should not be used directly (lua names wil change) \unexpanded\def\math_set_attribute #1#2{\ifmmode\ctxcommand{setmathattribute("#1","#2")}\fi} \unexpanded\def\math_set_alphabet #1{\ifmmode\ctxcommand{setmathalphabet("#1")}\fi} \unexpanded\def\math_set_font_style #1{\ifmmode\ctxcommand{setmathstyle("#1")}\fi} \unexpanded\def\math_set_font_alternate#1{\ifmmode\ctxcommand{setmathalternate(\number\defaultmathfamily,"#1")}\fi} \installcorenamespace{mathstylealternate} % might become a setuphandler \unexpanded\def\math_set_font_style_alterternate#1% {\ifcsname\??mathstylealternate\fontclass:#1\endcsname \expandafter\math_set_font_alternate\csname\??mathstylealternate\fontclass:#1\endcsname \else\ifcsname\??mathstylealternate#1\endcsname \expandafter\math_set_font_alternate\csname\??mathstylealternate#1\endcsname \fi\fi} \unexpanded\def\setupmathrendering % the name might change {\dodoubleargument\math_setup_rendering} \def\math_setup_rendering[#1][#2]% {\ifsecondargument \getparameters[\??mathstylealternate#1:][#2]% \else \getparameters[\??mathstylealternate][#1]% \fi} \unexpanded\def\mathaltcal{\math_set_font_alternate{cal}\cal} % ss01 in xits \let\setmathattribute \math_set_attribute \let\setmathalphabet \math_set_alphabet \let\setmathfontstyle \math_set_font_style \let\setmathfontalternate \math_set_font_alternate \let\setmathfontstylealterternate\math_set_font_style_alterternate \let\mathalternate \math_set_font_alternate % obsolete \unexpanded\def\mathupright {\math_set_attribute\s!regular\s!tf\math_set_font_style_alterternate\s!tf} \unexpanded\def\mathdefault {\math_set_attribute\s!regular\s!it\math_set_font_style_alterternate\s!it} \unexpanded\def\mathscript {\math_set_alphabet \s!script \math_set_font_style_alterternate\s!script} \unexpanded\def\mathfraktur {\math_set_alphabet \s!fraktur \math_set_font_style_alterternate\s!fraktur} \unexpanded\def\mathblackboard{\math_set_alphabet \s!blackboard \math_set_font_style_alterternate\s!blackboard} \unexpanded\def\mathrm {\math_set_attribute\s!rm\s!tf \math_set_font_style_alterternate\s!tf} \unexpanded\def\mathss {\math_set_attribute\s!ss\s!tf \math_set_font_style_alterternate\s!tf} \unexpanded\def\mathtt {\math_set_attribute\s!tt\s!tf \math_set_font_style_alterternate\s!tf} \unexpanded\def\mathtf {\math_set_font_style\s!tf \math_set_font_style_alterternate\s!tf} \unexpanded\def\mathsl {\math_set_font_style\s!it \math_set_font_style_alterternate\s!it} % no sl \unexpanded\def\mathit {\math_set_font_style\s!it \math_set_font_style_alterternate\s!it} \unexpanded\def\mathbf {\math_set_font_style\s!bf \math_set_font_style_alterternate\s!bf} \unexpanded\def\mathbs {\math_set_font_style\s!bi \math_set_font_style_alterternate\s!bi} % no sl \unexpanded\def\mathbi {\math_set_font_style\s!bi \math_set_font_style_alterternate\s!bi} \let\tfmath\mathtf % maybe a grouped command \let\slmath\mathsl \let\itmath\mathit \let\bfmath\mathbf \let\bsmath\mathbs \let\bimath\mathbi \let\Bbb\mathblackboard \unexpanded\def\frak {\ifmmode\expandafter\mathfraktur \fi} \unexpanded\def\cal {\ifmmode\expandafter\mathscript \fi} \unexpanded\def\bbd {\ifmmode\expandafter\mathblackboard\fi} \unexpanded\def\blackboard{\ifmmode\expandafter\mathblackboard\fi} \unexpanded\def\fraktur {\ifmmode\expandafter\mathfraktur \fi} \unexpanded\def\gothic {\ifmmode\expandafter\mathfraktur \fi} \unexpanded\def\mathcal #1{{\mathscript #1}} % for AMS compatibility \unexpanded\def\mathfrak#1{{\mathfraktur #1}} % for AMS compatibility \unexpanded\def\mathbb #1{{\mathblackboard#1}} % for AMS compatibility \let\normaltf\tf \unexpanded\def\tf{\ifmmode\mathtf\else\normaltf\fi} \let\normalbf\bf \unexpanded\def\bf{\ifmmode\mathbf\else\normalbf\fi} \let\normalit\it \unexpanded\def\it{\ifmmode\mathit\else\normalit\fi} \let\normalsl\sl \unexpanded\def\sl{\ifmmode\mathsl\else\normalsl\fi} \let\normalbi\bi \unexpanded\def\bi{\ifmmode\mathbi\else\normalbi\fi} \let\normalbs\bs \unexpanded\def\bs{\ifmmode\mathbs\else\normalbs\fi} \let\normalrm\rm \unexpanded\def\rm{\ifmmode\mathrm\else\normalrm\fi} \let\normalss\ss \unexpanded\def\ss{\ifmmode\mathss\else\normalss\fi} \let\normaltt\tt \unexpanded\def\tt{\ifmmode\mathtt\else\normaltt\fi} \ifdefined\mr \else \let\mr\relax \fi \ifdefined\mb \else \let\mb\relax \fi % 1: $\setmathattribute{ss}{bf}3$ % 2: $\setmathattribute{ss}{bf}\setmathfontstylealterternate{bf}3$ % 3: $\setmathattribute{ss}{bf}\setmathfontstyle{bf}3$ % 4: $\setmathattribute{ss}{bf}\setmathfontstyle{bf}\setmathfontstylealterternate{bf}3$ % 5: $e=mc^2 \quad \mb e=mc^2$ \prependtoks \mathdefault \to \everymathematics %D We could set the rendering attribute at the \LUA\ end but as there can be many %D small math snippets we keep track of the state at the \TEX\ end (mapping is %D export safe). %D %D \starttyping %D \startformula %D \reals {\mathbf R} \utfchar{"0211D} \utfchar{"1D411} %D \stopformula %D %D \setupmathematics %D [symbolset=blackboard-to-bold] %D %D \startformula %D \reals {\mathbf R} \utfchar{"0211D} \utfchar{"1D411} %D \stopformula %D \stoptyping \newcount\c_math_renderings_attribute \appendtoks \c_math_renderings_attribute\ctxcommand{mathrenderset("\mathematicsparameter\c!symbolset")}\relax \to \everysetupmathematics % only in mathematics \appendtoks \ifcase\c_math_renderings_attribute\else \attribute\mathrenderingattribute\c_math_renderings_attribute \fi \to \everymathematics \setupmathematics [\c!symbolset=] %D \macros %D {boldsymbol} %D %D To be done. \let\mathboldsymbol\relax % yet unsupported, will be \unexpanded\def\boldsymbol {\mathortext\mathboldsymbol\bold} %D Helpers: \def\utfmathclass #1{\ctxcommand{utfmathclass (\!!bs#1\!!es)}} \def\utfmathstretch#1{\ctxcommand{utfmathstretch(\!!bs#1\!!es)}} \def\utfmathcommand#1{\ctxcommand{utfmathcommand(\!!bs#1\!!es)}} \def\utfmathfiller #1{\ctxcommand{utfmathfiller (\!!bs#1\!!es)}} \def\utfmathclassfiltered #1#2{\ctxcommand{utfmathclass (\!!bs#1\!!es,nil,"#2")}} \def\utfmathcommandfiltered#1#2{\ctxcommand{utfmathcommand(\!!bs#1\!!es,nil,"#2")}} \def\utfmathcommandabove #1{\ctxcommand{utfmathcommandabove (\!!bs#1\!!es)}} \def\utfmathcommandbelow #1{\ctxcommand{utfmathcommandbelow (\!!bs#1\!!es)}} \def\utfmathcommandfiller#1{\ctxcommand{utfmathcommandfiller(\!!bs#1\!!es)}} \unexpanded\def\doifelseutfmathaccent #1{\ctxcommand{doifelseutfmathaccent(\!!bs#1\!!es)}} \unexpanded\def\doifelseutfmathaccentfiltered#1#2{\ctxcommand{doifelseutfmathaccent(\!!bs#1\!!es,"#2")}} \unexpanded\def\doifelseutfmathabove #1{\ctxcommand{doifelseutfmathabove(\!!bs#1\!!es)}} \unexpanded\def\doifelseutfmathbelow #1{\ctxcommand{doifelseutfmathbelow(\!!bs#1\!!es)}} \unexpanded\def\doifelseutfmathfiller #1{\ctxcommand{doifelseutfmathfiller(\!!bs#1\!!es)}} %D Not used that much: \installcorenamespace{mathcodecommand} \unexpanded\def\mathlimop#1{\mathop{#1}} %no \limits \unexpanded\def\mathbox #1{\dontleavehmode\hbox\Ustartmath\mathsurround\zeropoint#1\Ustopmath} \unexpanded\def\mathnolop#1{\mathop{#1}\nolimits} \let\mathnothing\firstofoneunexpanded \let\mathalpha \firstofoneunexpanded \setnewconstant\mathordcode \zerocount \letvalue{\??mathcodecommand ord}\mathord \setnewconstant\mathopcode \plusone \letvalue{\??mathcodecommand op}\mathop \setnewconstant\mathbincode \plustwo \letvalue{\??mathcodecommand bin}\mathbin \setnewconstant\mathrelcode \plusthree \letvalue{\??mathcodecommand rel}\mathrel \setnewconstant\mathopencode \plusfour \letvalue{\??mathcodecommand open}\mathopen \setnewconstant\mathclosecode \plusfive \letvalue{\??mathcodecommand close}\mathclose \setnewconstant\mathpunctcode \plussix \letvalue{\??mathcodecommand punct}\mathpunct \setnewconstant\mathalphacode \plusseven \letvalue{\??mathcodecommand alpha}\mathalpha \setnewconstant\mathinnercode \zerocount \letvalue{\??mathcodecommand inner}\mathinner \setnewconstant\mathnothingcode \zerocount \letvalue{\??mathcodecommand nothing}\mathnothing \setnewconstant\mathlimopcode \plusone \letvalue{\??mathcodecommand limop}\mathlimop \setnewconstant\mathnolopcode \plusone \letvalue{\??mathcodecommand nolop}\mathnolop \setnewconstant\mathboxcode \zerocount \letvalue{\??mathcodecommand box}\mathbox \setnewconstant\mathchoicecode \zerocount %letvalue{\??mathcodecommand choice}\mathnothing \setnewconstant\mathaccentcode \pluseight \setnewconstant\mathradicalcode \plusnine \def\mathcodenumber #1{\the\csname math#1code\endcsname} \unexpanded\def\mathcodecommand#1{\csname\??mathcodecommand#1\endcsname} % \startlines % $\mathopnolimits{\rm d}x$ % $\mathopnolimits{\kern\zeropoint \rm d}x$ % $\mathcodecommand{nolop}{\rm d}x$ % $\mathcodecommand{nolop}{\kern\zeropoint\rm d}x$ % \blank % $\mathcodecommand{nolop}{\mr d}x$ % $\mathcodecommand{nolop}{\kern\zeropoint\mr d}x$ % $\mathop{\kern\zeropoint\mr d}x$ % $\mathopnolimits{\kern\zeropoint d}x$ % \stoplines \installcorenamespace{mathcommand} \unexpanded\def\definemathcommand {\dotripleempty\math_define_command} \def\math_define_command[#1][#2][#3]#4% command class args meaning {\ifthirdargument \edef\nofmathcommandarguments{#3}% \ifx\nofmathcommandarguments\v!one \setuvalue{\??mathcommand#1}##1{\mathcodecommand{#2}{#4{##1}}}% \else\ifx\nofmathcommandarguments\v!two \setuvalue{\??mathcommand#1}##1##2{\mathcodecommand{#2}{#4{##1}{##2}}}% \else \setuvalue{\??mathcommand#1}{\mathcodecommand{#2}{#4}}% \fi\fi \else\ifsecondargument \setuvalue{\??mathcommand#1}{\mathcodecommand{#2}{#4}}% \else \setuvalue{\??mathcommand#1}{\mathcodecommand{nothing}{#4}}% \fi\fi \letcsnamecsname\csname#1\endcsname\csname\??mathcommand#1\endcsname} \unexpanded\def\mathcommand#1% {\csname\??mathcommand#1\endcsname} %D Let's define a few comands here: %definemathcommand [mathstrut] {\vphantom{(}} %definemathcommand [joinrel] {\mathrel{\mkern-3mu}} \definemathcommand [joinrel] [rel] {\mkern-3mu} \chardef\c_math_strut"28 \unexpanded\def\math_strut_htdp#1% {\s!height\fontcharht#1\c_math_strut \s!depth \fontchardp#1\c_math_strut} \unexpanded\def\math_strut_normal {\vrule \normalexpanded{\math_strut_htdp{\mathstylefont\normalmathstyle}}% \s!width \zeropoint \relax} \unexpanded\def\math_strut_visual {\hskip-.01\emwidth \vrule \normalexpanded{\math_strut_htdp{\mathstylefont\normalmathstyle}}% \s!width .02\emwidth \relax \hskip-.01\emwidth} \unexpanded\def\showmathstruts % let's not overload \nath_strut_normal {\let\math_strut\math_strut_visual} \let\math_strut\math_strut_normal % \unexpanded\def\mathstrut{\mathcodecommand{nothing}{\math_strut}} \definemathcommand [mathstrut] {\math_strut} %D We could have a arg variant \unknown\ but not now. \unexpanded\def\mathopwithlimits#1#2{\mathop{#1{#2}}\limits} \unexpanded\def\stackrel #1#2{\mathrel{\mathop{#2}\limits^{#1}}} %D Moved from font-ini.mkiv: %D %D \macros %D {mf,mbox,enablembox,mathop} %D %D Todo: \unexpanded\def\mf {\csname\fontalternative\endcsname} \let\normalmathop\mathop \unexpanded\def\mathop {\normalmathop \bgroup \let\rm\mf \let\nexttoken=} % this one too: \letvalue{\??mathcodecommand op}\mathop ? \unexpanded\def\normalmbox {\normalhbox\bgroup\mf \dowithnextboxcs\math_mbox_finish\normalhbox} \def\math_mbox_finish {\flushnextbox \egroup} \unexpanded\def\mbox % we cannot add \dontleavehmode ... else no \setbox0\mbox possible {\ifmmode\normalmbox\else\normalhbox\fi} \unexpanded\def\enablembox {\appendtoks\math_enable_mbox\to \everymathematics} {\everymathematics\expandafter{\the\everymathematics\math_enable_mbox}} \def\math_enable_mbox {\ifdefined\normalhbox\else\let\normalhbox\hbox\fi % ? \let\hbox\mbox} \unexpanded\def\snappedmath#1% sort of \struttedbox {\dontleavehmode \begingroup \setbox\scratchbox\hbox\bgroup \startimath#1\stopimath \egroup \ht\scratchbox\strutht \dp\scratchbox\strutdp \box\scratchbox \endgroup} %D The next hack is needed needed for sine, cosine etc. \let\mathfunction\firstofoneunexpanded \let\math_tags_function \firstofoneunexpanded \let\math_tags_functionlabeltext\mathlabeltext \let\math_tags_mo\firstofoneunexpanded \let\math_tags_mi\firstofoneunexpanded \unexpanded\def\math_tags_mn#1{\begingroup\mathupright#1\endgroup} \unexpanded\def\math_tags_ms#1{\begingroup\mathupright#1\endgroup} \unexpanded\def\mfunction #1{{\mathupright\math_tags_function{#1}}} \unexpanded\def\mfunctionlabeltext#1{{\mathupright\math_tags_functionlabeltext{#1}}} % Once this is stable we can store the number at the tex end which is % faster. Functions getnumbers >= 1000. \expanded\def\math_tags_mathfunction_indeed #1{\ctxcommand{taggedmathfunction("#1",false,\ifconditional\c_apply_function true\else false\fi)}} \expanded\def\math_tags_mathfunctionlabeltext_indeed#1{\ctxcommand{taggedmathfunction("#1",true ,\ifconditional\c_apply_function true\else false\fi)}} \expanded\def\math_tags_mo_indeed#1{\begingroup \attribute\mathcategoryattribute\plusone #1\endgroup} \expanded\def\math_tags_mi_indeed#1{\begingroup \attribute\mathcategoryattribute\plustwo #1\endgroup} \expanded\def\math_tags_mn_indeed#1{\begingroup\mathupright\attribute\mathcategoryattribute\plusthree#1\endgroup} \expanded\def\math_tags_ms_indeed#1{\begingroup\mathupright\attribute\mathcategoryattribute\plusfour #1\endgroup} \newconditional\c_apply_function \unexpanded\def\math_tags_apply#1#2% {\begingroup \settrue\c_apply_function #1% \endgroup \begingroup % todo: auto () #2% \endgroup} \appendtoks \let\math_tags_function \math_tags_mathfunction_indeed \let\math_tags_functionlabeltext\math_tags_mathfunctionlabeltext_indeed \let\math_tags_mo \math_tags_mo_indeed \let\math_tags_mi \math_tags_mi_indeed \let\math_tags_mn \math_tags_mn_indeed \let\math_tags_ms \math_tags_ms_indeed \to \everyenableelements \appendtoks \let\mo \math_tags_mo \let\mi \math_tags_mi \let\mn \math_tags_mn \let\ms \math_tags_ms \let\apply\math_tags_apply \to\everymathematics % \def\mlimitsfunction #1{\mathlimopcomm{{\mr#1}} % \def\mnolimitsfunction#1{\mathnolopcomm{{\mr#1}} %D Taco posted this solution as response to a mail by Olivier, so let's integrate %D it here. \def\currentmscaledstyle{rm} % will be plugged into the typeface text=ss option \unexpanded\def\math_function_style_opnolimits #1{\mathop{\mscaledtext{#1}}\nolimits} \unexpanded\def\math_function_style_mfunction #1{\mscaledtext{\math_tags_function{#1}}} \unexpanded\def\math_function_style_mfunctionlabeltext#1{\mscaledtext{\math_tags_functionlabeltext{#1}}} \unexpanded\def\setmathfunctionstyle#1% rm ss tt (can be made faster if needed) {\doifsomething{#1} {\def\currentmscaledstyle{#1}% \let\mathopnolimits \math_function_style_opnolimits \let\mfunction \math_function_style_mfunction \let\mfunctionlabeltext\math_function_style_mfunctionlabeltext}} \unexpanded\def\mscaledtext#1% {\mathchoice {\hbox{\csname\currentmscaledstyle\endcsname\tf #1}} {\hbox{\csname\currentmscaledstyle\endcsname\tf #1}} {\hbox{\csname\currentmscaledstyle\endcsname\tfx #1}} {\hbox{\csname\currentmscaledstyle\endcsname\tfxx#1}}} %D We can force the way functions are typeset by manipulating the text option: %D %D \starttyping %D \definetypeface[iwona][ss][sans][iwona][default][encoding=texnansi] %D \definetypeface[iwona][mm][math][iwona][default][encoding=texnansi,text=ss] %D \stoptyping %D %D This hooks into the math handler with: % no longer supported this way, has to be done with \setupmathematics % % \appendtoks % \setmathfunctionstyle\currentmathtextstyle % \to \everybodyfont %D Usage: %D %D \starttyping %D \setmathfunctionstyle\fontstyle % or {rm} or {ss} or .. %D \rm test $\sin{(x^{\sin(x^{\sin(x)})})}$ test %D \ss test $\sin{(x^{\sin(x^{\sin(x)})})}$ test %D \tt test $\sin{(x^{\sin(x^{\sin(x)})})}$ test %D \stoptyping %D \macros %D {nonknuthmode, donknuthmode} %D %D The underscore is frequently used in manuals but unfortunately \TEX\ prefers %D it to be a math specific character. And since computer modern fonts didn't %D have an underscore, one had to use commands to fake one. Nowadays we do %D have underscores in latin modern, and since all other fonts have them, we %D decided to get away from the restriction to use the underscore character in %D text mode. %D %D \starttyping %D \def\test#1{#1} %D %D \nonknuthmode $x_2$ x_2 \test{$x_2$} \test{x_2} %D %D \donknuthmode $x_2$ x_2 \test{$x_2$} \test{x_2} %D \stoptyping %D %D The result is as expected: the first line typesets ok, while the second %D one triggers an error message. \setnewconstant\activemathcharcode "8000 \newtoks\activatedmathcharacters \unexpanded\def\activatemathcharacter#1% {\appendtoks \global\mathcode#1=\activemathcharcode \to \activatedmathcharacters} \def\activatemathcharacters {\the\activatedmathcharacters} % beware, not runtime, so has to happen at format generation \activatemathcharacter\circumflexasciicode \activatemathcharacter\underscoreasciicode \activatemathcharacter\ampersandasciicode % \activatemathcharacter\primeasciicode % not used: % % \mathcode\spaceasciicode\activemathcharcode % % not used: % % \bgroup % \catcode\underscoreasciicode\activecatcode % \doglobal\appendtoks % \mathcode\underscoreasciicode\activemathcharcode % \let_\activemathunderscore % \to \everymathematics % \egroup % Here follows some plain legacy: primes. % % The \let\prime\math_prime_indeed might become an obsolete as we have \doubleprime % and \tripleprime and collapsing can nicely handle the script then. % % Collapsing to 0x2033 and 0x2034 happens elsewhere. % % \switchtobodyfont[modern] % \switchtobodyfont[cambria] % \switchtobodyfont[xits] % \switchtobodyfont[minion] % \setupbodyfont[dejavu] % % \startbuffer % \def\SampleLine#1{% % \NC#1 % \NC\switchtobodyfont[#1]$f^2$ % 1 % \NC\switchtobodyfont[#1]$f\prime^2$ % 2 % \NC\switchtobodyfont[#1]$f\prime\prime^2$ % 3 % \NC\switchtobodyfont[#1]$f\prime\prime\prime^2$ % 4 % \NC\switchtobodyfont[#1]$f{\prime}^2$ % 5 % \NC\switchtobodyfont[#1]$f{\prime\prime}^2$ % 6 % \NC\switchtobodyfont[#1]$f{\prime\prime\prime}^2$ % 7 % \NC\switchtobodyfont[#1]$f'(x)$ % 8 % \NC\switchtobodyfont[#1]$f''(x)$ % 9 % \NC\switchtobodyfont[#1]$f'''(x)$ % 10 % \NC\NR % } % % \starttabulate[|Tl|Tc|Tc|Tc|Tc|Tc|Tc|Tc|Tc|Tc|Tc|] % \NC\NC1\NC2\NC3\NC4\NC5\NC6\NC7\NC8\NC9\NC10\NC\NR % \SampleLine{modern} % \SampleLine{cambria} % \SampleLine{xits} % \SampleLine{minion} % \stoptabulate % \stopbuffer % % \typebuffer \getbuffer % most math fonts have messed up primes, just test this: $\prime^{\prime^{\prime}}$ { \catcode\circumflexasciicode\othercatcode \global\let\othercircumflextoken ^ } { \catcode\circumflexasciicode\superscriptcatcode \global\let\superscriptcircumflextoken^ } \ifdefined \prime \else \Umathchardef\prime "0 "0 "2032 \fi % \let\math_prime_indeed_normal\prime % % \appendtoks % \let\math_prime_indeed_normal\prime % gets defined later % \let\mathfontprime\prime % for tracing % \let\prime\math_prime_indeed % so this is needed % \to \everydump % % \unexpanded\def\math_prime_indeed % {\iffontchar\textfont\zerocount"FE325\relax % ^\bgroup % \expandafter\math_prime_indeed_virtual % virtual mess (using funny signal) % \else % % \expandafter\math_prime_indeed_normal % gets collapsed % \expandafter\math_prime_indeed_crapped % gets collapsed % \fi} % % \def\math_prime_indeed_crapped % {{^{\math_prime_indeed_normal}}} % % % \let\prime\math_prime_indeed % % \def\math_prime_indeed_virtual % {\math_prime_indeed_normal % \futurelet\nexttoken\math_prime_indeed_choice} % % \installcorenamespace{mathprime} % % \def\math_prime_indeed_choice % {\csname\??mathprime % \ifx '\nexttoken a\else % \ifx \math_prime_indeed_normal\nexttoken a\else % \ifx \prime\nexttoken a\else % \ifx\superscriptcircumflextoken\nexttoken b\else % \ifx\othercircumflextoken \nexttoken b\else % c\fi\fi\fi\fi\fi % \endcsname} % % \setvalue{\??mathprime a}#1{\math_prime_indeed_virtual} % \setvalue{\??mathprime b}#1#2{#2\egroup} % \setvalue{\??mathprime c}{\egroup} % % \let\activemathprime\math_prime_indeed % % \bgroup % % \catcode\primeasciicode\activecatcode % % \global\everymathematics\expandafter{\the\everymathematics\let'\math_prime_indeed} % todo: do this at the lua end % % \egroup \bgroup \catcode\underscoreasciicode\activecatcode \catcode\circumflexasciicode\activecatcode \catcode\ampersandasciicode \activecatcode \doglobal \appendtoks \let _\normalsubscript \let ^\normalsuperscript \let &\normalmathaligntab % use \def when it's \aligntab \to \everymathematics \egroup \newtoks\everydonknuthmode \newtoks\everynonknuthmode \newconditional \knuthmode \let\nonknuthmode\relax % no longer needed in MkIV \let\donknuthmode\relax % no longer needed in MkIV % \def\nonknuthmode % {\pushcatcodetable % \setcatcodetable\ctxcatcodes % \the\everynonknuthmode % \let\nonknuthmode\relax % \popcatcodetable} % % \def\donknuthmode % {\pushcatcodetable % \setcatcodetable\ctxcatcodes % \the\everydonknuthmode % \popcatcodetable} % % \bgroup % % \catcode\underscoreasciicode\activecatcode % \catcode\circumflexasciicode\activecatcode % \catcode\ampersandasciicode \activecatcode % % \global \everynonknuthmode {\appendtoks % \let_\normalsubscript % \let^\normalsuperscript % \let&\normalmathaligntab % use \def when it's \aligntab % \to \everymathematics} % % \egroup % % \appendtoks % \setfalse\knuthmode % \catcode\underscoreasciicode\othercatcode % \catcode\circumflexasciicode\othercatcode % \catcode\ampersandasciicode \othercatcode % \to \everynonknuthmode % % \appendtoks % \settrue\knuthmode % \catcode\underscoreasciicode\subscriptcatcode % \catcode\circumflexasciicode\superscriptcatcode % \catcode\ampersandasciicode \alignmentcatcode % \to \everydonknuthmode % % \appendtoks % \startextendcatcodetable\ctxcatcodes % \catcode\underscoreasciicode\othercatcode % \catcode\circumflexasciicode\othercatcode % \catcode\ampersandasciicode \othercatcode % \stopextendcatcodetable % \to \everynonknuthmode % % \appendtoks % \startextendcatcodetable\ctxcatcodes % \catcode\underscoreasciicode\subscriptcatcode % \catcode\circumflexasciicode\superscriptcatcode % \catcode\ampersandasciicode \alignmentcatcode % \stopextendcatcodetable % \to \everydonknuthmode %D Even more drastic (this code will move as nonknuthmode is default now) % \unexpanded\def\enableasciimode % {\ctxlua{resolvers.macros.enablecomment()}% % \glet\enableasciimode\relax} % % \unexpanded\def\asciimode % {\catcodetable\txtcatcodes % \enableasciimode % \nonknuthmode} % % \unexpanded\def\startasciimode % {\pushcatcodetable % \catcodetable\txtcatcodes % \enableasciimode % \nonknuthmode} % % \unexpanded\def\stopasciimode % {\popcatcodetable % \ifconditional\knuthmode\else\donknuthmode\fi} \unexpanded\def\enableasciimode {\ctxlua{resolvers.macros.enablecomment()}% \glet\enableasciimode\relax} \unexpanded\def\asciimode {\catcodetable\txtcatcodes \enableasciimode} \unexpanded\def\startasciimode {\pushcatcodetable \catcodetable\txtcatcodes \enableasciimode} \unexpanded\def\stopasciimode {\popcatcodetable} %D Needed for unicode: \def\nulloperator{\mathortext{\mathop{\emptyhbox}}{\emptyhbox}} %D Memory saver: \appendtoks \ifx\currentmathematics\empty \doifelse{\mathematicsparameter\c!compact}\v!yes\enabledirectives\disabledirectives[math.virtual.optional]% \fi \to \everysetupmathematics \setupmathematics [\c!compact=no] % \enabletrackers[typesetters.directions.math] %D Right||to||left typesetting in math is supported by the \type {align} parameter %D with as option the \type {bidi} parameter. Of course support for special symbols %D like square roots depends on the font as well. We probably need to mirror a few %D more characters. %D %D \startbuffer %D \removeunwantedspaces %D \m{ ( 1 = 1) }\quad %D \m{ (123 = 123) }\quad %D \m{ a ( 1 = 1) b }\quad %D \m{ a (123 = 123) b }\quad %D \m{ x = 123 y + (1 / \sqrt {x}) } %D \stopbuffer %D %D \typebuffer %D %D \starttabulate[|T|T||] %D \HL %D \NC align \NC bidi \NC \NC \NR %D \HL %D \NC l2r \NC no \NC \setupmathematics[bidi=no] \getbuffer \NC \NR %D \NC l2r \NC yes \NC \setupmathematics[bidi=yes] \getbuffer \NC \NR %D \NC r2l \NC no \NC \setupmathematics[align=r2l,bidi=no] \getbuffer \NC \NR %D \NC r2l \NC yes \NC \setupmathematics[align=r2l,bidi=yes] \getbuffer \NC \NR %D \HL %D \stoptabulate \newconditional\c_math_right_to_left \appendtoks \doifelse{\mathematicsparameter\c!align}{r2l}\settrue\setfalse\c_math_right_to_left \to \everyswitchmathematics \unexpanded\def\math_basics_synchronize_direction {\mathdir T\ifconditional\c_math_right_to_left R\else L\fi T} \appendtoks \math_basics_synchronize_direction %to \everymathematics % comes too late and I'm not in the mood for a mixed mode kludge now (should be a property of beginmath nodes and passed to callbacks) \to \everyswitchmathematics % experimental (needed for an article) \installcorenamespace {mathbidi} \newcount\c_math_bidi \setvalue{\??mathbidi\v!no }{\ctxcommand{setmathdirection(0)}\c_math_bidi\attributeunsetvalue} \setvalue{\??mathbidi\v!yes}{\ctxcommand{setmathdirection(1)}\c_math_bidi\plusone} \appendtoks \edef\p_bidi{\mathematicsparameter\c!bidi}% \csname\??mathbidi\ifcsname\??mathbidi\p_bidi\endcsname\p_bidi\else\v!no\fi\endcsname \to \everysetupmathematics \appendtoks \attribute\mathbidiattribute\ifconditional\c_math_right_to_left\c_math_bidi\else\attributeunsetvalue\fi \to \everyswitchmathematics %D Delayed: greek. %D %D \starttyping %D \usetypescript[cambria]\setupbodyfont[cambria] %D \startTEXpage %D $\alpha \mathgreekupright \alpha \mathgreekitalic \alpha$ %D \stopTEXpage %D \stoptyping % [lc uc] normal (upright) = 2, italic = 3, none = 0/1 % We can move the setting to the lua end and use abstract numbers instead % if funny ones here. \installcorenamespace{mathgreek} \newconstant\c_math_greek_attribute \setvalue{\??mathgreek\v!none }{1} \setvalue{\??mathgreek\v!normal}{2} \setvalue{\??mathgreek\v!italic}{3} \appendtoks \edef\p_sygreek{\mathematicsparameter\s!sygreek}% \edef\p_lcgreek{\mathematicsparameter\s!lcgreek}% \edef\p_ucgreek{\mathematicsparameter\s!ucgreek}% \c_math_greek_attribute"% hex digits \csname\??mathgreek\ifcsname\??mathgreek\p_sygreek\endcsname\p_sygreek\else\v!none\fi\endcsname \csname\??mathgreek\ifcsname\??mathgreek\p_lcgreek\endcsname\p_lcgreek\else\v!none\fi\endcsname \csname\??mathgreek\ifcsname\??mathgreek\p_ucgreek\endcsname\p_ucgreek\else\v!none\fi\endcsname \relax \ifcase\c_math_greek_attribute \c_math_greek_attribute\attributeunsetvalue \fi \to \everyswitchmathematics % only used local \unexpanded\def\mathgreekupright{\attribute\mathgreekattribute"222\relax} \unexpanded\def\mathgreekitalic {\attribute\mathgreekattribute"333\relax} \unexpanded\def\mathgreekdefault{\attribute\mathgreekattribute"000\relax} \let\mathgreeknormal\mathgreekupright \let\mathgreeknone \mathgreekdefault \appendtoks \attribute\mathgreekattribute\c_math_greek_attribute \to \everymathematics \setupmathematics [\s!sygreek=\v!normal, \s!lcgreek=\v!italic, \s!ucgreek=\v!normal] % was: none %D Math italics (experiment) % we need keys \installcorenamespace{mathitalics} \setnewconstant\c_math_italics_attribute\attributeunsetvalue \letvalue{\??mathitalics 1}\plusone % fontitalics \letvalue{\??mathitalics 2}\plustwo % fontdata \letvalue{\??mathitalics 3}\plusthree % quad based \letvalue{\??mathitalics 4}\plusfour % combination of 1 and 3 \letvalue{\??mathitalics\v!none}\attributeunsetvalue \def\math_italics_initialize {\ifnum\c_math_italics_attribute=\attributeunsetvalue \else \ctxcommand{setmathitalics()}% one time \global\let\math_italics_initialize\relax \fi} \appendtoks \edef\p_italics{\mathematicsparameter\s!italics}% \c_math_italics_attribute\csname\??mathitalics \ifcsname\??mathitalics\p_italics\endcsname\p_italics\else\v!none\fi \endcsname\relax % \math_italics_initialize \to \everyswitchmathematics % only in mathematics \appendtoks \math_italics_initialize \attribute\mathitalicsattribute\c_math_italics_attribute \to \everymathematics \setupmathematics [\s!italics=3] % for the moment only this one makes sense .. still experimental % looks nicer but can generate bogus csnames % % \setvalue{\??mathitalics1}{\math_italics_initialize\c_math_italics_attribute\plusone } % fontitalics % \setvalue{\??mathitalics2}{\math_italics_initialize\c_math_italics_attribute\plustwo } % fontdata % \setvalue{\??mathitalics3}{\math_italics_initialize\c_math_italics_attribute\plusthree} % quad based % \setvalue{\??mathitalics4}{\math_italics_initialize\c_math_italics_attribute\plusfour } % combination of 1 and 3 % % \appendtoks % \c_math_italics_attribute\attributeunsetvalue % \csname\??mathitalics\mathematicsparameter\s!italics\endcsname % \to \everyswitchmathematics % only in mathematics %D \macros %D {enablemathpunctuation,disablemathpunctuation} %D %D \startbuffer %D \enablemathpunctuation$(1,2) (1, 2) (1{,}2) \hbox{foo, not bar}$ %D \stopbuffer %D %D \typebuffer %D %D \blank{\getbuffer}\blank % \newconditional\automathpunctuation % % \unexpanded\def\enablemathpunctuation {\settrue \automathpunctuation} % \unexpanded\def\disablemathpunctuation{\setfalse\automathpunctuation} % % \appendtoks % \doifelse{\mathematicsparameter\v!autopunctuation}\v!yes\settrue\setfalse\automathpunctuation % \to \everyswitchmathematics % % \setupmathematics % [\v!autopunctuation=\v!no] % % \def\math_punctuation_next{\ifx\nexttoken\blankspace\char\zerocount\fi} % % \unexpanded\def\math_punctuation_comma {\textcomma \futurelet\nexttoken\math_punctuation_next} % \unexpanded\def\math_punctuation_period{\textperiod\futurelet\nexttoken\math_punctuation_next} % % \setnewconstant\c_math_comma "002C % \setnewconstant\c_math_period "002E % \setnewconstant\c_math_special"8000 % % \bgroup % % \catcode\c_math_comma \activecatcode % \catcode\c_math_period\activecatcode % % \unexpanded\gdef\math_punctuation_initialize_indeed % {\mathcode\c_math_comma \c_math_special % \mathcode\c_math_period\c_math_special % \let,\math_punctuation_comma % \let.\math_punctuation_period % \attribute\mathpunctuationattribute\plustwo} % % \unexpanded\gdef\math_punctuation_initialize_yes % {\attribute\mathpunctuationattribute\plustwo} % % \unexpanded\gdef\math_punctuation_initialize_nop % {\attribute\mathpunctuationattribute\plusone} % % \egroup % % \appendtoks % \ifconditional\automathpunctuation % \math_punctuation_initialize_indeed % \math_punctuation_initialize_yes % \let\enablemathpunctuation \math_punctuation_initialize_yes % \let\disablemathpunctuation\math_punctuation_initialize_nop % \fi % \to \everymathematics % Later I will look again into a \LUATEX\ based solution. It only makes sense % to delegate to \LUA\ when we have more variants and need analysis (experimental % trickery removed for a while). \def\math_punctuation_comma_next {\ifx\nexttoken\blankspace \mathpunct{\textcomma }\else\mathord{\textcomma }\fi} \def\math_punctuation_period_next{\ifx\nexttoken\blankspace \mathpunct{\textperiod}\else\mathord{\textperiod}\fi} \unexpanded\def\math_punctuation_nop_comma {\mathpunct{\textcomma}} \unexpanded\def\math_punctuation_all_comma {\futurelet\nexttoken\math_punctuation_comma_next} \let\math_punctuation_yes_comma \math_punctuation_all_comma \unexpanded\def\math_punctuation_nop_period{\mathord{\textperiod}} \unexpanded\def\math_punctuation_all_period{\futurelet\nexttoken\math_punctuation_period_next} \let\math_punctuation_yes_period\math_punctuation_nop_period \setnewconstant\c_math_comma "002C \setnewconstant\c_math_period "002E \setnewconstant\c_math_special"8000 \installcorenamespace {mathautopunctuation} \bgroup \catcode\c_math_comma \activecatcode \catcode\c_math_period\activecatcode \setgvalue{\??mathautopunctuation\v!no}% {\let,\math_punctuation_nop_comma \let.\math_punctuation_nop_period} \setgvalue{\??mathautopunctuation\v!yes}% {\let,\math_punctuation_yes_comma \let.\math_punctuation_yes_period} \setgvalue{\??mathautopunctuation\v!all}% {\let,\math_punctuation_all_comma \let.\math_punctuation_all_period} \egroup % \appendtoks % \global\mathcode\c_math_comma \c_math_special % \global\mathcode\c_math_period\c_math_special % \to \everyjob % \activatemathcharacter\c_math_comma % \activatemathcharacter\c_math_period \appendtoks \mathcode\c_math_comma \c_math_special \mathcode\c_math_period\c_math_special \csname\??mathautopunctuation\mathematicsparameter\v!autopunctuation\endcsname \to \everymathematics \appendtoks \ifcsname\??mathautopunctuation\mathematicsparameter\v!autopunctuation\endcsname \else \letmathematicsparameter\v!autopunctuation\v!no \fi \to \everysetupmathematics \def\enablemathpunctuation {\csname\??mathautopunctuation\v!no \endcsname} \def\disablemathpunctuation{\csname\??mathautopunctuation\v!yes\endcsname} \setupmathematics [\v!autopunctuation=\v!no] % no | yes | all %D \macros %D {mathstyle} %D %D If one want to be sure that something is typeset in the appropriate style, \type %D {\mathstyle} can be used: %D %D \starttyping %D \mathstyle{something} %D \stoptyping % \def\mathstyle#1% % {\mathchoice % {\displaystyle #1}% % {\textstyle #1}% % {\scriptstyle #1}% % {\scriptscriptstyle#1}} % % We now have a primitive operation for this. As the macro overloads a new % primitive introduced in \LUATEX, we need to use \type {\normalmathstyle} when we % consult the current math style. % % \let \mathstyle \Ustack % spoils cramped % % \let \mathstyle \firstofoneargument % % 0 = display % 1 = crampeddisplay % 2 = text % 3 = crampedtext % 4 = script % 5 = crampedscript % 6 = scriptscript % 7 = crampedscriptscript \def\uncramped#1% {{\ifcase\normalmathstyle \or \displaystyle \or \or \textstyle \or \or \scriptstyle \or \or \scriptscriptstyle \fi #1}} \def\cramped#1% {{\ifcase\normalmathstyle \crampeddisplaystyle \or \or % 0 -> 1 \crampedtextstyle \or \or % 2 -> 3 \crampedscriptstyle \or \or % 4 -> 5 \crampedscriptscriptstyle \fi % 6 -> 7 #1}} \def\triggermathstyle#1% #1 is number {\ifcase\numexpr#1\relax \displaystyle \or \crampeddisplaystyle \or \textstyle \or \crampedtextstyle \or \scriptstyle \or \crampedscriptstyle \or \scriptscriptstyle \or \crampedscriptscriptstyle \else % error \fi} \def\mathstylefont#1% #1 is number (\normalmathstyle) {\ifcase\numexpr#1\relax \textfont \or \textfont \or \textfont \or \textfont \or \scriptfont \or \scriptfont \or \scriptscriptfont \or \scriptscriptfont \else \textfont \fi\zerocount} % hm, can ie other value as well \def\mathsmallstylefont#1% #1 is number (\normalmathstyle) {\ifcase\numexpr#1\relax \scriptfont \or \scriptfont \or \scriptfont \or \scriptfont \or \scriptscriptfont \or \scriptscriptfont \or \scriptscriptfont \or \scriptscriptfont \else \scriptfont \fi\zerocount} % hm, can ie other value as well \def\mathstyleface#1% #1 is number (\normalmathstyle) {\ifcase\numexpr#1\relax \textface \or \textface \or \textface \or \textface \or \scriptface \or \scriptface \or \scriptscriptface \or \scriptscriptface \else \textface \fi} \def\mathsmallstyleface#1% #1 is number (\normalmathstyle) {\ifcase\numexpr#1\relax \scriptface \or \scriptface \or \scriptface \or \scriptface \or \scriptscriptface \or \scriptscriptface \or \scriptscriptface \or \scriptscriptface \else \scriptface \fi} \def\mathstylecommand#1#2#3% {\ifcase\numexpr\normalmathstyle\relax \expandafter#1\or \expandafter#1\or \expandafter#1\or \expandafter#1\or \expandafter#2\or \expandafter#2\or \expandafter#3\or \expandafter#3\else \expandafter#1\fi} \unexpanded\def\verbosemathstyle#1% #1 is number (\normalmathstyle) {{\normalexpanded{\relax\darkgray\ttxx[\number#1:\ifcase\numexpr#1\relax display\or % 0 crampeddisplay\or % 1 text\or % 2 crampedtext\or % 3 script\or % 4 crampedscript\or % 5 scriptscript\or % 6 crampedscriptscript\else % 7 unknown\fi]}}} \unexpanded\def\showmathstyle{\verbosemathstyle\normalmathstyle} %D A plain inheritance: \def\mathpalette#1#2% {\mathchoice {#1\displaystyle {#2}}% {#1\textstyle {#2}}% {#1\scriptstyle {#2}}% {#1\scriptscriptstyle{#2}}} %D Often we can use: %D %D \startbuffer %D $x^{\mathstylehbox{x^{\mathstylehbox{x}}}}$ %D \stopbuffer %D %D \typebuffer \getbuffer % to be tested: {#1} but it could have side effects \unexpanded\def\mathstylehbox#1% sensitive for: a \over b => {a\over b} or \frac{a}{b} {\normalexpanded{\hbox\bgroup \startimath\triggermathstyle\normalmathstyle}\mathsurround\zeropoint#1\stopimath\egroup} \unexpanded\def\mathstylevbox#1% {\normalexpanded{\vbox\bgroup \startimath\triggermathstyle\normalmathstyle}\mathsurround\zeropoint#1\stopimath\egroup} \unexpanded\def\mathstylevcenter#1% {\normalexpanded{\vcenter\bgroup \startimath\triggermathstyle\normalmathstyle}\mathsurround\zeropoint#1\stopimath\egroup} \unexpanded\def\mathstylevcenteredhbox#1% {\normalexpanded{\vcenter\bgroup\hbox\bgroup \startimath\triggermathstyle\normalmathstyle}\mathsurround\zeropoint#1\stopimath\egroup\egroup} \unexpanded\def\mathstylevcenteredvbox#1% {\normalexpanded{\vcenter\bgroup\vbox\bgroup \startimath\triggermathstyle\normalmathstyle}\mathsurround\zeropoint#1\stopimath\egroup\egroup} \unexpanded\def\setmathsmalltextbox#1#2#% {\normalizebodyfontsize\m_math_text_choice_face{\mathsmallstyleface\normalmathstyle}% \setbox#1#2\bgroup \font_basics_switchtobodyfont\m_math_text_choice_face \let\next} \unexpanded\def\setmathtextbox#1#2#% {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}% \setbox#1#2\bgroup \font_basics_switchtobodyfont\m_math_text_choice_face \let\next} %D Here is the new mechanism ... it might replace some of the above but we will do %D that stepwise. Keep in mind that cramped only affects superscripts and even then, %D only when in a smaller size than normal. %D %D \def\TestMe#1% %D {\NC \ttbf #1 %D \NC \ruledhbox{$\setupmathstyle[#1]x + x_j^2 + x_i^{e^2} + \frac{1}{x}$} %D \NC \ruledhbox{$\setupmathstyle[#1,small]x + x_j^2 + x_i^{e^2} + \frac{1}{x}$} %D \NC \NR} %D %D \starttabulate[|l|r|l|] %D \HL %D \NC \NC \NC \ttbf ...,small \NC \NR %D \HL %D \TestMe{text} \TestMe{text,cramped} %D \TestMe{script} \TestMe{script,cramped} %D \TestMe{scriptscript} \TestMe{scriptscript,cramped} %D \TestMe{display} \TestMe{display,cramped} %D \HL %D \stoptabulate \def\triggerdisplaystyle {\ifcase\normalmathstyle\relax \displaystyle \or \crampeddisplaystyle \or \displaystyle \or \crampeddisplaystyle \or \displaystyle \or \crampeddisplaystyle \or \displaystyle \or \crampeddisplaystyle \or \fi} \def\triggertextstyle {\ifcase\normalmathstyle\relax \textstyle \or \crampedtextstyle \or \textstyle \or \crampedtextstyle \or \textstyle \or \crampedtextstyle \or \textstyle \or \crampedtextstyle \else \fi} \def\triggerscriptstyle {\ifcase\normalmathstyle\relax \scriptstyle \or \crampedscriptstyle \or \scriptstyle \or \crampedscriptstyle \or \scriptstyle \or \crampedscriptstyle \or \scriptstyle \or \crampedscriptstyle \or \fi} \def\triggerscriptscriptstyle {\ifcase\normalmathstyle\relax \scriptscriptstyle \or \crampedscriptscriptstyle \or \scriptscriptstyle \or \crampedscriptscriptstyle \or \scriptscriptstyle \or \crampedscriptscriptstyle \or \scriptscriptstyle \or \crampedscriptscriptstyle \or \fi} \def\triggeruncrampedstyle {\ifcase\normalmathstyle\relax \or \displaystyle \or \or \textstyle \or \or \scriptstyle \or \or \scriptscriptstyle \fi} \def\triggercrampedstyle {\ifcase\normalmathstyle\relax \crampeddisplaystyle \or \or \crampedtextstyle \or \or \crampedscriptstyle \or \or \crampedscriptscriptstyle \fi} \def\triggersmallstyle {\ifcase\normalmathstyle\relax \scriptstyle \or \crampedscriptstyle \or \scriptstyle \or \crampedscriptstyle \or \scriptscriptstyle \or \crampedscriptscriptstyle \or \scriptscriptstyle \or \crampedscriptscriptstyle \or \fi} \def\triggeruncrampedsmallstyle {\ifcase\normalmathstyle\relax \scriptstyle \or \scriptstyle \or \scriptstyle \or \scriptstyle \or \scriptscriptstyle \or \scriptscriptstyle \or \scriptscriptstyle \or \scriptscriptstyle \or \fi} \def\triggercrampedsmallstyle {\ifcase\normalmathstyle\relax \crampedscriptstyle \or \crampedscriptstyle \or \crampedscriptstyle \or \crampedscriptstyle \or \crampedscriptscriptstyle \or \crampedscriptscriptstyle \or \crampedscriptscriptstyle \or \crampedscriptscriptstyle \or \fi} \def\triggerbigstyle {\ifcase\normalmathstyle\relax \displaystyle \or \crampeddisplaystyle \or \textstyle \or \crampedtextstyle \or \textstyle \or \crampedtextstyle \or \scriptstyle \or \crampedscriptstyle \or \fi} \def\triggeruncrampedbigstyle {\ifcase\normalmathstyle\relax \displaystyle \or \displaystyle \or \textstyle \or \textstyle \or \textstyle \or \textstyle \or \scriptstyle \or \scriptstyle \or \fi} \def\triggercrampedbigstyle {\ifcase\normalmathstyle\relax \crampeddisplaystyle \or \crampeddisplaystyle \or \crampedtextstyle \or \crampedtextstyle \or \crampedtextstyle \or \crampedtextstyle \or \crampedscriptstyle \or \crampedscriptstyle \or \fi} \installcorenamespace{mathstylecommand} \installcorenamespace{mathstylecache} \newconstant\c_math_styles_state_style \newconstant\c_math_styles_state_cramped \newconstant\c_math_styles_state_size \def\math_style_add_to_cache_choice {% \ifcase\c_math_styles_state_size \ifcase\c_math_styles_state_style \ifcase\c_math_styles_state_cramped \relax \or \noexpand\triggeruncrampedstyle \or \noexpand\triggercrampedstyle \fi \or\ifcase\c_math_styles_state_cramped \noexpand\triggerdisplaystyle \or \displaystyle \or \crampeddisplaystyle \fi \or\ifcase\c_math_styles_state_cramped \noexpand\triggertextstyle \or \textstyle \or \crampedtextstyle \fi \or\ifcase\c_math_styles_state_cramped \noexpand\triggerscriptstyle \or \scriptstyle \or \crampedscriptstyle \fi \or\ifcase\c_math_styles_state_cramped \noexpand\triggerscriptscriptstyle \or \scriptscriptstyle \or \crampedscriptscriptstyle \fi \fi \or % small \ifcase\c_math_styles_state_style \ifcase\c_math_styles_state_cramped \noexpand\triggersmallstyle \or \noexpand\triggeruncrampedsmallstyle \or \noexpand\triggercrampedsmallstyle \fi \or\ifcase\c_math_styles_state_cramped \noexpand\triggerscriptstyle \or \scriptstyle \or \crampedscriptstyle \fi \or\ifcase\c_math_styles_state_cramped \noexpand\triggerscriptstyle \or \scriptstyle \or \crampedscriptstyle \fi \or\ifcase\c_math_styles_state_cramped \noexpand\triggerscriptscriptstyle \or \scriptscriptstyle \or \crampedscriptscriptstyle \fi \or\ifcase\c_math_styles_state_cramped \noexpand\triggerscriptscriptstyle \or \scriptscriptstyle \or \crampedscriptscriptstyle \fi \fi \or % large \ifcase\c_math_styles_state_style \ifcase\c_math_styles_state_cramped \noexpand\triggerbigstyle \or \noexpand\triggeruncrampedbigstyle \or \noexpand\triggercrampedbigstyle \fi \or\ifcase\c_math_styles_state_cramped \noexpand\triggerdisplaystyle \or \displaystyle \or \crampeddisplaystyle \fi \or\ifcase\c_math_styles_state_cramped \noexpand\triggertextstyle \or \textstyle \or \crampedtextstyle \fi \or\ifcase\c_math_styles_state_cramped \noexpand\triggertextstyle \or \textstyle \or \crampedtextstyle \fi \or\ifcase\c_math_styles_state_cramped \noexpand\triggerscriptstyle \or \scriptstyle \or \crampedscriptstyle \fi \fi \fi } \unexpanded\def\math_style_set#1% {\edef\m_math_style_asked{#1}% \ifx\m_math_style_asked\empty \else \math_style_set_indeed \fi} \let\setmathstyle\math_style_set \def\installmathstyle#1#2% {\ifcsname\??mathstylecommand#1\endcsname \else \setvalue{\??mathstylecommand#1}{#2}% \fi} \def\math_style_collect#1% {\csname\??mathstylecommand#1\endcsname} \setvalue{\??mathstylecommand\s!display }{\c_math_styles_state_style \plusone} \setvalue{\??mathstylecommand\s!text }{\c_math_styles_state_style \plustwo} \setvalue{\??mathstylecommand\s!script }{\c_math_styles_state_style \plusthree} \setvalue{\??mathstylecommand\s!scriptscript}{\c_math_styles_state_style \plusfour} \setvalue{\??mathstylecommand\s!uncramped }{\c_math_styles_state_cramped\plusone} \setvalue{\??mathstylecommand\s!cramped }{\c_math_styles_state_cramped\plustwo} \setvalue{\??mathstylecommand\v!normal }{\c_math_styles_state_cramped\plusone} \setvalue{\??mathstylecommand\v!packed }{\c_math_styles_state_cramped\plustwo} \setvalue{\??mathstylecommand\v!small }{\c_math_styles_state_size \plusone} \setvalue{\??mathstylecommand\v!big }{\c_math_styles_state_size \plustwo} \unexpanded\def\setupmathstyle[#1]% {\edef\m_math_style_asked{#1}% \ifx\m_math_style_asked\empty \else \math_style_set_indeed \fi} \unexpanded\def\usemathstyleparameter#1% faster local variant {\edef\m_math_style_asked{#1\c!mathstyle}% \ifx\m_math_style_asked\empty \else \math_style_set_indeed \fi} %D \startbuffer %D \definemathstyle[mystyle][scriptscript] %D %D $text\startmathstyle[mystyle]scriptscript\stopmathstyle text$ %D \stopbuffer %D %D \typebuffer \blank \start \getbuffer \stop \blank \installcorenamespace {mathstyle} \unexpanded\def\definemathstyle {\dodoubleargument\math_style_define} \def\math_style_define[#1][#2]% {\c_math_styles_state_style \zerocount \c_math_styles_state_cramped\zerocount \c_math_styles_state_size \zerocount \rawprocesscommacommand[#2]\math_style_collect \expandafter\let\csname\??mathstyle#1\normalexpanded{\endcsname\math_style_add_to_cache_choice}} % \def\math_style_set_indeed % {\ifcsname\??mathstyle\m_math_style_asked\endcsname % \csname\??mathstyle\m_math_style_asked\endcsname % \else % \math_style_set_indeed_cached % \fi} % % \def\math_style_set_indeed_cached % {\ifcsname\??mathstylecache\m_math_style_asked\endcsname % % already in cache % \else % \math_style_add_to_cache % \fi % \csname\??mathstylecache\m_math_style_asked\endcsname} % % \def\math_style_add_to_cache % {\c_math_styles_state_style \zerocount % \c_math_styles_state_cramped\zerocount % \c_math_styles_state_size \zerocount % \rawprocesscommacommand[\m_math_style_asked]\math_style_collect % \global\expandafter\let\csname\??mathstylecache\m_math_style_asked\normalexpanded{\endcsname\math_style_add_to_cache_choice}} % % ugly but more efficient (as called often) \def\math_style_set_indeed {\csname\??mathstyle \ifcsname\??mathstyle\m_math_style_asked\endcsname \m_math_style_asked \else \??mathstyle \fi \endcsname} \setvalue{\??mathstyle\??mathstyle}% {\csname\??mathstylecache \ifcsname\??mathstylecache\m_math_style_asked\endcsname \m_math_style_asked \else \??mathstylecache \fi \endcsname} \setvalue{\??mathstylecache\??mathstylecache}% {\c_math_styles_state_style \zerocount \c_math_styles_state_cramped\zerocount \c_math_styles_state_size \zerocount \rawprocesscommacommand[\m_math_style_asked]\math_style_collect \global\expandafter\let\csname\??mathstylecache\m_math_style_asked\normalexpanded{\endcsname\math_style_add_to_cache_choice}% \csname\??mathstylecache\m_math_style_asked\endcsname} %D \startbuffer %D $x\begingroup\setupmathstyle[script]x\endgroup x$ %D $x{\setupmathstyle[script]x}x$ %D $x\startmathstyle[script]x\stopmathstyle x$ %D \stopbuffer %D %D \typebuffer \getbuffer \unexpanded\def\startmathstyle[#1]% {\edef\m_math_style_asked{#1}% \ifx\m_math_style_asked\empty \let\stopmathstyle\relax \else \bgroup \math_style_set_indeed \let\stopmathstyle\egroup \fi} \let\stopmathstyle\relax \unexpanded\def\startusemathstyleparameter#1% {\edef\m_math_style_asked{#1\c!mathstyle}% \ifx\m_math_style_asked\empty \let\stopusemathstyleparameter\relax \else \bgroup \math_style_set_indeed \let\stopusemathstyleparameter\egroup \fi} \let\stopusemathstyleparameter\relax %D Something similar can be used in the (re|)|definition of \type {\text}. This %D version is a variation on the one in the math module (see \type{m-math} and|/|or %D \type {m-newmat}). \unexpanded\def\mathtext {\mathortext\math_text_choice\hbox} % \def\math_text_choice#1% % {\mathchoice % {\math_text_choice_indeed\displaystyle\textface {#1}}% % {\math_text_choice_indeed\textstyle \textface {#1}}% % {\math_text_choice_indeed\textstyle \scriptface {#1}}% % {\math_text_choice_indeed\textstyle \scriptscriptface{#1}}} % % \def\math_text_choice_indeed#1#2#3% no \everymath ! % {\hbox{\everymath{#1}\switchtobodyfont[#2]#3}} % 15 sec % \let\m_math_text_choice_style\relax % % \def\math_text_choice#1% % {\edef\m_math_text_choice_style{\normalmathstyle}% % \hbox\bgroup % % \everymath{\triggermathstyle\m_math_text_choice_style}% % \normalizebodyfontsize\m_math_text_choice_style{\mathstylefont\m_math_text_choice_style}% % \font_basics_switchtobodyfont\m_math_text_choice_style % #1% % \egroup} \let\m_math_text_choice_face \relax % \def\math_text_choice#1% if needed we can get rid of the normalize (predo in font code) % {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}% % \hbox{\font_basics_switchtobodyfont\m_math_text_choice_face#1}} \def\math_text_choice% if needed we can get rid of the normalize (predo in font code) {\normalizebodyfontsize\m_math_text_choice_face{\mathstyleface\normalmathstyle}% %\showmathstyle \hbox\bgroup\font_basics_switchtobodyfont\m_math_text_choice_face\let\next} %D Safeguard against redefinitions: \appendtoks \let\_\normalunderscore % is textunderscore or fakeunderscore \to \everymathematics %D Because we may overload \type {\text} in other (structuring) macros, we say: \appendtoks \let\text\mathtext \to \everymathematics %D The next code is derived from plain \TEX. The names will change! \newcount\interdisplaylinepenalty \interdisplaylinepenalty\plushundred % Actually, not using an if saves one macro so there is no penalty % for splitting up this macro. % % \newif\ifdt@p % % \def\displ@y % {\global\dt@ptrue % \math_openup\displayopenupvalue % was \openup\jot % \everycr % {\noalign % {\ifdt@p % \global\dt@pfalse % \ifdim\prevdepth>-\thousandpoint % \vskip-\lineskiplimit % \vskip\normallineskiplimit % \fi % \else % \penalty\interdisplaylinepenalty % \fi}}} \newtoks\mathdisplayaligntweaks \appendtoks \resetdisplaymatheq % moved to here \to \mathdisplayaligntweaks \unexpanded\def\math_display_align_hack % I don't like the global, maybe we should push and pop {\global\let\math_display_align_hack_indeed\math_display_align_hack_remove_skip \math_openup\displayopenupvalue % was \math_openup\jot \everycr{\noalign{\math_display_align_hack_indeed}}} \def\math_display_align_hack_remove_skip {\ifdim\prevdepth>-\thousandpoint \vskip\dimexpr-\lineskiplimit+\normallineskiplimit\relax \fi \global\let\math_display_align_hack_indeed\math_display_align_hack_insert_penalty} \def\math_display_align_hack_insert_penalty {\penalty\interdisplaylinepenalty} \appendtoks \math_display_align_hack \to \mathdisplayaligntweaks %D Text in math: \unexpanded\def\mathortext {\ifmmode \expandafter\firstoftwoarguments \else \expandafter\secondoftwoarguments \fi} % \defineactivecharacter _ {\mathortext{_}{\_}} text_text $a^2$ % force text mode, will be overloaded later \ifdefined\text\else \let\text\hbox \fi \unexpanded\def\mathoptext#1{\mathop{\text{#1}}} % new: % \startsetups math:morespacing % \Umathordordspacing\textstyle 1mu plus .5mu minus .25mu\relax % \stopsetups % % \setupmathematics % [setups=math:morespacing] \appendtoks \edef\p_setups{\mathematicsparameter\c!setups}% \ifx\p_setups\empty\else \directsetup\p_setups \fi \to \everyswitchmathematics % new: \unexpanded\def\smallmathsymbol#1% {\mathematics{\mathbin{\normalexpanded{\raise.15\exheight\hbox{$\triggermathstyle{\the\numexpr\normalmathstyle+2\relax}#1$}}}}} % this should be a primitive: % \def\mathextensiblecode#1#2% % {\cldcontext{mathematics.extensiblecode(\number#1,\number#2)}} \def\mathextensiblecode#1#2{\ctxcommand{extensiblecode(\number#1,\number#2)}} \def\mathhorizontalcode#1#2{\ctxcommand{horizontalcode(\number#1,\number#2)}} \protect \endinput % % not used (yet) % % \newtoks \everystartimath % \newtoks \everystopimath % % \unexpanded\def\startimath{\Ustartmath\the\everystartimath} % \unexpanded\def\stopimath {\the\everystopimath\Ustopmath} % % \unexpanded\def\m% % {\relax % \ifmmode\expandafter\math_m_stay\else\expandafter\math_m_math\fi} % % \unexpanded\def\math_m_math#1% % {\startimath#1\stopimath} % % \let\math_m_stay\firstofoneargument