# Browser Support

Temml works in browsers that support MathML. This includes Chrome, Edge, Firefox, and Safari. Temml will never work in Internet Explorer.

# Installation

For use in the browser, you can download a zip file of Temml from the releases page of the Temml repository. For server-side use, you can obtain Temml via CLI commands npm install temml or yarn add temml.

The minimum browser installation needs the following files. The css file and font file must be in the same folder.

• temml.min.js
• Temml-Local.css
• Temml.woff2

A server-side installation should use temml.cjs or temml.mjs instead of temml.min.js.

#### Starter template

<!DOCTYPE html>
<!-- Temml requires the use of the HTML5 doctype. -->
<html>
...
<script src="./temml.min.js"></script>
...
</html>

# API

### Overview

Say that you have an HTMLCollection of elements whose contents should be converted from TeX strings to math. The code for such a conversion might look like this:

Option 1: Macros do not persist between calls to Temml:

// Render all the math.
for (let aSpan of [...mathSpans]) {
const tex = aSpan.textContent;
const displayMode = aSpan.classList.contains("display");
temml.render(tex, aSpan, { displayMode });
}
// Optional postProcess to render \ref{}
temml.postProcess(document.body);
Option 2: Macros defined with \gdef do persist:
// Optional macros object to hold macros that persist between calls to Temml.
const macros = {}
// Render all the math.
for (let aSpan of [...mathSpans]) {
const tex = aSpan.textContent;
const displayMode = aSpan.classList.contains("display");
// Notice the macros argument below.
// It carries macros that were defined with \gdef or \global\let
temml.render(tex, aSpan, { macros, displayMode });
}
// Optional postProcess to render \ref{}
temml.postProcess(document.body);

Notice that you can choose when to stop macro persistence by redefining macros.

Option 3: Macros persist and there are some predefined macros:

Now say that you wish to pre-define two macros and a color with document-wide scope.

// Optional preamble to pre-define macros.
const macros = temml.definePreamble(
\\newcommand\\d[0]{\\operatorname{d}\\!}
\\def\\foo{x^2}
\\definecolor{sortaGreen}{RGB}{128,128,0}
);
// Render all the math.
for (let aSpan of [...mathSpans]) {
const tex = aSpan.textContent;
const displayMode = aSpan.classList.contains("display");
temml.render(tex, aSpan, { macros, displayMode });
}
// Optional postProcess to render \ref{}
temml.postProcess(document.body);

Below, we examine the parts of that code.

### In-Browser

To render math in one DOM element, call temml.render with a TeX expression and a DOM element to render into:

temml.render("c = \\pm\\sqrt{a^2 + b^2}", element);

If the element you provide is a [itex] element, Temml will populate it. Otherwise, it will create a new [itex] element and make it a child of the element you provide.

### Server-Side

To generate MathML on the server or to generate an MathML string of the rendered math, you can use temml.renderToString:

const temml = require('./temml.cjs');  // if in Node.js
const mathML = temml.renderToString("c = \\pm\\sqrt{a^2 + b^2}");

### Preamble

To give document-wide scope to a set of macros or colors, define them in a preamble.

const macros = temml.definePreamble(
\\newcommand\\d[0]{\\operatorname{d}\\!}
\\def\\foo{x^2}
\\definecolor{sortaGreen}{RGB}{128,128,0}
);

Any valid Temml macro or \definecolor may be written into a preamble. Then include the resulting macros in the Temml options.

### Options

You can provide an object of options as the last argument to temml.render and temml.renderToString. For example:

temml.render(
"c = \\pm\\sqrt{a^2 + b^2}",
element,
{ displayMode: true,  macros }
);

Available options are:

• displayMode: boolean. If true the math will be rendered in display mode, which will put the math in display style (so \int and \sum are large, for example), and will center the math on the page on its own line. If false the math will be rendered in inline mode. (default: false)

• macros: object. A collection of custom macros. The easy way to create them is via a preamble, noted just above. Alternatively, you can provide a set of key-value pairs in which each key is a new Temml function name and each value is the expansion of the macro. Example: macros: {"\\R": "\\mathbb{R}"}.

• annotate: boolean. If true, Temml will include an <annotation> element that contains the input TeX string. (default: false)

• wrap: ("tex" | "="). A mode for soft line breaks in non-display mode math. The tex option sets a soft line break after every top-level relation and binary operator, per The TeXbook, page 173. The = option sets a soft line break before the second and subsequent top-level = signs. tex is the default.

Caveats: Soft line breaks work in Chromium and Firefox, but do not work in WebKit or Safari. Display mode math gets no soft line breaks. Annotated math gets no soft line breaks. If a writer sets a hard line break via \\ or \cr, then Temml will not set any soft line breaks in that expression.

• leqno: boolean. If true, display math has \tags rendered on the left instead of the right, like \usepackage[leqno]{amsmath} in LaTeX. (default: false)

• colorIsTextColor: boolean. In LaTeX, \color is a switch, but in early versions of MathJax and KaTeX, \color applied its color to a second argument, the way that LaTeX \textcolor works. Set option colorIsTextColor to true if you want \color to work like early MathJax or KaTeX. (default: false)

• errorColor: string. A color string given in the format "#XXX" or "#XXXXXX". This option determines the color that unsupported commands and invalid LaTeX are rendered in. (default: #b22222)

• maxSize: [number, number]. This provides a way to cap all user-specified sizes, e.g. in \rule{500em}{500em}. The first number is the cap in em units, which will be applied to user-specified relative units. The second number is the cap in CSS pt units, which will be applied to user-specified absolute units. The default is [Infinity, Infinity], which allows users to make elements and spaces arbitrarily large.

• maxExpand: number. Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX. (default: 1000)

• strict: boolean. If false (similar to MathJax), allow features that make writing LaTeX convenient but are not actually supported by LaTeX. If true (LaTeX faithfulness mode), throw an error for any such transgressions. (default: false)

• xml: boolean. If true, Temml will write a namespace into the [itex] element. That namespace is xmlns="http://www.w3.org/1998/Math/MathML". Such a namespace is unnecessary for modern browsers but may be helpful for other user agents. (default: false)

• trust: boolean or function (default: false). If false (do not trust input), prevent any commands like \includegraphics that could enable adverse behavior, rendering them instead in errorColor. If true (trust input), allow all such commands. Provide a custom function handler(context) to customize behavior depending on the context (command, arguments e.g. a URL, etc.). A list of possible contexts:

• {command: "\\url", url, protocol}
• {command: "\\href", url, protocol}
• {command: "\\includegraphics", url, protocol}
• {command: "\\class", class}
• {command: "\\id", id}
• {command: "\\style", style}
• {command: "\\data", attributes}

Here are some sample trust settings:

• Forbid specific command: trust: (context) => context.command !== '\\includegraphics'
• Allow specific command: trust: (context) => context.command === '\\url'
• Allow multiple specific commands: trust: (context) => ['\\url', '\\href'].includes(context.command)
• Allow all commands with a specific protocol: trust: (context) => context.protocol === 'http'
• Allow all commands with specific protocols: trust: (context) => ['http', 'https', '_relative'].includes(context.protocol)
• Allow all commands but forbid specific protocol: trust: (context) => context.protocol !== 'file'
• Allow certain commands with specific protocols: trust: (context) => ['\\url', '\\href'].includes(context.command) && ['http', 'https', '_relative'].includes(context.protocol)

## Post Process

The postProcess function implements the AMS functions \ref and \label. It should be called outside of any loop.

The main Temml functions, temml.render and temml.renderToString, each operate on only one element at a time. In contrast, the postProcess function makes two passes through the entire document. If you choose not to support \ref, postProcess can be omitted.

If Temml is used server-side, \ref and \label are still implemented at runtime with client-side JavaScript. A small file, temmlPostProcess.js, is provided to be installed in place of temml.min.js. It exposes one function:

temml.postProcess(document.body)

If you do not provide a runtime postProcess, everything in Temml will work except \ref.

If you use the auto-render extension, it includes the post-processor nuances.

# Fonts

Temml has several different pre-written CSS files. You should use only one and by that choice, you also choose a math font. There are several math fonts available and each has different advantages.

Temml-Local.css is the light-weight option. It calls two fonts: Cambria Math, which comes pre-installed in Windows, or STIX TWO, which comes pre-installed in iOS and MacOS (as of Safari 16). Cambria Math lacks roundhand glyphs, so you still have to serve a small (12 kb) font, Temml.woff2, in order to support \mathscr{…}.
Android does not currently provide a font with a MATH table. They are considering several options.

Sadly, native fonts render math with a couple of flaws. In Firefox, square root radicals are sometimes oddly sized. Chromium is better at radicals, but it fails to stretch five stretchy accents and some extensible arrows. Chromium also renders extensible arrows with notes placed too high.

Latin Modern is a clone of Computer Modern and so is very home-like for readers accustomed to LaTeX documents. Rendering is excellent except that some line thicknesses may be too thin for some screens. This option also needs that additional 12kb Temml.woff2 file in order to support \mathscr{…}.

Asana and Libertinus have some of the same rendering problems as Cambria Math, although Asana does contain its own roundhand glyphs.

Several other math fonts exist and you can try them out at Frédéric Wang’s Mathematical OpenType Fonts.

Where to find font files:

If you want a different math font size, you can add a rule to your own page's CSS, like this example:

math { font-size: 125%; }

# Equation numbering

In order to place automatic equation numbering in certain AMS environments, Temml contains these CSS rules:

.tml-eqn::before {
counter-increment: tmlEqnNo;
content: "(" counter(tmlEqnNo) ")";
}
body { counter-reset: tmlEqnNo; }

You can overwrite the content rule to produce customized equation numbers. For instance, if chapter three of your book is in its own html file, that file’s <head> could contain:

<style>
.tml-eqn::before { content: "(3." counter(tmlEqnNo) ")"; }
</style>

Then the automatic equation numbering in that chapter would look like: (3.1)

If your site does not render automatic numbering properly, check if your other CSS has overwritten the Temml counter-reset.

# Extensions

More Temml functionality can be added via the following extensions:

• auto-render: Find and render all math in a running HTML page.
• mhchem: Write beautiful chemical equations easily.
• physics: Implement much of the LaTeX physics package.
• texvc: Support functions used in wikimedia.

To install extensions for browser use, include the appropriate file from the contrib folder of the Temml repository. Then reference the file in the <head> of the HTML page. As in this mhchem example:

  <head>
...
<script src="./temml.min.js"></script>
<script src="./mhchem.min.js"></script>
</head>

The extension reference must come after the reference to temml.min.js.

For server-side use, just use temml.cjs instead of temml.min.js. temml.cjs includes mhchem, physics, and texvc.

# Security

Any HTML generated by Temml should be safe from <script> or other code injection attacks.

A variety of options give finer control over the security of Temml with untrusted inputs; refer to Options for more details.

• maxSize can prevent large width/height visual affronts.
• maxExpand can prevent infinite macro loop attacks.
• trust can allow certain commands that may load external resources or change HTML attributes and thus are not always safe (e.g., \includegraphics or \class)