Classical TeX and pdfTeX have a limit of maximal 16 math families of fonts in one formula. OPmac uses `ams-math.tex`

or `tx-math.tex`

and these macros allocate 12 resp. 14 math families statically (for whole document). But you can allocate less math families statically and other families will be allocated dynamically (on demand) inside each formula. The result: you can have arbitrary number of math families in your document (but the limit 16 to one formula is still valid).

We create a macro `\dfam{family-name}`

which behaves similar as `\fam=family-number`

inside formula, but the family is dynamically allocated. Moreover, we create a macro

```
\dmathchardef \sequence class{family-name}hexa-code
```

which declares the `\sequence`

similarly as `\matchardef`

does it, but the appropriate math family is dynamicaly allocated only if the `\sequence`

is used in the formula. For example, we suppose that the families eufm (for fractur) and rsfs (for script) are not loaded statically. Then you can declare families at beginning of your document:

```
% in general: \sdef{dfam:family-name}{font-name-as-in-\loadmathfamily}
\sdef{dfam:fractur}{eufm} \def\fractur{\dfam{fractur}}
\sdef{dfam:script}{rsfs} \def\script{\dfam{script}}
% ...
\dmathchardef\foo 0{fractur}00 % character class 0 code 00 (hex) from fractur family
% ...
```

and next you can use it:

```
$a \times {\script B} = {\fractur C}$, a taky $ \beta = \foo^2 $.
```

Two formulae are in this example. The script and fractur families are loaded in the first formula and only fractur is loaded in the second formula. Of course, the statically loaded families are used in both formulae too.

The implementation:

```
\chardef\numfamilies=\count18 % the number of statically loaded families
\everymath={\dfamstart} \everydisplay{\dfamstart} \def\dfamlist{}
\def\dfamstart{\aftergroup\dfamreset \let\dfamstart=\relax}
\def\dfamreset{\global\count18=\numfamilies \gdef\dfamlist{}}
\def\dfam#1{\relax
\expandafter\ifx\csname dfam:#1\endcsname \relax
\opwarning{dynamic math family "#1" is not declared}%
\else
\isinlist\dfamlist{,#1,}\iftrue \else
\begingroup \def\wlog##1{}%
\csname newfam\expandafter\endcsname \csname dmn:#1\endcsname
\globaldefs=1
\loadmathfamily{\csname dmn:#1\endcsname} {\csname dfam:#1\endcsname}
\endgroup
\global\addto\dfamlist{,#1,}%
\tmpnum=\csname dmn:#1\endcsname
\ifnum \tmpnum<10 \sxdef{dmh:#1}{\the\tmpnum}\else
\advance\tmpnum by-10
\sxdef{dmh:#1}{\ifcase\tmpnum A\or B\or C\or D\or E\or F\fi}%
\fi\fi
\fam=\csname dmn:#1\endcsname\relax
\fi
}
\def\dmathchar#1#2#3#4{\relax
\ifnum#1=0{\fi % 2^\foo will work, don't need to write 2^{\foo}
\isinlist\dfamlist{,#2,}\iftrue\else\begingroup\dfam{#2}\endgroup\fi
\mathchar"#1\csname dmh:#2\endcsname#3#4
\ifnum#1=0}\fi
}
\def\dmathchardef #1#2#3#4#5{\def#1{\dmathchar#2{#3}#4#5}}
\addprotect\dfam \addprotect\dmathchar
```

Dynamically allocated families are loaded by `\loadmathfamily`

on demand and with global settings. The names of such families are stored into `\famlist`

. The control sequence `\dmn:name`

includes the number of the family and `\dmh:name`

includes the hexa digit of such number. The data about loaded families are reset at the end of the formula using `\dfamreset`

. The nested formulae (like `\hbox{...$formula$...}`

inside another formula) don't reset the data because the `\dfamstart`

is set to `\relax`

temporary.

When `\dfam`

is used then small number of statically allocated families are recommended. You do this by redefining `\normalmath`

and `\boldmath`

and by decreasing the `\count18`

number. The families 0, 1, 2 ad 3 must be loaded statically because the metric information from these families is used by TeX in each formula.

If the family have the bold variant then you can declare such family like this:

```
\newif \ifboldmath \boldmathfalse
\addto\normalmath{\boldmathfalse} \addto\boldmath{\boldmathtrue}
% příklad eufm a eufb:
\sdef{dfam:fractur}{\ifboldmath eufb\else eufm\fi}
```