<..math config util..>+
\:CheckOption{base}
\if:Option \else
<.config math end-points.>
<.sub and sup.>
<.math classes.>
<.grouped math classes.>
<.built-in tex math ops.>
\fi
-_-_-
The following become active only when they are being configured.
<..config math end-points..>
\NewConfigure{$}[3]{%
\def\a:mth{\bgroup#1}\def\b:mth{#2\egroup}%
\def\c:mth{<.empty script base trap.>#3}%
\everymath{\ifx \EndPicture\:UnDef
$\a:mth\everymath{}\everydisplay{}$%
\aftergroup\b:mth \c:mth \fi}}
-_-_-
<..config math end-points..>+
\NewConfigure{$$}[3]{%
\def\a:display{\bgroup#1}%
\def\b:display{#2\egroup}%
\def\c:display{#3}%
\everydisplay{\ifx \EndPicture\:UnDef
$$\a:display\everymath{}\everydisplay{}$$%
\aftergroup\b:display \c:display\fi}}
-_-_-
Can’t put |<empty script base trap|> into \def\c:display{#3}% because of cases such as $$\halign{#\cr a\cr}$$
<..empty script base trap..>
{\csname HCode\endcsname{}}%
-_-_-
Tex4ht translate each $$...$$ into $$ $$$$...$$ and upon reaching the second environment the mode is already horizontal. For such case, the above approach of distinguishing in-line and off-line display math don’t work. This is a place where an implimentation within the tex engine can do a better work. On the other hand, all of this can be fixed within and XSL-like transformations on the final output of tex4ht.
\halign doesn’t allow expansion into content to precede it within the math mode. Hence, the \aftergroup below.
<..config math end-points..>+
\def\PicDisplay{\pic:gobble\env:PD
\def\:temp{$$}\pic:cond\Pic:math\:temp}
\def\EndPicDisplay{\end:condpic\pic:gobble\endenv:PD}
\def\Pic:math{\hfil\break
\expand:after{\Picture*}\alt:Mth{ \c:Math}}
-_-_-
<..config math end-points..>+
\def\PicMath{\leavevmode\pic:gobble\env:PM\hbox\bgroup
\everymath{}\everydisplay{}\pic:cond\pic:math$}
\def\EndPicMath{\end:condpic\egroup\pic:gobble\endenv:PM}
\def\pic:math{\expand:after{\Picture+}\alt:mth{ \c:math}}
-_-_-
<..config math end-points..>+
\NewConfigure{PicDisplay}[4]{\def\alt:Mth{#3}%
\ifx \alt:Mth\empty\else \def\alt:Mth{[#3]}\fi\def\c:Math{#4}%
\c:def\env:PD{#1}\c:def\endenv:PD{#2}}
\NewConfigure{PicMath}[4]{\def\alt:mth{#3}%
\ifx \alt:mth\empty\else \def\alt:mth{[#3]}\fi\def\c:math{#4}%
\c:def\env:PM{#1}\c:def\endenv:PM{#2}}
-_-_-
\Configure{PicDisplay}{}{}{[ALT]}{extra-attributes} \Configure{PicMath}{}{}{[ALT]}{extra-attributes}
<..config math end-points..>+
\def\DviMath{\a:DviMath\leavevmode \MathClass <.same page.> \DviSend}
\def\EndDviMath{\EndDviSend <.end same page.>\EndMathClass \b:DviMath}
\NewConfigure{DviMath}{2}
-_-_-
The above need to be boxed to prevent page breaks within the send environment \special{t4ht~}...\special{t4ht~}..
<..same page..>
\ht:special{t4ht@(}\vbox
\bgroup{\expandafter\ifx\csname ht:everypar\endcsname\relax
\expandafter\everypar
\else \expandafter\ht:everypar\fi{}\leavevmode\ht:special{t4ht@)}}%
\relpenalty=10000
\binoppenalty=10000
-_-_-
<..end same page..>
\ht:special{t4ht@(}\egroup\ht:special{t4ht@)}%
-_-_-
The penalty is to prohibit line breaks. For instance, the following formula under the mathml mode.
The specials remove the space at the start and end points of the box.
Examples:
<..config math end-points..>+
\def\PMath{\bgroup\Canvas \x:SUBOff \x:SUPOff
\let\Picture=\empty \everymath{}\everydisplay{}}
\def\EndPMath{\EndCanvas\egroup}
\:CheckOption{PMath} \if:Option
\def\:Pmath{$\PMath$\aftergroup\EndPMath}
\def\:Pdisp{$$\PMath$$\aftergroup\EndPMath}
\everymath{\:Pmath}
\everydisplay{\:Pdisp}
\fi
-_-_-
Example: \def\({\PMath$} \def\){$\EndPMath} \def\[{\PMath$$} \def\]{$$\EndPMath}.
<..sp and sb for catcode 13..>
\ifnum \the\catcode‘^=13
\let\expandafter\noexpand
\csname x:SUPOff\endcsname=\noexpand\empty
\let\expandafter\noexpand
\csname x:SUPOn\endcsname=\noexpand\empty
\catcode‘\noexpand ^=\the\catcode‘^\fi
\ifnum \the\catcode‘_=13
\let\expandafter\noexpand
\csname x:SUBOff\endcsname=\noexpand\empty
\let\expandafter\noexpand
\csname x:SUBOn\endcsname=\noexpand\empty
\catcode‘\noexpand _=\the\catcode‘_\fi
-_-_-
The \x:SUBOff (and \x:SUPOff) are activated only if the catcodes of ^ and _, respectively, were not 13 when tex4ht.sty was loaded. If the catcode were 13, we need a user intervention, in which \sp and \sb should be referenced for math mode. That is, something along the lines \ifmmode \expandafter\sp\else \expandafter current^\fi will probably work most of the times.
TRY: Replace SUBOn with HSUBOn, SUBOff with HSUBOff, Ditto for SUP
<..sub and sup..>
\let\s:b=\sb
\let\:sbb=\sb DraTeX already uses \:sb
\def\sb{\m:op\:sbb{SUB}}
\catcode‘\_=8
\:CheckOption{no_} \if:Option
\let\s:b=\:UndFi
<.old SUB 0.>
<.new SUB 0.>
\def\no:restore{\let\no:restore=\:UnDef}
\else
\Log:Note{for non active \string_,
use the command line option ‘no\string_’}%
<.old SUB 1.>
<.new SUB 1.>
\catcode‘\_=13
<.math sb.>
\def\x:SUBOff{\let_=\s:b}
\def\pr:sb{\ifx \EndPicture\:UnDef
\expandafter\Protect\expandafter\S:b
\else \expandafter\s:b \fi}
<.old SUB 2.>
<.new SUB 2.>
<.old SUB 3.>
<.new SUB 3.>
\catcode‘\_=8
\:CheckOption{_13} \if:Option
\def\no:restore{\let\no:restore=\:UnDef
\mathcode‘\_="8000 \catcode‘\_=13 }
\append:def\SUBOn{\mathcode‘\_="8000 \catcode‘\_=13 <.let sb.>}
\else
\Log:Note{for \string_ of catcode 13,
use the command line option ‘\string_13’}
\def\no:restore{\let\no:restore=\:UnDef
\mathcode‘\_="8000 \catcode‘\_=12 }
\append:def\SUBOn{\mathcode‘\_="8000 \catcode‘\_=12 <.let sb.>}
\fi
\bgroup
\SUBOn \def\:temp{<.let sb.>}
\expandafter \egroup \:temp
\fi
-_-_-
<..old SUB 0..>
\let\x:SUBOff=\empty \let\x:SUBOn=\empty
-_-_-
<..new SUB 0..>
\let\SUBOff=\empty \let\SUBOn=\empty
-_-_-
<..old SUB 1..>
\ifx \sys:sb\:UnDef \def\:tempaa{_}
\else \def\:tempaa{\noexpand\sys:sb}\fi
-_-_-
<..new SUB 1..>
\ifx \sys:sb\:UnDef \def\:tempa#1{\append:def\SUBOff{\let#1=_}}
\else \def\:tempa#1{\append:def\SUBOff{<.HSUBOff op.>}}\fi
-_-_-
<..HSUBOff op..>
\def#1{%
\ifmmode \expandafter\s:b \else \expandafter\sys:sb \fi
}%
-_-_-
<..old SUB 2..>
\edef\:SUBOff{\def\noexpand_{\:tempaa}}
-_-_-
<..new SUB 2..>
\:tempa_
-_-_-
<..old SUB 3..>
\def\x:SUBOn{\def_{\ifmmode \expandafter\pr:sb
\else \expandafter\sys:sb\fi}<.let sb.>}
\x:SUBOn
-_-_-
<..new SUB 3..>
\def\SUBOn{\catcode‘\_=8
\def_{\ifmmode \expandafter\pr:sb
\else \expandafter\sys:sb\fi}}
\SUBOn
-_-_-
<..record external sub-sup..>
\edef\SUPOff{%
\catcode‘\noexpand ^=\the\catcode‘^\relax
}
\edef\SUBOff{%
\catcode‘\noexpand _=\the\catcode‘_\relax
}
\bgroup
\catcode‘\^=13 \global\let\sys:sp=^
\catcode‘\_=13 \global\let\sys:sb=_
\egroup
-_-_-
<..sub and sup..>+
\let\s:p=\sp
\let\:spp=\sp
\def\sp{\m:op\:spp{SUP}}
\catcode‘\^=7
<.default sup sup config.>
\:CheckOption{no^} \if:Option
\let\s:p=\:UndFi
<.old SUP 0.>
<.new SUP 0.>
\else
\Log:Note{for non active \string^,
use the command line option ‘no\string^’}%
<.old SUP 1.>%
<.new SUP 1.>%
\catcode‘\^=13
<.math sp.>
\def\x:SUPOff{\let^=\s:p }
\def\pr:sp{\ifx \EndPicture\:UnDef
\expandafter\Protect\expandafter\S:p
\else \expandafter\s:p \fi}
<.old SUP 2.>
<.new SUP 2.>
<.old SUP 3.>
<.new SUP 3.>
<.sup 13.>
\catcode‘\^=7
\:CheckOption{^13} \if:Option
<.sup sup 13 config.>
\append:def\no:restore{\mathcode‘\^="8000 \catcode‘\^=13 }
\append:def\SUPOn{\mathcode‘\^="8000 \catcode‘\^=13 <.let sp.>}
\else
\Log:Note{for \string^ of catcode 13,
use the command line option ‘\string^13’}%
\append:def\no:restore{\mathcode‘\^="8000 \catcode‘\^=12 }
\append:def\SUPOn{\mathcode‘\^="8000 \catcode‘\^=12 <.let sp.>}
\fi
\bgroup
\SUPOn \def\:temp{<.let sp.>}
\expandafter \egroup \:temp
\fi
-_-_-
<..default sup sup config..>
\NewConfigure{\string^\string^}[2]{%
\def\:tempa##1>{}\def\:temp{#1}\:warning{\string
\Configure{\string\string\string ^\string\string
\string^}{\expandafter\:tempa\meaning \:temp}{...}
ignored; option \string^13 is not on}}
-_-_-
<..sup 13..>
\def\:sUp{%
\let\:sUp=^%
\def^{\futurelet\:temp\next:hat}
\def\next:hat{\ifx ^\:temp \expandafter\:dblhat\else
\expandafter\:sUp\fi}%
}
-_-_-
<..sup sup 13 config..>
\:sUp
\def\:dblhat#1#2{\def\:temp{#2}%
\def\:tempc{\def\:tempa####1>{}\:warning{\string^\string
^\expandafter\:tempa\meaning\:temp? \string\Configure{\string
\string\string ^\string\string\string^}{\expandafter\:tempa
\meaning \:temp}{...} or use option no\string^}}%
\ext:chr \:tempc}
\let\ext:chr=\empty
\NewConfigure{\string^\string^}[2]{%
\NewConfigure{\string^\string^}{2}%
\append:def\ext:chr{\def\:tempa{#1}\ifx \:temp\:tempa
\def\:tempc{#2}\fi}}
-_-_-
<..old SUP 0..>
\let\x:SUPOff=\empty \let\x:SUPOn=\empty
-_-_-
<..new SUP 0..>
\let\SUPOff=\empty \let\SUPOn=\empty
-_-_-
<..old SUP 1..>
\ifx \sys:sp\:UnDef \def\:tempbb{^}
\else \def\:tempbb{\noexpand\sys:sp}\fi
-_-_-
<..new SUP 1..>
\ifx \sys:sp\:UnDef \def\:tempb#1{\append:def\SUPOff{\let#1=^}}
\else \def\:tempb#1{\append:def\SUPOff{<.HSUPOff op.>}}\fi
-_-_-
<..HSUPOff op..>
\def#1{%
\ifmmode \expandafter\s:p \else \expandafter\sys:sp \fi
}%
-_-_-
<..old SUP 2..>
\edef\:SUPOff{\def\noexpand^{\:tempbb}}
-_-_-
<..new SUP 2..>
\:tempb^
-_-_-
<..old SUP 3..>
\def\x:SUPOn{\def^{\ifmmode \expandafter\pr:sp
\else \expandafter\sys:sp\fi}<.let sp.>}
\x:SUPOn
-_-_-
<..new SUP 3..>
\def\SUPOn{%
\def^{\ifmmode \expandafter\pr:sp
\else \expandafter\sys:sp\fi}}
\SUPOn
-_-_-
<..math sp..>
\if:Option
\def\S:p{\m:op\s:p{SUP}}
\else
\def\S:p#1{\def\SuP:{#1}\futurelet\:temp\sup:sub}
\:CheckOption{^13} \if:Option \catcode‘\_=13
\else \catcode‘\_=12\fi
\def\blank:space{
}
\def\sup:sub{\expandafter
\ifx \blank:space\:temp \expandafter\sup:subA
\else \expandafter\sup:subB\fi}
\expandafter\def
\expandafter\sup:subA\blank:space{\futurelet\:temp\sup:sub}
\def\sup:subB{\ifx _\:temp \expandafter\SUP:SUB
\else \expandafter\a:putSUP \fi }
\catcode‘\_=8
\def\a:putSUP{\sup:I \SuP:}
\def\sup:I{\m:op\s:p{SUP}}
\fi
-_-_-
<..math sb..>
\if:Option
\def\S:b{\m:op\s:b{SUB}}
\else
\def\S:b#1{\def\SuB:{#1}\futurelet\:temp\sub:sup}
\def\blank:space{
}
\def\sub:sup{\expandafter
\ifx \blank:space\:temp \expandafter\sub:supA
\else \expandafter\after:sub\fi}
\expandafter\def
\expandafter\sub:supA\blank:space{\futurelet\:temp\sub:sup}
<.extension of sub.>
\def\a:putSUB{\sub:I \SuB:}
\def\sub:I{\m:op\s:b{SUB}}
\fi
-_-_-
<..utilities..>+
\NewConfigure{afterSUB}[2]{\expandafter
\def \csname \meaning#1sb\endcsname{#2}}
\NewConfigure{putSUB}[1]{\def\a:putSUB{#1}}
\NewConfigure{putSUP}[1]{\def\a:putSUP{#1}}
\:CheckOption{no^} \if:Option \else
\:CheckOption{^13} \if:Option \catcode‘\^=13
\else \catcode‘\^=12 \fi
\Configure{afterSUB}^{\SUB:SUP}
\catcode‘\^=7
\fi
-_-_-
The following is needed for a math prime after sub. For instance, a_1’$.
<..extension of sub..>
\def\after:sub{\futurelet\:temp\choose:sub}
\def\choose:sub{\expandafter
\ifx \csname \meaning\:temp sb\endcsname\relax
\expandafter \a:putSUB
\else
\expandafter\expandafter\csname \meaning\:temp sb\endcsname
\fi
}
-_-_-
We need to catch cases like the blank space appearing after the b within AmsTeX in an equation like:
We can’t use a declaration of the form \def\sub:supA#1{... because the macro consumes the parameter following the space, and that parameter can a forbidden token.
The \edef\:SUBSUPOff doesnt wotk with \let instead of \def in the body. Why?
<..sub and sup..>+
\def\m:op{\ifx \EndPicture\:UnDef \expandafter\:mop
\else \expandafter\:m:p\fi}
\def\:mop{\relax\ifmmode \expandafter \mo:p \else \expandafter\mop:\fi}
\def\mo:p#1#2#3{{\csname a:#2\endcsname
#1{#3}\csname b:#2\endcsname}}
\def\mop:#1#2#3{#1}
\def\:m:p#1#2{#1}
-_-_-
<..sub and sup..>+
\NewConfigure{SUB}{2}
\NewConfigure{SUP}{2}
-_-_-
We need to pause the hyperext font for the case that the subscript itself comes with a font change. Without the pause we’ll get a partial overlap with the <SUB/SUP> font (e.g., \it $\A_{\mathbf{R}}$).
In case that ^ looses its original meaning, TeX will complain about double exponnet if it follows a quote symbol.[’].
Two options \Configure{SUBSUP}{ before }{ between }{ after } and \Configure{SUPSUB}{ before }{ between }{ after }, differing in the way the reorder the superscript and subscript. However, if the three parameters are empty, or just a single subscript / superscript is present, then \Configure{SUB}{ before }{ after } and \Configure{SUP}{ before }{ after } get into effect.
<..sub and sup..>+
\:CheckOption{no^} \if:Option \else \:CheckOption{no_}\fi
\if:Option
\NewConfigure{SUBSUP}[3]{}
\NewConfigure{SUPSUB}[3]{}
\NewConfigure{SUB/SUP}[6]{}
\else
\def\SUP:SUB#1#2{\let\chs:sbsp=\:gobble\def\SuB:{#2}\SUBSUP:}
\def\SUB:SUP#1#2{\def\chs:sbsp##1##2{##1}\def\SuP:{#2}\SUBSUP:}
\let\SUBSUP:=\empty
\NewConfigure{SUBSUP}[3]{%
\def\:temp{#1#2#3}\ifx \:temp\empty
\def\SUBSUP:{\sub:I\SuB:\sup:I\SuP:}%
\else \def\SUBSUP:{#1\s:b{\SuB:}#2\s:p{\SuP:}#3}\fi}
\NewConfigure{SUPSUB}[3]{%
\def\:temp{#1#2#3}\ifx \:temp\empty
\def\SUBSUP:{\sup:I\SuP:\sub:I\SuB:}%
\else \def\SUBSUP:{#1\s:p{\SuP:}#2\s:b{\SuB:}#3}\fi}
\NewConfigure{SUB/SUP}[6]{%
\def\:temp{#1#2#3#4#5#6}\ifx \:temp\empty
\def\SUBSUP:{\sub:I\SuB:\sup:I\SuP:}%
\else \def\SUBSUP:{\chs:sbsp
{#1\s:b{\SuB:}#2\s:p{\SuP:}#3}%
{#4\s:p{\SuP:}#5\s:b{\SuB:}#6}}\fi}
\fi
-_-_-
<..early latex subs/sups..>
\ifx \config:opt\:UnDef \else
<.defs for early latex subs/sups.>
\fi
-_-_-
<..defs for early latex subs/sups..>
\append:def\:RestoreCatcodes{\early:sub\early:sup}
\let\:IfFileExists\IfFileExists
\def\IfFileExists#1#2#3{%
\csname recall:sub\endcsname
\csname recall:sup\endcsname
\expandafter\let\csname #1:sub\endcsname=\early:sub
\expandafter\let\csname #1:sup\endcsname=\early:sup
\let\early:sub=\relax \let\recall:sub\relax
\let\early:sup=\relax \let\recall:sup\relax
\:IfFileExists{#1}{#2}{#3}%
\expandafter\let\expandafter\early:sub\csname #1:sub\endcsname
\expandafter\let\expandafter\early:sup\csname #1:sup\endcsname
\early:sub \early:sup
}
\ifx \o:document\:UnDef
\pend:def\Preamble{%
\csname recall:sub\endcsname
\csname recall:sup\endcsname}
\fi
-_-_-
<../document recall sub/sup..>
\csname recall:sub\endcsname
\csname recall:sup\endcsname
-_-_-
<..defs for early latex subs/sups..>+
\def\:CheckOption#1{\def\:temp{#1}%
\:Optionfalse
\expandafter\:ScanOptions\config:opt,,//}
\def\:ScanOptions#1,#2//{\def\:next{#1}%
\ifx \:next\empty
\else \ifx \:temp\:next \:Optiontrue \let\:next\relax
\else \def\:next{\:ScanOptions#2//}%
\fi \fi \:next }
<.cats early latex subs/sups.>
\let\:CheckOption=\:UnDef
-_-_-
<..cats early latex subs/sups..>
\let\early:sub=\empty
\:CheckOption{early_} \if:Option
\:CheckOption{no_} \if:Option \else
\:CheckOption{_13} \if:Option
\def\early:sub{%
\xdef\recall:sub{%
\mathcode‘\noexpand\_=\the\mathcode‘\_
\catcode‘\noexpand\_=\the\catcode‘\_
}
\mathcode‘\_="8000 \catcode‘\_=13
}
\else
\def\early:sub{%
\xdef\recall:sub{%
\mathcode‘\noexpand\_=\the\mathcode‘\_
\catcode‘\noexpand\_=\the\catcode‘\_
% \immediate\write16{.....sub \the\catcode‘\_}%
}%
\mathcode‘\_="8000 \catcode‘\_=12
% \immediate\write16{.....sub 12}
}
\fi
\fi
\else
\Log:Note{for \string_ at preamble,
use the command line option ‘early\string_’}%
\fi
-_-_-
<..cats early latex subs/sups..>+
\let\early:sup=\empty
\:CheckOption{early^} \if:Option
\:CheckOption{no^} \if:Option \else
\:CheckOption{^13} \if:Option
\def\early:sup{%
\xdef\recall:sup{%
\mathcode‘\noexpand\^=\the\mathcode‘\^
\catcode‘\noexpand\^=\the\catcode‘\^
}
\mathcode‘\^="8000 \catcode‘\^=13
}
\else
\def\early:sup{%
\xdef\recall:sup{%
\mathcode‘\noexpand\^=\the\mathcode‘\^
\catcode‘\noexpand\^=\the\catcode‘\^
% \immediate\write16{.....sup \the\catcode‘\^}%
}%
\mathcode‘\^="8000 \catcode‘\^=12
% \immediate\write16{.....sup 12}%
}
\fi
\fi
\else
\Log:Note{for \string^ at preamble,
use the command line option ‘early\string^’}%
\fi
-_-_-
The requests are placed on symbols of the fonts, which might be a problem for symbols not used in math.
<..math classes..>
\def\MathClass{\ht:special{t4ht\string^}}
\let\EndMathClass=\MathClass
\def\PauseMathClass{\ht:special{t4ht\string^-}}
\def\EndPauseMathClass{\ht:special{t4ht\string^+}}
-_-_-
Math classes: Ordinary (0), large operators (1), binary operators (2), relation (3), opening del (4), closing delimiter (5), punctuation (7).
Set the class delimiters for the symbols.
<..math classes..>+
\catcode‘\^=7
\NewConfigure{MathClass}[5]{\NoFonts \ht:special{t4ht@[}%
\def\:temp{#2}\ifx \:temp\empty \else
\ht:special{t4ht\string^#1#2#3#2#4}\fi
\def\:temp{#5}\ifx \:temp\empty \else
\bgroup \everypar{}\everymath{}\everydisplay{}%
\hbox{${\ht:special{t4ht\string^#1}%
{#5}^{{#5}^{#5}}\ht:special{t4ht\string^}}$}%
\vbox{$${\ht:special
{t4ht\string^#1}{#5}^{{#5}^{#5}}\ht:special{t4ht\string^}}$$}\egroup
\fi
{\everypar{}\noindent\vfill\break}%
\ht:special{t4ht@]}\EndNoFonts
}
\NewConfigure{MathDelimiters}[2]{\NoFonts \ht:special{t4ht@[}%
\bgroup \everypar{}\everymath{}\everydisplay{}%
\hbox{${\ht:special
{t4ht\string^4}#1\ht:special{t4ht\string^5}#2%
\ht:special{t4ht\string^4}{}^{#1}\ht:special{t4ht\string^5}{}^{#2}%
\ht:special{t4ht\string^4}{}^{{}^{#1}}\ht:special
{t4ht\string^5}{}^{{}^{#2}}%
\ht:special{t4ht\string^}}$}%
\vbox{$${\ht:special
{t4ht\string^4}#1\ht:special{t4ht\string^5}#2%
\ht:special{t4ht\string^4}{}^{#1}\ht:special{t4ht\string^5}{}^{#2}%
\ht:special{t4ht\string^4}{}^{{}^{#1}}\ht:special
{t4ht\string^5}{}^{{}^{#2}}%
\ht:special{t4ht\string^}}$$}%
{\everypar{}\noindent\vfill\break}%
\ht:special{t4ht@]}\egroup
\EndNoFonts}
\catcode‘\^=12
-_-_-
<..math classes..>+
\HAssign\New:MathClass=7
\catcode‘\/=0
\catcode‘\\=12
/def/NewMathClass#1{/relax
/expandafter/ifx /csname /expandafter/:gobble/string#1/endcsname/relax
/gHAdvance/New:MathClass by 1/relax
/ifnum /New:MathClass>78
/:warning{Too many math classes}
/else
/HAssign#1/New:MathClass /def/:tempc{#1}/:NewMC
0123456789:;<=>?%
@ABCDEFGHIJKLMNO%
PQRSTUVWXYZ[\]{/string^}{/string_}%
‘abcdefghijklmno%
pqrstuvwxyz{/string{}|{/string}}{/string~}<.par del.>%
/fi
/else
/:warning{/string#1 is already defined}
/fi}
/catcode‘/\=0
\catcode‘\/=12
\def\:NewMC#1{%
\ifnum \:tempc=0 \expandafter\xdef\:tempc{#1}\expandafter\stop:do
\else
\expandafter\HAdvance\:tempc by -1\relax
\expandafter\:NewMC
\fi
}
-_-_-
79 math classes: 0–78.
<..math classes..>+
\NewConfigure{nolimits}[1]{\def\:temp{#1}\ifx \:temp\empty
\let\nolimits=\o:nolimits: \else
\def\:temp{\o:nolimits:\futurelet\:temp\:nolimits}%
\def\:nolimits{\ifx \:temp\limits \else
\ifx \:temp\nolimits \else #1\fi\fi}%
\HLet\nolimits=\:temp \fi}
\let\o:nolimits:=\nolimits
\NewConfigure{limits}[1]{\def\:temp{#1}\ifx \:temp\empty
\let\limits=\o:limits: \else
\def\:limits{\ifx \:temp\nolimits \else#1\fi}%
\def\:temp{\o:limits:\:l:mits}%
\HLet\limits=\:temp \fi}
\let\o:limits:=\limits
\def\::limits{\expandafter\ifx \blank:spc\:temp
\afterassignment\:l:mits \tmp:cnt0%
\else
\ifx \limits\:temp\else
\expandafter\expandafter\expandafter\:limits
\fi
\fi}
\def\:l:mits{\futurelet\:temp\::limits}
\catcode‘\ =13\relax\def\blank:spc{\let\blank:spc= }\blank:spc%
\catcode‘\ =10\relax
-_-_-
Test case to check: \[\sum\nolimits\limits_a^b u_s^2 \]
The assignment \tmp:cnt0% also consumes the space that follows.
<..math classes..>+
\NewConfigure{displaylimits}[1]{\def\:temp{#1}\ifx \:temp\empty
\let\displaylimits=\o:displaylimits: \else
\def\:displaylimits{\ifx \:temp\nolimits \else
\ifx \:temp\limits \else #1\fi\fi}%
\def\:temp{\o:displaylimits:\display:l:mits}%
\HLet\displaylimits=\:temp \fi}
\let\o:displaylimits:=\displaylimits
\def\::displaylimits{\expandafter\ifx \blank:spc\:temp
\afterassignment\display:l:mits \tmp:cnt0%
\else\expandafter\:displaylimits \fi}
\def\display:l:mits{\futurelet\:temp\::displaylimits}
-_-_-
\mathord{...} et al request delimiters for their arguments. The \special{t4ht^X} , for ‘ ’-‘0’ (digit) greater than 79, request the delimiters of class 0 to apply to the next group (created by the math ord). The 0 asks to ignore nested delimiters; can be replaced by 1 to request the sub delimiters.
A \special{t4ht\string^)*...*...} is variant of \Send{Group}{1}... \Send{EndGroup}{1} for delimiters, without subdelimiters. Taking ( (or any other character which below a digit and not + or -) instead of ) gives also the subdelimiters.
A \special{t4ht\string^i)} takes the delimiters from the characters of class i.
<..grouped math classes..>
\def\:temp{\a:mathord \o:mathord:} \HLet\mathord=\:temp
\let\a:mathord=\empty
\def\:temp{\a:mathop \o:mathop:} \HLet\mathop=\:temp
\let\a:mathop=\empty
\def\:temp{\a:mathbin \o:mathbin:} \HLet\mathbin=\:temp
\let\a:mathbin=\empty
\def\:temp{\a:mathrel \o:mathrel:} \HLet\mathrel=\:temp
\let\a:mathrel=\empty
\def\:temp{\a:mathopen \o:mathopen:} \HLet\mathopen=\:temp
\let\a:mathopen=\empty
\def\:temp{\a:mathclose \o:mathclose:} \HLet\mathclose=\:temp
\let\a:mathclose=\empty
\def\:temp{\a:mathpunct \o:mathpunct:} \HLet\mathpunct=\:temp
\let\a:mathpunct=\empty
-_-_-
<..grouped math classes..>+
\NewConfigure{FormulaClass}[4]{%
\def\:temp{#2}%
\expandafter\edef\csname a:\ifcase #1 mathord\or mathop\or
mathbin\or mathrel\or mathopen\or mathclose\else
mathpunc\fi\endcsname{\noexpand\ht:special
{t4ht\string^\ifx\:temp\empty#1)\else )#2#3#2#4\fi}}}
-_-_-
\Configure{FormulaClass}{class number}{char}{before}{after}: char+before+after=empty implies same markings as for single characters. In fact, can do the same for any sub formula with any function, not just the math functions.
<..grouped math classes..>+
\NewConfigure{FormulaClass*}[4]{%
\def\:temp{#2}%
\expandafter\edef\csname a:\ifcase #1 mathord\or mathop\or
mathbin\or mathrel\or mathopen\or mathclose\else
mathpunc\fi\endcsname{\ht:special
{t4ht\string^\ifx\:temp\empty#1(\else (#2#3#2#4\fi}}}
-_-_-
The following are generalizations, introduced for allowing temporary changs, like in \renewcommand{\opname}[1]{% \Configure{mathop*}{*}{<mrow>}{</mrow>}{\Configure{FormulaClass}{0}{}{}{}} \mathop{\fam0#1}}.
<..grouped math classes..>+
\NewConfigure{mathord}[4]{\Configure{FormulaClass}{0}{#1}{#2}{#3}%
\pend:def\a:mathord{#4}}
\NewConfigure{mathop}[4]{\Configure{FormulaClass}{1}{#1}{#2}{#3}%
\pend:def\a:mathop{#4}}
\NewConfigure{mathbin}[4]{\Configure{FormulaClass}{2}{#1}{#2}{#3}%
\pend:def\a:mathbin{#4}}
\NewConfigure{mathrel}[4]{\Configure{FormulaClass}{3}{#1}{#2}{#3}%
\pend:def\a:mathrel{#4}}
\NewConfigure{mathopen}[4]{\Configure{FormulaClass}{4}{#1}{#2}{#3}%
\pend:def\a:mathopen{#4}}
\NewConfigure{mathclose}[4]{\Configure{FormulaClass}{5}{#1}{#2}{#3}%
\pend:def\a:mathclose{#4}}
\NewConfigure{mathpunct}[4]{\Configure{FormulaClass}{6}{#1}{#2}{#3}%
\pend:def\a:mathpunct{#4}}
-_-_-
<..grouped math classes..>+
\NewConfigure{mathord*}[4]{\Configure{FormulaClass*}{0}{#1}{#2}{#3}%
\pend:def\a:mathord{#4}}
\NewConfigure{mathop*}[4]{\Configure{FormulaClass*}{1}{#1}{#2}{#3}%
\pend:def\a:mathop{#4}}
\NewConfigure{mathbin*}[4]{\Configure{FormulaClass*}{2}{#1}{#2}{#3}%
\pend:def\a:mathbin{#4}}
\NewConfigure{mathrel*}[4]{\Configure{FormulaClass*}{3}{#1}{#2}{#3}%
\pend:def\a:mathrel{#4}}
\NewConfigure{mathopen*}[4]{\Configure{FormulaClass*}{4}{#1}{#2}{#3}%
\pend:def\a:mathopen{#4}}
\NewConfigure{mathclose*}[4]{\Configure{FormulaClass*}{5}{#1}{#2}{#3}%
\pend:def\a:mathclose{#4}}
\NewConfigure{mathpunct*}[4]{\Configure{FormulaClass*}{6}{#1}{#2}{#3}%
\pend:def\a:mathpunct{#4}}
-_-_-
The \MathSymbol works on empty when the symbol comes from a font. That is, when the macro is defined as \mathchar"xxxx. A \MathSymbol+ variant may be applied to force definitions. Warning messages are not helpful as the symbols may have nultiple definitions dependent on the style files being loaded.
<..built-in tex math ops..>
\def\MathSymbol{\futurelet\:temp\:::MathSymbol}
\def\:::MathSymbol{\if +\:temp
\expandafter\:MathSymbol \else
\expandafter\::MathSymbol \fi
}
\def\::MathSymbol#1#2{%
\def\:tempb##1"##2///{##1}%
\edef\:tempa{\expandafter\expandafter\expandafter\:tempb
\expandafter\meaning\csname#2\endcsname"///}%
\edef\:tempc{\string\mathchar}%
\ifx \:tempa\:tempc
\NewConfigure{#2}{1}\Configure{#2}{\csname o:#2:\endcsname}%
\else
\:MathSymbol{}{#1}{#2}%
\fi
}
\def\:MathSymbol#1#2#3{%
\def\:temp{{\math:sym#2{#3}}}%
\expandafter\HLet\csname #3\endcsname\:temp
\NewConfigure{#3}{1}\Configure{#3}{\csname o:#3:\endcsname}%
}
\def\math:sym#1#2{{\relax\ifmmode \expandafter#1\fi
{\csname a:#2\endcsname}}}
-_-_-
Again, we don’t want line breaks from <PRE>s within formulas in visual browsers.
<..built-in tex math ops..>+
\def\:temp#1{\a:left{#1}\o:left:#1\b:left{#1}}
\HLet\left=\:temp
\def\:temp#1{\a:right{#1}\o:right:#1\b:right{#1}}
\HLet\right=\:temp
\NewConfigure{left}[2]{\def\a:left##1{#1}\def\b:left##1{#2}}
\NewConfigure{right}[2]{\def\a:right##1{#1}\def\b:right##1{#2}}
\Configure{left}{}{}
\Configure{right}{}{}
-_-_-
<..built-in tex math ops..>+
\def\:tempc{\pic:gobble\a:over \o:over: \pic:gobble\b:over}
\HLet\over=\:tempc
\NewConfigure{over}{2}
\def\:tempc{\pic:gobble\a:atop \o:atop: \pic:gobble\b:atop}
\HLet\atop\:tempc
\NewConfigure{atop}{2}
\def\::above{\pic:gobble\a:above \o:above:\tmp:dim
\pic:gobble\b:above }
\def\:above{\afterassignment\::above}
\def\:tempc{\Protect\:above \tmp:dim=}
\HLet\above\:tempc
\NewConfigure{above}{2}
-_-_-
<..built-in tex math ops..>+
\def\::abovewithdelims#1#2{\pic:gobble\a:abovewithdelims
\o:abovewithdelims:#1#2\tmp:dim\pic:gobble\b:abovewithdelims}
\def\:abovewithdelims#1#2{\def\:temp{\::abovewithdelims#1#2}%
\afterassignment\:temp\tmp:dim=}
\def\:tempc{\Protect\:abovewithdelims }
\HLet\abovewithdelims\:tempc
\NewConfigure{abovewithdelims}{2}
\def\:overwithdelims#1#2{\pic:gobble\a:overwithdelims
\o:overwithdelims:#1#2\pic:gobble\b:overwithdelims}
\def\:tempc{\Protect\:overwithdelims}
\HLet\overwithdelims\:tempc
\NewConfigure{overwithdelims}{2}
\def\:atopwithdelims#1#2{\pic:gobble\a:atopwithdelims
\o:atopwithdelims:#1#2\pic:gobble\b:atopwithdelims}
\def\:tempc{\Protect\:atopwithdelims}
\HLet\atopwithdelims\:tempc
\NewConfigure{atopwithdelims}{2}
-_-_-
\Configure{over} {\Send{GROUP}{0}{[before]}[before-rule]} {[before-argument]\Send{EndGROUP}{0}{[after]}}
\Configure{over} {\special{t4ht\string~<<NOMINATOR>}\HCode {</NOMINATOR><DENOMINATOR>}} {\special{t4ht\string~></DENOMINATOR>}}
Beware of nested formulas for proper arrangments of \special{t4ht\string~...}
<..built-in tex math ops..>+
\def\:temp{\pic:gobble\a:radical\o:radical:}
\HLet\radical=\:temp
\NewConfigure{radical}{1}
-_-_-
The following is disabled because TEX evaluates the four parameters and then keeps one and throws away the other. With the picture environment enabled, we’ll get messages in the log file of the form --- needs --- a.idv[1] ==> ai.gif --- for pictures that are not included in the code.
<..built-in tex math ops..>+
\def\:temp#1#2#3#4{\a:mathchoice
\o:mathchoice:{#1}{#2}{#3}{#4}\b:mathchoice }
\HLet\mathchoice=\:temp
\NewConfigure{mathchoice}{2}
-_-_-
The following, for \?phantom, is not needed because it is already covered by \mathchoice.
The \eqno and \leqno refer to what follow them in the math environment as left and right equation numbers, respectively. Tex typesets them within groups, so material can be sent to the end of the number with a \Send{GROUP}{0}{...}.
<..built-in tex math ops..>+
\def\:temp{\o:eqno:\a:eqno}
\HLet\eqno=\:temp
\def\:temp{\o:leqno:\a:leqno}
\HLet\leqno=\:temp
\NewConfigure{eqno}{1}
\NewConfigure{leqno}{1}
-_-_-
In addition, 1140. We get into ordinary math mode from display math mode when the equation numbers \eqno and \leqno appear. Hence, the \everymath{} is needed also for the display case. To be on the sure side, we also put \everydisplay{} in the math mode.