diff options
Diffstat (limited to 'tex/context/base/mkiv/math-ali.mkxl')
-rw-r--r-- | tex/context/base/mkiv/math-ali.mkxl | 1893 |
1 files changed, 1893 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/math-ali.mkxl b/tex/context/base/mkiv/math-ali.mkxl new file mode 100644 index 000000000..997ecd3d7 --- /dev/null +++ b/tex/context/base/mkiv/math-ali.mkxl @@ -0,0 +1,1893 @@ +%D \module +%D [ file=math-ali, +%D version=2008.10.20, +%D title=\CONTEXT\ Math Macros, +%D subtitle=Math Alignments, +%D author={Hans Hagen, Taco Hoekwater \& Aditya Mahajan}, +%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 / Math Alignments} + +\unprotect + +%D The code here has been moved from other files. Beware: the \MKII\ and \MKIV\ code +%D is not gathered in files with the same name. In the meantime this code has been +%D adapted to \MKIV\ but more is possible. The code is somewhat complicated by the +%D fact that alignments are tricky with rspect to tagging. + +% export: +% +% alignment : ok +% cases : +% matrix : ok +% substack : + +%D \macros +%D {definemathalignment, setupmathalignment, startmathalignment} +%D +%D Modules may provide additional alignment features. The following mechanisms are +%D provided by the core. + +\newtoks\t_math_align_a +\newtoks\t_math_align_b +\newtoks\t_math_align_c + +\newskip\d_math_eqalign_distance + +\protected\def\math_eqalign_distance + {\relax + \ifdim\d_math_eqalign_distance>\zeropoint + % \hskip\d_math_eqalign_distance + \tabskip\d_math_eqalign_distance + \fi + \mathalignmentparameter\c!separator + \relax} + +\def\displayopenupvalue{.25\bodyfontsize} + +\def\math_build_eqalign + {\scratchtoks\emptytoks + \d_math_eqalign_distance\mathalignmentparameter\c!distance\relax + \scratchcounterone\mathalignmentparameter\c!m + \scratchcountertwo\mathalignmentparameter\c!n + \etoksapp\scratchtoks{\the\t_math_align_a}% + \scratchcounter\plusone + \dorecurse{\numexpr\scratchcounterone*\scratchcountertwo-\plusone\relax} + {\ifnum\scratchcounter=\scratchcountertwo + \scratchcounter\plusone + \etoksapp\scratchtoks{\math_eqalign_distance}% + \else + \advance\scratchcounter\plusone + \fi + \etoksapp\scratchtoks{\the\t_math_align_b}}% + \etoksapp\scratchtoks{\the\t_math_align_c}} + +\def\math_math_in_eqalign#1% + {\startforceddisplaymath + \tabskip\zeropoint + \everycr\emptytoks + {{}#1{}}% + \stopforceddisplaymath} + +\def\math_text_in_eqalign#1% + {\startimath + \tabskip\zeropoint + \everycr\emptytoks + #1% + \stopimath} + +\def\eqalign#1% why no halign here, probably because of displaywidth + {\emptyhbox + \mskip\thinmuskip + \vcenter + {\math_openup\displayopenupvalue % was: \openup\jot + \mathsurround\zeropoint + \ialign{% + \strut + \hfil + \startforceddisplaymath{\alignmark\alignmark}\stopforceddisplaymath + \aligntab + \startforceddisplaymath{{}\alignmark\alignmark{}}\stopforceddisplaymath + \hfil\crcr + #1\crcr}% + }% + \mskip\thinmuskip} + +% preamble is scanned for tabskips so we need the span to prevent an error message + +\setnewconstant\eqalignmode\plusone + +% use zeroskipplusfill + +\def\math_prepare_r_eqalign_no + {\t_math_align_a + {\strut + \tabskip\zeropoint + \alignmark\alignmark % for picking up the number + \aligntab + \math_first_in_eqalign + \hfil + \math_left_of_eqalign + \span + \math_math_in_eqalign{\alignmark\alignmark}% + \math_right_of_eqalign + \tabskip\zeropoint}% + \t_math_align_b + {\aligntab + \math_next_in_eqalign + \math_left_of_eqalign + \span + \math_math_in_eqalign{\alignmark\alignmark}% + \math_right_of_eqalign + \tabskip\zeropoint}% + \ifnum\mathraggedstatus=\plusone + \t_math_align_c + {\hfil + \aligntab + \span + \math_text_in_eqalign{\alignmark\alignmark}% + \tabskip\zeropoint}% + \orelse\ifnum\mathraggedstatus=\plusthree + \t_math_align_c + {\hfil + \tabskip\zeropoint\s!plus 1\s!fill + \aligntab + \span + \math_text_in_eqalign{\alignmark\alignmark}% + \tabskip\zeropoint}% + \else + \t_math_align_c + {\hfil + \tabskip\centering + \aligntab + \span + \llap{\math_text_in_eqalign{\alignmark\alignmark}}% + \tabskip\zeropoint}% + \fi + \math_build_eqalign + \the\mathdisplayaligntweaks + \tabskip\centering} + +\def\math_prepare_l_eqalign_no % \checkeddisplaymath + {\t_math_align_a + {\strut + \tabskip\zeropoint + \alignmark\alignmark % for picking up the number + \aligntab + \math_first_in_eqalign + \hfil + \math_left_of_eqalign + \span + \math_math_in_eqalign{\alignmark\alignmark}% + \math_right_of_eqalign + \tabskip\zeropoint}% + \t_math_align_b + {\aligntab + \math_next_in_eqalign + \math_left_of_eqalign + \span + \math_math_in_eqalign{\alignmark\alignmark}% + \math_right_of_eqalign + \tabskip\zeropoint}% + \ifnum\mathraggedstatus=\plusone + \t_math_align_c + {\hfil + \aligntab + \kern-\displaywidth + \span + \rlap{\math_text_in_eqalign{\alignmark\alignmark}}% + \tabskip\displaywidth}% + \orelse\ifnum\mathraggedstatus=\plusthree + \t_math_align_c + {\hfil + \tabskip\zeropoint\s!plus 1\s!fill + \aligntab + \kern-\displaywidth + \span + \math_rlap{\math_text_in_eqalign{\alignmark\alignmark}}% + \tabskip\displaywidth}% + \else + \t_math_align_c + {\hfil + \tabskip\centering + \aligntab + \kern-\displaywidth + \span + \rlap{\math_text_in_eqalign{\alignmark\alignmark}}% + \tabskip\displaywidth}% + \fi + \math_build_eqalign + \the\mathdisplayaligntweaks + \tabskip\centering} + +\def\math_halign_checked + {\halign \ifcase\eqalignmode \or to \checkeddisplaywidth \fi} + +\def\math_both_eqalign_no_normal#1#2% + {\ifmmode + \the\mathdisplayaligntweaks + \vcenter\bgroup + \enforced\let\math_finish_eqalign_no\egroup + \else + \enforced\let\math_finish_eqalign_no\relax + \fi + #1% + \math_halign_checked\expandafter\bgroup\the\scratchtoks\crcr#2\crcr\egroup + \math_finish_eqalign_no} + +\installcorenamespace {mathalignlocation} + +\setvalue{\??mathalignlocation\v!top }{\let\math_alignment_halign_method\halign\tpack} +\setvalue{\??mathalignlocation\v!bottom}{\let\math_alignment_halign_method\halign\vpack} +\setvalue{\??mathalignlocation\v!center}{\let\math_alignment_halign_method\halign\vcenter} + +\def\math_both_eqalign_no_aligned#1% + {\let\math_alignment_halign_method\math_halign_checked + \ifmmode + \the\mathdisplayaligntweaks + \global\mathnumberstatus\plusone + \ifcase\mathraggedstatus + \def\math_finish_eqalign_no{\crcr\egroup}% + \else % we're in a mathbox + \ifcsname\??mathalignlocation\mathalignmentparameter\c!location\endcsname + \lastnamedcs % top|bottom|center as suggested by HM + \else + \vcenter + \fi + \bgroup + \def\math_finish_eqalign_no{\crcr\egroup\egroup}% + \fi + \fi + #1% + \math_alignment_halign_method\expandafter\bgroup\the\scratchtoks\crcr} + +\def\math_rlap#1% + {\setbox\scratchbox\hbox{#1}% + \ifdim\wd\scratchbox>\d_math_number_correction + \global\d_math_number_correction\wd\scratchbox + \fi + \box\scratchbox + \global\mathnumberstatus\plustwo} + +\def\math_handle_eqalign_no_r_normal {\math_both_eqalign_no_normal \math_prepare_r_eqalign_no} +\def\math_handle_eqalign_no_l_normal {\math_both_eqalign_no_normal \math_prepare_l_eqalign_no} +\def\math_handle_eqalign_no_r_aligned{\math_both_eqalign_no_aligned\math_prepare_r_eqalign_no} +\def\math_handle_eqalign_no_l_aligned{\math_both_eqalign_no_aligned\math_prepare_l_eqalign_no} +\def\math_finish_eqalign_no {\crcr\egroup} + +\let\reqalignno\relax +\let\leqalignno\relax +\let\eqalignno \relax + +%D Here we implement the user interface part. We start with basic math alignments: + +\newcount \c_math_eqalign_column +\newconditional\c_math_eqalign_first + +\newtoks \everymathalignment +\newtoks \everymathalignmentdone + +\permanent\tolerant\protected\def\math_alignment_NN[#1]#*[#2]% + {\aligntab + \strc_formulas_place_number_nested{#1}{#2}} + +\permanent\tolerant\protected\def\math_alignment_NR[#1]#*[#2]% + {\aligntab + \dostoptagged % finish cell + \strc_formulas_place_number_nested{#1}{#2}% + \math_number_right_of_eqalign + \global\settrue\c_math_eqalign_first + \crcr + \dostoptagged} % finish row + +\permanent\protected\def\math_alignment_NC + {\relax + \ifconditional\c_math_eqalign_first + \ifx\p_math_alignment_number\v!auto + \strc_formulas_place_number_nested{+}{}% + \fi + \global\setfalse\c_math_eqalign_first + \fi + \math_number_left_of_eqalign + \aligntab} + +\permanent\protected\def\math_alignment_EQ + {\NC=} + +\installmacrostack\NC % maybe more to shared table definitions +\installmacrostack\NN % maybe more to shared table definitions +\installmacrostack\EQ % maybe more to shared table definitions +\installmacrostack\NR % maybe more to shared table definitions +\installmacrostack\BC % maybe more to shared table definitions +\installmacrostack\EC % maybe more to shared table definitions + +\appendtoks + \push_macro_NC + \push_macro_NN + \push_macro_EQ + \push_macro_NR + \enforced\let\NC\math_alignment_NC + \enforced\let\NN\math_alignment_NN + \enforced\let\EQ\math_alignment_EQ + \enforced\let\NR\math_alignment_NR + \global\settrue\c_math_eqalign_first +\to \everymathalignment + +\appendtoks + \pop_macro_NR + \pop_macro_EQ + \pop_macro_NN + \pop_macro_NC +\to \everymathalignmentdone + +\let\math_alignment_snap_start\relax +\let\math_alignment_snap_stop \relax + +% % experimental: +% +% \def\math_alignment_snap_start +% {\ifgridsnapping +% \edef\p_math_alignment_grid{\mathalignmentparameter\c!grid}% +% \ifx\p_math_alignment_grid\v!no\else +% \snaptogrid[\p_math_alignment_grid]\vbox\bgroup +% \fi +% \fi} +% +% \def\math_alignment_snap_stop +% {\ifgridsnapping +% \ifx\p_math_alignment_grid\v!no\else +% \egroup +% \fi +% \fi} +% +% % doesn't work well, so: + +\let\math_alignment_snap_start\relax +\let\math_alignment_snap_stop \relax + +% end of experimental + +\newconditional\c_math_alignment_auto_number + +% \begingroup not permitted ($$...assignments...\halign... ).. check in luametatex + +\permanent\tolerant\protected\def\math_alignment_start[#1]#*[#2]% + {\edef\currentmathalignment{#1}% + \ifarguments\or\or + \setupmathalignment[#1][#2]% bad! ungrouped + \fi + \math_alignment_snap_start + \the\everymathalignment + \c_math_eqalign_column\zerocount + \edef\p_math_alignment_number{\mathalignmentparameter\c!number}% + \processcommacommand + [\mathalignmentparameter\c!align]% + {\advance\c_math_eqalign_column\plusone\math_eqalign_set_column}% takes argument + \global\c_math_eqalign_column\plusone + \dostarttagged\t!math\empty + \dostarttagged\t!mathtable\currentmathalignment + \numberedeqalign} + +\def\math_alignment_stop + {\math_finish_eqalign_no + \dostoptagged + \dostoptagged + \the\everymathalignmentdone + \math_alignment_snap_stop} + +\installcorenamespace{mathalignment} +\installcorenamespace{mathalignmentvariant} + +\installcommandhandler \??mathalignment {mathalignment} \??mathalignment + +\appendtoks + \setuevalue{\e!start\currentmathalignment}{\math_alignment_start[\currentmathalignment]}% + \setvalue {\e!stop \currentmathalignment}{\math_alignment_stop}% +\to \everydefinemathalignment + +\setupmathalignment + [\c!n=2, + \c!m=1, + \c!distance=\emwidth, + \c!grid=\v!math] + +\definemathalignment[align] % default case (this is what amstex users expect) +\definemathalignment[\v!mathalignment] % prefered case (this is cleaner, less clashing) + +% special case.. in case one mistypes .. + +\ifdefined \startalignment + + \let\align_math_normal_start\startalign + \let\align_math_normal_stop \stopalign + + \let\align_text_normal_start\startalignment + \let\align_text_normal_stop \stopalignment + + \permanent\overloaded\protected\def\startalign + {\ifmmode + \enforced\let\stopalign\align_math_normal_stop % cannot be an unexpanded def ... lookahead in align + \expandafter\align_math_normal_start + \orelse\ifinformula + \enforced\let\stopalign\align_math_normal_stop + \expandafter\align_math_normal_start + \else + \enforced\let\stopalign\align_text_normal_stop + \expandafter\align_text_normal_start + \fi} + + \overloaded\let\stopalign\relax + + \permanent\overloaded\protected\def\startalignment + {\ifmmode + \enforced\let\stopalignment\align_math_normal_stop % cannot be an unexpanded def ... lookahead in align + \expandafter\align_math_normal_start + \orelse\ifinformula + \enforced\let\stopalignment\align_math_normal_stop % cannot be an unexpanded def ... lookahead in align + \expandafter\align_math_normal_start + \else + \enforced\let\stopalignment\align_text_normal_stop + \expandafter\align_text_normal_start + \fi} + + \overloaded\let\stopalignment\relax + +\fi + +% + +\permanent\protected\def\numberedeqalign + {\doifelse{\formulaparameter\c!location}\v!left + \math_handle_eqalign_no_l_aligned + \math_handle_eqalign_no_r_aligned} + +\def\math_first_in_eqalign + {\global\c_math_eqalign_column\plusone + \dostarttagged\t!mathtablerow \empty + \dostarttagged\t!mathtablecell\empty} + +\def\math_next_in_eqalign + {\global\advance\c_math_eqalign_column\plusone + \dostoptagged % finish cell + \dostarttagged\t!mathtablecell\empty} + +\def\math_left_of_eqalign + {\ifcsname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname + \ifcase\lastnamedcs \or \relax \or \hfill \or \hfill \fi + \fi} + +\def\math_right_of_eqalign + {\ifcsname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname + \ifcase\lastnamedcs \or \hfill \or \relax \or \hfill \fi + \fi} + +\newconditional\c_math_alignment_local_number % not used but when true puts in front (todo) + +\def\math_number_right_of_eqalign + {\ifcase\wd\b_strc_formulas_number\else + \ifconditional\c_math_alignment_local_number + \ifcase\c_strc_math_number_location\or\or + \box\b_strc_formulas_number + \fi + \else + \box\b_strc_formulas_number + \fi + \fi} + +\def\math_number_left_of_eqalign + {\ifcase\wd\b_strc_formulas_number\else + \ifconditional\c_math_alignment_local_number + \ifcase\c_strc_math_number_location\or + \box\b_strc_formulas_number + \fi + \fi + \fi} + +% \def\math_eqalign_set_column#1% we could just add to the preamble (as with other alignments) +% {\expandafter\let\csname\??mathalignmentvariant\number\c_math_eqalign_column\expandafter\endcsname +% \csname\??mathalignmentvariant\ifcsname\??mathalignmentvariant#1\endcsname#1\else\v!normal\fi\endcsname} + +\def\math_eqalign_set_column#1% we could just add to the preamble (as with other alignments) + {\expandafter\chardef\csname\??mathalignmentvariant\number\c_math_eqalign_column\expandafter\expandafter\expandafter\endcsname + \ifcsname\??mathalignmentvariant#1\endcsname\lastnamedcs\else\zerocount\fi\relax} + +\letvalue{\??mathalignmentvariant\v!normal}\zerocount +\letvalue{\??mathalignmentvariant\v!left }\plusone +\letvalue{\??mathalignmentvariant\v!right }\plustwo +\letvalue{\??mathalignmentvariant\v!middle}\plusthree + +\permanent\protected\def\math_align_NR_generic[#1][#2]% + {\strc_formulas_place_number_nested{#1}{#2}\crcr} + +%D \starttyping +%D \placeformula[eqn0]\startformula \startalign[n=1] a\NR \stopalign \stopformula See \in[eqn0] +%D \placeformula[eqn1]\startformula \startalign[n=1] a\NR \stopalign \stopformula See \in[eqn1] +%D \placeformula \startformula \startalign[n=1] a\NR[eqn2] \stopalign \stopformula See \in[eqn2] +%D \placeformula[eqn3]\startformula \startalign[n=1] a\NR[+] \stopalign \stopformula See \in[eqn3] +%D \stoptyping + +%D \startbuffer +%D \placeformula \startformula \eqalignno { +%D a &= b & \formulanumber \cr +%D c &= d \cr +%D &= e \cr +%D &= f & \formulanumber +%D } \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D \placeformula \startformula \startalign +%D \NC a \EQ b \NR[+] +%D \NC c \EQ d \NR +%D \NC \EQ f \NR[for:demo-a-1] +%D \NC \EQ g \NR[for:demo-a-2][a] +%D \NC \EQ h \NR[for:demo-a-3][b] +%D \NC \EQ i \NR +%D \stopalign \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D \placeformula \startformula \startalign +%D \NC a \EQ b \NR[+] +%D \NC c \EQ d \NR +%D \NC \EQ f \NR +%D \NC \EQ g \NR +%D \NC \EQ h \NR +%D \NC \EQ i \NR[+] +%D \stopalign \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D \placeformula \startformula \startalign +%D \NC a \NC \eq b \NR[+] +%D \NC c \NC \neq d \NR +%D \NC \NC \neq f \NR[for:demo-b-1] +%D \NC \NC \geq g \NR[for:demo-b-2][a] +%D \NC \NC \leq h \NR[for:demo-b-3][b] +%D \NC \NC \neq i \NR +%D \stopalign \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D \placeformula \startformula \startalign[n=3,align={left,middle,right}] +%D \NC l \NC = \NC r \NR +%D \NC left \NC = \NC right \NR +%D \stopalign \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D \placeformula \startformula \startalign[n=3,align={right,middle,left}] +%D \NC l \NC = \NC r \NR +%D \NC left \NC = \NC right \NR +%D \stopalign \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D \placeformula \startformula \startalign[n=3,align={middle,middle,middle}] +%D \NC l \NC = \NC r \NR +%D \NC left \NC = \NC right \NR +%D \stopalign \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D \placeformula +%D \startformula +%D \startalign[n=3,align={middle,middle,middle}] +%D \NC a \NC = \NC b \NR[+] +%D \NC 2a \NC = \NC 2b \NR +%D \stopalign +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D \placeformula +%D \startformulas +%D \setupmathalignment[n=3,align={middle,middle,middle}]% +%D \startformula +%D \startalign +%D \NC a \NC = \NC b \NR[+] +%D \NC 2a \NC = \NC 2b \NR +%D \stopalign +%D \stopformula +%D \startformula +%D \startalign +%D \NC a \NC = \NC b \NR[+] +%D \NC 2a \NC = \NC 2b \NR +%D \stopalign +%D \stopformula +%D \stopformulas +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D \placeformula +%D \startformulas +%D \dorecurse{5}{\startformula +%D \startalign[n=3,align={middle,middle,middle}] +%D \NC a \NC = \NC b \NR[+] +%D \NC 2a \NC = \NC 2b \NR +%D \stopalign +%D \stopformula} +%D \stopformulas +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +%D \macros +%D {definemathcases, setupmathcases, startmathcases} +%D +%D Another wish \unknown + +\installcorenamespace{mathcases} + +\installcommandhandler \??mathcases {mathcases} \??mathcases + +\setupmathcases + [\c!distance=\emwidth, + \c!strut=\v!yes, % new + \c!numberdistance=2.5\emwidth, + \c!left={\left\{\mskip\thinmuskip}, + \c!right={\right.}] + +\appendtoks + \setuevalue{\e!start\currentmathcases}{\math_cases_start[\currentmathcases]}% + \setvalue {\e!stop \currentmathcases}{\math_cases_stop}% +\to \everydefinemathcases + +\permanent\protected\def\math_cases_NC_zero + {\math_cases_NC} + +\permanent\protected\def\math_cases_MC_zero + {\math_cases_NC + \ifmmode\else + \startimath + \enforced\let\math_cases_end_math\stopimath + \fi} + +\let\math_cases_end_math\relax + +\permanent\protected\def\math_cases_NR_zero + {\unskip + \math_cases_end_math + \aligntab + \global\enforced\let\math_cases_NC\math_cases_NC_first + \dodirectdoubleempty\math_cases_NR} + +\permanent\protected\def\math_cases_NC_first + {\global\enforced\let\math_cases_NC\math_cases_NC_second} + +\permanent\protected\def\math_cases_NC_second + {\math_cases_end_math\aligntab} + +\let\math_cases_NR\math_align_NR_generic + +\installmacrostack\math_cases_NC + +\permanent\tolerant\protected\def\math_cases_start[#1]#*[#2]% + {\begingroup + \edef\currentmathcases{#1}% + \ifarguments\or\or + \setupcurrentmathcases[#2]% + \fi + \edef\p_strut{\mathcasesparameter\c!strut}% + \ifx\p_strut\v!yes + \enforced\let\math_cases_strut\strut + \else + \enforced\let\math_cases_strut\relax + \fi + \mathcasesparameter\c!left + \vcenter\bgroup + \push_macro_math_cases_NC + \enforced\let\endmath\relax + \enforced\let\NC\math_cases_NC_zero + \enforced\let\MC\math_cases_MC_zero + \enforced\let\NR\math_cases_NR_zero + \global\enforced\let\math_cases_NC\math_cases_NC_first + \normalbaselines + \mathsurround\zeropoint + \everycr\emptytoks + \tabskip\zeropoint + \global\c_math_eqalign_column\plusone + \halign\bgroup + \startimath + \mathcasesparameter\c!style + \alignmark\alignmark + \stopimath + \hfil + \aligntab + \hskip\mathcasesparameter\c!distance\relax + \pop_macro_math_cases_NC + \math_cases_strut % looks better + \alignmark\alignmark + \hfil + \aligntab + \hskip\mathcasesparameter\c!numberdistance\relax + \let\formuladistance\!!zeropoint + \span\math_text_in_eqalign{\alignmark\alignmark}% + \crcr} % todo: number + +\def\math_cases_stop + {\crcr + \egroup + \popmacro\math_cases_NC + \egroup + \mathcasesparameter\c!right + \endgroup} + +\definemathcases[cases] +\definemathcases[\v!mathcases] + +%D \startbuffer +%D \placeformula \startformula \startcases +%D \NC 2 \NC $ y > 0 $ \NR +%D \NC 7 \NC $ x = 7 $ \NR[+] +%D \NC 4 \NC otherwise \NR +%D \stopcases \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D \placeformula \startformula x \startcases +%D \NC 2 \NC $ y > 0 $ \NR[+] +%D \NC 7 \NC $ x = 7 $ \NR +%D \NC 4 \NC otherwise \NR +%D \stopcases \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D \placeformula \startformula \startcases +%D \NC 2 \NC $ y > 0 $ \NR +%D \NC 7 \NC $ x = 7 $ \NR +%D \NC 4 \NC otherwise \NR +%D \stopcases \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D \placeformula \startformula x \startcases +%D \NC 2 \NC $ y > 0 $ \NR +%D \NC 7 \NC $ x = 7 $ \NR +%D \NC 4 \NC otherwise \NR +%D \stopcases \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +%D \macros +%D {definemathmatrix, setupmathmatrix, startmathmatrix} +%D +%D Yet another one \unknown. This time we implement the lot a bit +%D different which is a side effect of getting the tagging right. In +%D retrospect the main alignment could be done this way but \unknown + +\installcorenamespace{mathmatrix} + +\installcommandhandler \??mathmatrix {mathmatrix} \??mathmatrix + +\setupmathmatrix + [\c!distance=\emwidth, + \c!left=, + \c!right=, + \c!align=\v!middle] + +\appendtoks + \setuevalue{\e!start\currentmathmatrix}{\math_matrix_start[\currentmathmatrix]}% + \setvalue {\e!stop \currentmathmatrix}{\math_matrix_stop}% no u else lookahead problem +\to \everydefinemathmatrix + +\def\math_matrix_start_table + {\global\c_math_eqalign_column\zerocount + \dostarttagged\t!math\empty + \dostarttagged\t!mathtable\empty} + +\def\math_matrix_stop_table + {\dostoptagged + \dostoptagged} + +\def\math_matrix_start_row + {\noalign{\global\c_math_eqalign_column\zerocount}% + \dostarttagged\t!mathtablerow\empty} + +\def\math_matrix_stop_row + {\dostoptagged} + +\protected\def\math_matrix_start_cell + {\dostarttagged\t!mathtablecell\empty + \hss + \math_left_of_eqalign + \startimath + \math_matrix_set_style + \tabskip\zeropoint + \everycr\emptytoks} + +\protected\def\math_matrix_stop_cell + {\stopimath + \math_right_of_eqalign + \hss + \dostoptagged} + +% We could construct a preamble with alignment and such embedded but the number +% of matrices with many rows is normally so low that it doesn't pay of at all. + +\protected\def\math_matrix_distance + {\relax + \ifdim\d_math_eqalign_distance>\zeropoint + \hskip\d_math_eqalign_distance + \fi + \relax} + +\def\math_matrix_preamble + {\math_matrix_strut + \global\advance\c_math_eqalign_column\plusone + \math_matrix_start_cell + \alignmark\alignmark + \math_matrix_stop_cell + \aligntab + \aligntab + \math_matrix_distance + \global\advance\c_math_eqalign_column\plusone + \math_matrix_start_cell + \alignmark\alignmark + \math_matrix_stop_cell} + +\newconditional\c_math_matrix_first + +\permanent\protected\def\math_matrix_NR + {\aligntab\omit + \math_matrix_stop_row + \math_matrix_pickup + \crcr + \math_matrix_start_row} + +\permanent\protected\def\math_matrix_NC + {\ifconditional\c_math_matrix_first + \expandafter\math_matrix_NC_yes + \else + \expandafter\math_matrix_NC_nop + \fi} + +\permanent\protected\def\math_matrix_pickup{\global\settrue \c_math_matrix_first} +\permanent\protected\def\math_matrix_NC_yes{\global\setfalse\c_math_matrix_first} +\permanent\protected\def\math_matrix_NC_nop{\aligntab} % avoids lookahead + +% \def\math_matrix_stop_wrapup +% {\crcr +% \strut +% \crcr +% \noalign{\vskip-\struthtdp}} + +\def\math_matrix_start_processing + {\dontleavehmode + \bgroup + \tabskip\zeropoint + \math_matrix_pickup + \enforced\let\NR\math_matrix_NR + \enforced\let\NC\math_matrix_NC + \enforced\let\MC\math_matrix_NC + % + \enforced\let\endmath\relax + % + \setbox\nextbox\vbox\bgroup + \math_matrix_start_table + \halign \bgroup + % preamble + \span\math_matrix_preamble + % done + \crcr + \math_matrix_start_row} + +\def\math_matrix_stop_processing + {%\math_matrix_stop_wrapup % optional + \math_matrix_stop_row + \egroup + \math_matrix_stop_table + \egroup + \mathmatrixleft + \math_matrix_finish_nextbox + \mathmatrixright + \egroup} + +\let\math_matrix_strut \strut +\let\math_matrix_set_style\relax + +\def\math_matrix_check_settings + {\edef\p_strut{\mathmatrixparameter\c!strut}% + \ifx\p_strut\v!no + \enforced\let\math_matrix_strut\relax + \else + \enforced\let\math_matrix_strut\strut + \ifx\p_strut\v!yes\else + \spacing\p_strut + \fi + \fi + \d_math_eqalign_distance\mathmatrixparameter\c!distance\relax + \edef\math_matrix_set_style{\mathmatrixparameter\c!style}} + +\def\math_matrix_set_defaults + {\normalbaselines % hm, spacing ? + \mathsurround\zeropoint + \tabskip\zeropoint} + +\def\math_matrix_set_columns_step + {\advance\c_math_eqalign_column\plusone + %\c_math_matrix_columns\c_math_eqalign_column + \math_eqalign_set_column} + +\def\math_matrix_set_columns + {\c_math_eqalign_column\zerocount + \rawprocesscommacommand[\mathmatrixparameter\c!align]\math_matrix_set_columns_step} + +\newcount\c_math_eqalign_column_saved + +% \installglobalmacrostack\c_math_matrix_first + +\tolerant\protected\def\math_matrix_start[#1]#*[#2]% + {\begingroup + \globalpushmacro\c_math_matrix_first % hm, does that work? + \c_math_eqalign_column_saved\c_math_eqalign_column + \globalpushmacro\c_math_eqalign_first + \edef\currentmathmatrix{#1}% + \setupcurrentmathmatrix[#2]% + \math_matrix_check_settings + \math_matrix_set_defaults + \math_matrix_set_columns + \math_matrix_start_processing} + +\def\math_matrix_stop + {\math_matrix_stop_processing + \globalpushmacro\c_math_eqalign_first + \global\c_math_eqalign_column\c_math_eqalign_column_saved + \globalpopmacro\c_math_matrix_first + \endgroup} + +% vcenter: +% +% delta = (height(v) + depth(v))/2 +% axis = math_axis_size(cur_size) +% height(v) = delta + axis +% depth(v) = delta - axis + +\installcorenamespace{mathmatrixalignlocation} + +\let\mathmatrixleft \empty % experimental hook +\let\mathmatrixright\empty % experimental hook + +\setvalue{\??mathmatrixalignlocation\v!top }{\raise\dimexpr(\nextboxdp-\nextboxht)/2 +\mathaxisheight\mathstyle\relax} +\setvalue{\??mathmatrixalignlocation\v!high }{\raise\dimexpr(\nextboxdp-\nextboxht)/2\relax} +\setvalue{\??mathmatrixalignlocation\v!center}{\relax} +\setvalue{\??mathmatrixalignlocation\v!lohi} {\relax} +\setvalue{\??mathmatrixalignlocation\v!normal}{\relax} +\setvalue{\??mathmatrixalignlocation\v!bottom}{\lower\dimexpr(\nextboxdp-\nextboxht)/2 +\mathaxisheight\mathstyle\relax} +\setvalue{\??mathmatrixalignlocation\v!low }{\lower\dimexpr(\nextboxdp-\nextboxht)/2\relax} + +\def\math_matrix_finish_nextbox + {\begincsname\??mathmatrixalignlocation\mathmatrixparameter\c!location\endcsname\hbox\bgroup + \normalstartimath + \mathmatrixparameter\c!left + \vcenter{\box\nextbox}% + \mathmatrixparameter\c!right + \normalstopimath + \egroup} + +\definemathmatrix[matrix] +\definemathmatrix[\v!mathmatrix] + +%D \startbuffer +%D \placeformula \startformula[-] \startmatrix +%D \NC 1 \NC x \NC a \NR +%D \NC 2 \NC y \NC b \NR +%D \NC 3 \NC z \NC c \NR +%D \stopmatrix \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \definemathmatrix[bmatrix][left={\left[\mskip\thinmuskip},right={\mskip\thinmuskip\right]},strut=1.25] +%D +%D \startbuffer +%D \placeformula \startformula[-] \startbmatrix +%D \NC 1 \NC x \NC a \NR +%D \NC 2 \NC y \NC b \NR +%D \NC 3 \NC z \NC c \NR +%D \stopbmatrix \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D Taco added some code (dedicated to Aditya Mahajan) that gives more +%D control over aligments: + +%D \startbuffer +%D \startformula +%D \startmatrix +%D \NC a + x \NC = \NC a + d \NR +%D \NC y \NC = \NC d \NR +%D \stopmatrix +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +%D \startbuffer +%D \startformula +%D \startmatrix [distance=3pt,align={right,left}] +%D \NC a + x \NC = a + d \NR +%D \NC y \NC = d \NR +%D \stopmatrix +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +%D \startbuffer +%D \startformula +%D \startmatrix [left=\left(,right=\right)] +%D \NC a + x \NR +%D \NC y \NR +%D \stopmatrix +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D A bit more complex code: +%D +%D \startbuffer +%D \startformula +%D \text{Let }{\cal R} = \bigcup_{P_{X_1},P_{X_2}} +%D \left\{ (R_1, R_2) : +%D \startmatrix[distance=1em,align={left,left,right}] +%D \NC R_1 \NC < I(X_1 ; Y \mid X_2) \NC R_1 \NR +%D \NC \hfill Q_2 \NC < I(X_2 ; Y \mid X_1) \NC R_2 \NR +%D \NC R_1 + R_2 \NC < I(X_1 ; Y) \NC R_1 + R_2 \NR +%D \stopmatrix +%D \right\} +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +%D \macros +%D {startmatrices} +%D +%D Just a handy keystroke safer: + +\permanent\protected\def\startmatrices + {\begingroup + \setupmathmatrix} + +\permanent\protected\def\stopmatrices + {\endgroup} + +%D \startbuffer +%D \startformula +%D \startmatrix[left={\left(},right={\right)}] +%D \NC A \NC B \NR \NC C \NC D \NR +%D \stopmatrix +%D = +%D \startmatrix[left={\left(},right={\right)},location=low] +%D \NC A \NC B \NR \NC C \NC D \NR +%D \stopmatrix +%D = +%D \startmatrix[left={\left(},right={\right)},location=high] +%D \NC A \NC B \NR \NC C \NC D \NR +%D \stopmatrix +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D \startformula +%D \startmatrices[left={\left(},right={\right)}] +%D \startmatrix +%D \NC A \NC B \NR \NC C \NC D \NR +%D \stopmatrix +%D = +%D \startmatrix[location=bottom] +%D \NC A \NC B \NR \NC C \NC D \NR +%D \stopmatrix +%D = +%D \startmatrix[location=top] +%D \NC A \NC B \NR \NC C \NC D \NR +%D \stopmatrix +%D \stopmatrices +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer % does not run well: \getbuffer + +%D Handy for the \type {m-matrix} module: + +\permanent\tolerant\protected\def\startnamedmatrix[#1]#*[#2]% + {\begingroup + \edef\currentmathmatrix{#1}% + \setupcurrentmathmatrix[#2]% + \math_matrix_start[\currentmathmatrix]} + +\permanent\protected\def\stopnamedmatrix + {\math_matrix_stop + \endgroup} + +%D The following code is derived from Aditya's simplematrix prototype but +%D adapted to regular mathmatrices (which saves some code so it can go into +%D the core): + +\def\math_matrix_simple_row#1% + {\rawprocesscommalist[#1]\math_matrix_simple_col + \toksapp\scratchtoks{\NR}} + +\def\math_matrix_simple_col#1% + {\toksapp\scratchtoks{\NC#1}} + +\permanent\tolerant\protected\def\math_matrix_simple[#1]#*[#2]#:#3% + {\begingroup + \edef\currentmathmatrix{#1}% + \setupcurrentmathmatrix[#2]% + \scratchtoks\emptytoks + \processlist[];\math_matrix_simple_row[#3]% + \math_matrix_start[\currentmathmatrix]% + \the\scratchtoks + \math_matrix_stop + \endgroup} + +%D We hook it into the normal mathmatrix code: + +\appendtoks + \edef\p_simplecommand{\mathmatrixparameter\c!simplecommand}% + \ifx\p_simplecommand\empty\else + \setuevalue{\p_simplecommand}{\math_matrix_simple[\currentmathmatrix]}% + \fi +\to \everydefinemathmatrix + +%D And predefine some matrices: + +\definemathmatrix[matrix:parentheses][\c!left={\left(\mskip\thinmuskip},\c!right={\mskip\thinmuskip\right)},\c!align=\v!middle] +\definemathmatrix[matrix:brackets] [\c!left={\left[\mskip\thinmuskip},\c!right={\mskip\thinmuskip\right]},\c!align=\v!middle] +\definemathmatrix[matrix:bars] [\c!left={\left|\mskip\thinmuskip},\c!right={\mskip\thinmuskip\right|},\c!align=\v!middle] + +\definemathmatrix[thematrix][matrix:parentheses][\c!simplecommand=thematrix] + +%D \startbuffer +%D \startformula +%D \thematrix{1,2,3,4;5,6,7,8;9,10,11,12} +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer +%D +%D \startbuffer +%D \startformula +%D \startthematrix +%D \NC 1\NC 2\NC 3\NC 4\NR +%D \NC 5\NC 6\NC 7\NC 8\NR +%D \NC 9\NC10\NC11\NC12\NR +%D \stopthematrix +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer \getbuffer + +%D \macros +%D {startintertext} +%D +%D Preliminary feature: +%D +%D {\em example code} +%D +%D The intertext commands have to be expandable (in aligment lookahead) so +%D we cannot use \type {\protected}. + +\permanent\def\startintertext#1\stopintertext + {\noalign{\math_intertext{#1}}} + +\permanent\let\stopintertext\relax + +\permanent\def\intertext#1% + {\noalign{\math_intertext{#1}}} + +\protected\def\math_intertext#1% + {\penalty\postdisplaypenalty + \afterdisplayspace + \vbox{\forgetall\noindent#1\par}% + \penalty\predisplaypenalty + \beforedisplayspace} + +%D \macros +%D {substack} +%D +%D Preliminary code: +%D +%D \startbuffer +%D \startformula +%D \sum_{% +%D \startsubstack +%D i = 1 \NR +%D i \neq n \NR +%D i \neq m +%D \stopsubstack +%D }a_i +%D \stopformula +%D \stopbuffer +%D +%D \getbuffer which was typed as \typebuffer +%D +%D Notice that these macros give the correct spacing for +%D subscripts. Compare for example +%D +%D \startbuffer +%D \startformula +%D \sum_{\startsubstack a \NR b \NR \stopsubstack} +%D \text{ and } +%D \sum_{\scriptstyle a \atop \scriptstyle} +%D \stopformula +%D \stopbuffer +%D +%D \typebuffer which gives \getbuffer + +% no tagging yet : how is it supposed to be coded? + +\permanent\protected\def\startsubstack + {\begingroup + \vcenter\bgroup + \baselineskip\mathstacktotal + \lineskip\mathstackvgap + \lineskiplimit\lineskip + \mathsurround\zeropoint + \everycr\emptytoks + \enforced\let\NC\relax + \enforced\let\MC\relax + \enforced\let\NR\crcr + \halign\bgroup\hfil\normalstartimath\scriptstyle\alignmark\alignmark\normalstopimath\hfil\crcr} + +\permanent\def\stopsubstack % todo: \protected and delayed + {\crcr + \egroup + \egroup + \endgroup} + +% %D \macros +% %D {bordermatrix} +% %D +% %D In \PLAIN\ \TEX\ the width of a parenthesis is stored in +% %D the \DIMENSION\ \type{\mathparentwd}. This value is derived from +% %D the width of \type{\tenrm B}, so let's take care of it now: +% +% \ifx\mathparentwd\undefined \newdimen\mathparentwd \fi +% +% \let\normalbordermatrix\bordermatrix % move that code to here instead +% +% \protected\def\bordermatrix +% {\begingroup +% \setbox\scratchbox\hbox{\mr\char"239C}% +% \global\mathparentwd\wd\scratchbox +% \endgroup +% \normalbordermatrix} +% +% \def\bordermatrix +% {\begingroup +% \mr +% \global\mathparentwd\fontcharwd\font"239C\relax +% \endgroup +% \normalbordermatrix} + +%D \macros{overset, underset} +%D +%D The macros \type{\overset} and \type{\underset} are provided by +%D \AMS\ packages in \LATEX. These macro allows you to place a symbol +%D above or below another symbol, irrespective of whether the other +%D symbol is a relation or something else, and without influencing the +%D spacing. For most cases there is a better way to do such things +%D (declaring a math command with limop option, or using accents), but +%D occasionally these macros can be useful, for example: +%D +%D \startbuffer +%D \startformula +%D \overset{*}{X} \underset{*}{X} +%D \stopformula +%D \stopbuffer +%D \typebuffer \getbuffer +%D +%D Use these macros sparingly. Remember, \TEX\ was designed for +%D mathematics, so there is usually a proper method for typesetting +%D common math notation. +%D +%D These macros are a cleaner version of \type {\binrel@} and +%D \type {\binrel@@} macros in \AMSTEX\ packages. + +\def\math_binrel_apply#1% + {\begingroup + \setbox\scratchbox\hbox + {\thinmuskip 0mu + \medmuskip -1mu + \thickmuskip -1mu + \setbox\scratchbox\hbox{\normalstartimath#1\mathsurround\zeropoint\normalstopimath}% + \kern-\wd\scratchbox + \normalstartimath{}#1{}\mathsurround\zeropoint\normalstopimath}% + \ifdim\wd\scratchbox<\zeropoint + \endgroup + \expandafter\mathbin + \orelse\ifdim\wd\scratchbox>\zeropoint + \endgroup + \doubleexpandafter\mathrel + \else + \endgroup + \doubleexpandafter\firstofoneargument + \fi} + +\permanent\protected\def\overset#1#2% + {\math_binrel_apply{#2}{\mathop{\kern\zeropoint#2}\limits\normalsuperscript{#1}}} + +\permanent\protected\def\underset#1#2% + {\math_binrel_apply{#2}{\mathop{\kern\zeropoint#2}\limits\normalsubscript {#1}}} + +%D The following code comes from \type {math-str.mkiv}. +%D +%D Here we implement a basic math alignment mechanism. Numbers are also handled. The macros +%D \type {\startinnermath} and \type {\stopinnermath} can be overloaded in specialized +%D modules. + +\installcorenamespace{mathinnerstart} +\installcorenamespace{mathinnerstop} + +% \protected\def\startinnermath{\csname\??mathinnerstart\formulaparameter\c!align\endcsname} +% \protected\def\stopinnermath {\csname\??mathinnerstop \formulaparameter\c!align\endcsname} + +\permanent\protected\def\startinnermath{\expandnamespaceparameter\??mathinnerstart\formulaparameter\c!align\v!normal} +\permanent\protected\def\stopinnermath {\expandnamespaceparameter\??mathinnerstop \formulaparameter\c!align\v!normal} + +\permanent\protected\def\mathinnerstrut + {\doif{\formulaparameter\c!strut}\v!yes\strut} + +\permanent\protected\def\defineinnermathhandler#1#2#3% + {\setvalue{\??mathinnerstart#1}{#2}% + \setvalue{\??mathinnerstop #1}{#3}} + +\installtextracker + {formulas.boxes} + {\enforced\let\math_hbox\ruledhbox} + {\enforced\let\math_hbox\hbox} + +\let\math_hbox\hbox + +\newconstant\mathraggedstatus % normal left center right +\newconstant\mathnumberstatus % nothing normal shift_right + +\newdimen\d_math_number_correction + +\def\math_box_llapped_math_no + {\ifcase\mathraggedstatus\or + \box\b_strc_formulas_number + \or + \llap{\box\b_strc_formulas_number}% + \or + \llap{\box\b_strc_formulas_number}% + \fi} + +\def\math_box_rlapped_math_no + {\ifcase\mathraggedstatus\or + \rlap{\box\b_strc_formulas_number}% + \or + \rlap{\box\b_strc_formulas_number}% + \or + \box\b_strc_formulas_number + \fi} + +\newconditional\c_strc_math_has_number +\newconditional\c_strc_math_display_overflow +\newconstant \c_strc_math_number_location +\newdimen \d_strc_math_number_width +\newdimen \d_strc_math_display_width +\newbox \b_strc_math_display +\newconstant \c_strc_formulas_frame_mode +\newdimen \d_strc_math_indent +\newconditional\c_strc_math_indent + +\let\d_strc_math_framed_width\displaywidth + +\setvalue{\??formulaoption\v!frame}% + {\edef\p_frame{\formulaparameter\c!frame}% + \ifx\p_frame\v!number + \c_strc_formulas_frame_mode\plustwo % inside frame + \else + \c_strc_formulas_frame_mode\plusone % outside frame + \fi} + +% mode: 0=no frame | 1=number inside frame | 2=number outside frame + +\def\strc_math_flush_aligned + {\ifcase\c_strc_math_vertical + \ifcase\mathraggedstatus\or\hfill\or\hfill\fi + \box\b_strc_math_display + \ifcase\mathraggedstatus\or\or\hfill\or\hfill\fi + \else + \ifconditional\c_strc_math_indent + \ifzeropt\d_strc_math_indent\else + \hangafter\plusone + \hangindent\d_strc_math_indent + \fi + \fi + \edef\p_interlinespace{\formulaparameter\c!interlinespace}% + \ifx\p_interlinespace\empty\else\baselineskip\p_interlinespace\fi + \global\d_strc_math_indent\zeropoint + \ifcase\mathraggedstatus\or\raggedleft\or\raggedcenter\or\raggedright\fi + \unhbox\b_strc_math_display + \fi} + +\def\strc_math_flush_box_normal + {\ifcase\c_strc_math_vertical + \hbox to \displaywidth\bgroup + \strc_math_flush_aligned + \egroup + \else + \strc_math_flush_aligned + \fi} + +\def\strc_math_flush_box_framed_common + {\setformulaframedparameter\c!align{\formulaparameter\c!align}% + \letformulaframedparameter\c!strut\v!no + \d_framed_formula\ht\b_strc_math_display + \ifcase\mathraggedstatus\or\hfill\or\hfill \fi + \inheritedformulaframedframed{\box\b_strc_math_display}% + \ifcase\mathraggedstatus\or \or\hfill\or\hfill\fi} + +% \def\strc_math_flush_box_framed_inline +% {\letformulaframedparameter\c!location\empty +% \letformulaframedparameter\c!width\displaywidth +% \strc_math_flush_box_framed_common} + +\def\strc_math_flush_box_framed_display + {\let\currentformulaframed\currentformula + \letformulaframedparameter\c!location\v!formula + \setformulaframedparameter\c!width{\d_strc_math_framed_width}% + \strc_math_flush_box_framed_common} + +\def\strc_math_flush_box_framed_fit_inline + {\let\currentformulaframed\currentformula + \letformulaframedparameter\c!location\empty + \letformulaframedparameter\c!width\v!fit + \strc_math_flush_box_framed_common} + +\def\strc_math_flush_box_framed_fit_display + {\let\currentformulaframed\currentformula + \letformulaframedparameter\c!location\v!formula + \letformulaframedparameter\c!width\v!fit + \strc_math_flush_box_framed_common} + +% combiners + +\def\strc_math_flush_box + {\ifcase\c_strc_formulas_frame_mode + \strc_math_flush_box_normal + \else + \strc_math_flush_box_framed_display + \fi} + +\def\strc_math_number_right_normal + {\strc_math_flush_aligned + \hss % hss makes room for number + \math_box_llapped_math_no} + +\def\strc_math_number_left_normal + {\math_box_rlapped_math_no + \strc_math_flush_aligned + \hss} % hss makes room for number + +\def\strc_math_number_right_normal_outside + {\ifconditional\c_strc_formulas_tight + \strc_math_flush_box_framed_fit_display + \else + \strc_math_flush_box_framed_display + \fi + \hss % hss makes room for number + \math_box_llapped_math_no} + +\def\strc_math_number_left_normal_outside + {\math_box_rlapped_math_no + \hss % hss makes room for number + \ifconditional\c_strc_formulas_tight + \strc_math_flush_box_framed_fit_display + \else + \strc_math_flush_box_framed_display + \fi} + +\def\strc_math_number_right_normal_inside + {\setbox\b_strc_math_display\hpack to \dimexpr\displaywidth-\d_framed_locator_lo-\d_framed_locator_ro\relax\bgroup + \strc_math_flush_aligned + \hss + \math_box_llapped_math_no + \egroup + \strc_math_flush_box_framed_fit_inline} + +\def\strc_math_number_left_normal_inside + {\setbox\b_strc_math_display\hpack to \dimexpr\displaywidth-\d_framed_locator_lo-\d_framed_locator_ro\relax\bgroup + \math_box_rlapped_math_no + \hss + \strc_math_flush_aligned + \egroup + \strc_math_flush_box_framed_fit_inline} + +\def\strc_math_number_right_overflow + {\vpack\bgroup + \strc_math_flush_box + \par + \hpack to \displaywidth\bgroup + \hss + \math_box_llapped_math_no + \egroup + \egroup} + +\def\strc_math_number_left_overflow + {\vpack\bgroup + \hpack to \displaywidth\bgroup + \math_box_rlapped_math_no + \hss + \egroup + \strc_math_flush_box + \egroup} + +\def\strc_math_number_right_overflow_outside + {\vpack\bgroup + \strc_math_flush_box_framed_fit_inline + %\hskip\zeropoint % nicely breaks the line without introducing funny vertical spacing ... why o why + \hpack to \displaywidth\bgroup + \hss + \math_box_llapped_math_no + \egroup + \egroup} + +\def\strc_math_number_left_overflow_outside + {\vpack\bgroup + \hpack to \dimexpr\displaywidth-\d_framed_locator_lo\relax\bgroup + \math_box_rlapped_math_no + \hss + \egroup + \hskip\zeropoint % nicely breaks the line without introducing funny vertical spacing ... why o why + \strc_math_flush_box_framed_fit_inline + \egroup} + +\def\strc_math_number_right_overflow_inside + {\setbox\b_strc_math_display\vpack\bgroup + \box\b_strc_math_display + \hpack to \displaywidth\bgroup + \hss + \math_box_llapped_math_no + \hskip\d_framed_locator_ro + \egroup + \egroup + \strc_math_flush_box_framed_fit_inline} + +\def\strc_math_number_left_overflow_inside + {\setbox\b_strc_math_display\vpack\bgroup + \hpack to \displaywidth\bgroup + % \hskip\d_framed_locator_lo + \math_box_rlapped_math_no + \hss + \egroup + \box\b_strc_math_display + \egroup + \strc_math_flush_box_framed_fit_inline} + +% checkers + +\def\strc_math_number_check + {\d_strc_math_display_width\wd\b_strc_math_display + \ifconditional\c_strc_formulas_tight + \ifdim\d_strc_math_display_width>\displaywidth + \settrue\c_strc_math_display_overflow + \else + \displaywidth\d_strc_math_display_width + \setfalse\c_strc_math_display_overflow + \fi + \else + \ifdim\d_strc_math_display_width>\displaywidth + \settrue\c_strc_math_display_overflow + \else + \setfalse\c_strc_math_display_overflow + \fi + \fi} + +\def\strc_math_number_check_outside + {\d_strc_math_display_width\naturalwd\b_strc_math_display + \ifdim\dimexpr\d_strc_math_display_width+\d_framed_locator_lo+\d_framed_locator_ro\relax>\displaywidth + \settrue\c_strc_math_display_overflow + \else + \setfalse\c_strc_math_display_overflow + \fi + % still ok? + \ifnum\mathraggedstatus=\plustwo + \edef\d_strc_math_framed_width{\the\dimexpr\displaywidth-2\wd\b_strc_formulas_number\relax}% + \else + \edef\d_strc_math_framed_width{\the\dimexpr\displaywidth-\wd\b_strc_formulas_number\relax}% + \fi} + +\let\strc_math_number_check_inside\strc_math_number_check_outside + +% offsets + +\def\strc_math_number_check_offsets + {\begingroup + \setbox\scratchbox\hbox + {\inheritedformulaframedframed + {\pack_framed_locator_set_lo\pack_framed_locator_set_ro}}% + \endgroup} + +% tracing + +\def\strc_math_traced_state_yes + {\llap{\setbox\scratchbox\hbox{\infofont + \ifcase\mathraggedstatus unset\or right\or middle\or left\fi + \space + \ifcase\c_strc_formulas_frame_mode no\or out\or in\fi + \space + \ifconditional\c_strc_math_display_overflow overflow\else fit\fi + \quad}\ht\scratchbox\zeropoint\dp\scratchbox\zeropoint\box\scratchbox}} + +\let\strc_math_traced_state\relax + +\installtextracker + {formulas.framed} + {\let\strc_math_traced_state\strc_math_traced_state_yes} + {\let\strc_math_traced_state\relax} + +% packaging + +\protected\def\strc_math_box_start#1% + {\hsize\displaywidth % \checkeddisplaymath + \global\mathnumberstatus\plusone + \mathraggedstatus#1\relax + % + \global\d_math_number_correction\zeropoint + % + \edef\p_location{\formulaparameter\c!location}% + \useformulacolorparameter\c!color + \c_strc_math_number_location\ifx\p_location\v!left\plusone\orelse\ifx\p_location\v!right\plustwo\else\zerocount\fi + % + %\strc_formulas_place_number % not here as we can have inner alignment numbers + \dontcomplain + \setbox\b_strc_math_display\math_hbox\bgroup % \checkeddisplaymath + \mathinnerstrut + \startforceddisplaymath} + +\def\strc_math_flush_number_no + {\ifcase\c_strc_math_vertical + \ifconditional\c_strc_math_display_overflow + \ifcase\c_strc_formulas_frame_mode + \strc_math_flush_box_normal + \else + \strc_math_flush_box_framed_fit_inline + \fi + \else + \ifcase\c_strc_formulas_frame_mode + %\ifconditional\c_strc_formulas_tight + % \strc_math_flush_box_normal + %\else + \strc_math_flush_box_normal + %\fi + \else + \ifconditional\c_strc_formulas_tight + \strc_math_flush_box_framed_fit_inline + \else + \strc_math_flush_box_framed_display + \fi + \fi + \fi + \else + \strc_math_flush_box + \fi} + +\def\strc_math_flush_number_left + {\ifcase\c_strc_math_vertical + \ifconditional\c_strc_math_display_overflow + \ifcase\c_strc_formulas_frame_mode + \strc_math_number_left_overflow + \or + \strc_math_number_left_overflow_outside + \or + \strc_math_number_left_overflow_inside + \fi + \else + \ifcase\c_strc_formulas_frame_mode + \strc_math_number_left_normal + \or + \strc_math_number_left_normal_outside + \or + \strc_math_number_left_normal_inside + \fi + \fi + \else + \box\b_strc_formulas_number + \hfill + \strc_math_flush_aligned + \fi} + +\def\strc_math_flush_number_right + {\ifcase\c_strc_math_vertical + \ifconditional\c_strc_math_display_overflow + \ifcase\c_strc_formulas_frame_mode + \strc_math_number_right_overflow + \or + \strc_math_number_right_overflow_outside + \or + \strc_math_number_right_overflow_inside + \fi + \else + \ifcase\c_strc_formulas_frame_mode + \strc_math_number_right_normal + \or + \strc_math_number_right_normal_outside + \or + \strc_math_number_right_normal_inside + \fi + \fi + \else + \strc_math_flush_aligned + \hfill + \box\b_strc_formulas_number + \fi} + +\protected\def\strc_math_box_stop + {\stopforceddisplaymath + \egroup + % check number + \d_strc_math_number_width\wd\b_strc_formulas_number + % + \ifcase\mathnumberstatus + \setfalse\c_strc_math_has_number + \or\ifzeropt\d_strc_math_number_width + \setfalse\c_strc_math_has_number + \else + \settrue\c_strc_math_has_number + \fi\fi + % preroll left and right offsets + \ifcase\c_strc_formulas_frame_mode + % no frame + \else + \strc_math_number_check_offsets + \fi + \ifcase\c_strc_formulas_frame_mode + \strc_math_number_check + \or + \strc_math_number_check_outside + \else + \strc_math_number_check_inside + \fi + \noindent % \noindentation % not \dontleavehmode + \hskip\d_strc_formulas_display_margin_left % was kern but that doesn't indent + \strc_math_traced_state + \ifcase\c_strc_math_vertical + \hbox to \displaywidth \bgroup + \or + \vbox \bgroup \hsize\displaywidth + \or + \bgroup \hsize\displaywidth + \fi + \ifcase\mathnumberstatus + \strc_math_flush_box + \or % status 1 + \ifcase\c_strc_math_number_location + \strc_math_flush_box + \or % number left + \ifzeropt\wd\b_strc_formulas_number + \strc_math_flush_number_no + \else + \strc_math_flush_number_left + \fi + \else % number right + \ifzeropt\wd\b_strc_formulas_number + \strc_math_flush_number_no + \else + \strc_math_flush_number_right + \fi + \fi + \or % status 2 + \hskip\d_math_number_correction % probably no longer used + \strc_math_flush_box + \hss + \else + \strc_math_flush_box + \fi + \ifcase\c_strc_math_vertical + \or + \or + \par + \fi + \egroup} + +\defineinnermathhandler\v!left {\strc_math_box_start\plusone }{\strc_math_box_stop} +\defineinnermathhandler\v!middle {\strc_math_box_start\plustwo }{\strc_math_box_stop} +\defineinnermathhandler\v!right {\strc_math_box_start\plusthree}{\strc_math_box_stop} +\defineinnermathhandler\v!flushleft {\strc_math_box_start\plusthree}{\strc_math_box_stop} +\defineinnermathhandler\v!center {\strc_math_box_start\plustwo }{\strc_math_box_stop} +\defineinnermathhandler\v!flushright{\strc_math_box_start\plusone }{\strc_math_box_stop} +\defineinnermathhandler\v!normal {\strc_math_box_start\plustwo }{\strc_math_box_stop} + +%D Some inline math tweak. + +\appendtoks + \ifcase\mathnestinglevel\or + % 4=disable 6=only when no spaces + \mathsurroundskip\mathematicsparameter\c!textdistance\relax + \ifzeropt\mathsurroundskip + \ifzeropt\gluestretch\mathsurroundskip + \ifzeropt\glueshrink\mathsurroundskip + \mathsurroundmode\plussix + \else + \mathsurroundskip\zeropoint + \mathsurroundmode\plusfour + \fi + \else + \mathsurroundmode\plussix + \fi + \else + \mathsurroundmode\plussix + \fi + \else + \mathsurroundmode\plusfour + \mathsurroundskip\zeropoint + \fi +\to \everymathematics + +\setupmathematics + [\c!textdistance=\zeropoint] + +%D This is an experiment. No fancy spacing and alignments here. If we ever +%D go that route it might result in incompatible rendering. + +\permanent\protected\def\startsplitformula + {\ifhmode + \par + \fi + \begingroup + \beforedisplayspace + % subset of \everydisplay: + \c_attr_mathmode\plusone + \settrue \indisplaymath + % end of subset + \informulatrue} + +\permanent\protected\def\stopsplitformula + {\afterdisplayspace + \endgroup} + +\protect \endinput + +% \placeformula \startformula[-] \startmatrix +% \NC 1 \NC x \NC a \NR +% \NC 2 \NC y \NC b \NR +% \NC 3 \NC z \NC c \NR +% \stopmatrix \stopformula + +% \definemathmatrix[bordermatrix][left={\left[\mskip\thinmuskip},right={\mskip\thinmuskip\right]}] + +% \placeformula \startformula[-] \startbordermatrix +% \NC 1 \NC x \NC a \NR +% \NC 2 \NC y \NC b \NR +% \NC 3 \NC z \NC c \NR +% \stopbordermatrix \stopformula |