Support a rendering option for a preamble string of LaTeX command definitions
See original GitHub issueIs your feature request related to a problem? Please describe.
When defining a command using \newcommand, the number of arguments that it takes is explicit, and not all arguments need to be used in the expansion. For example, after:
\newcommand{\First}[2]{#1}
\newcommand{\Second}[2]{#2}
KaTeX renders \First{A}{B}, \Second{C}{D} correctly as ‘A, D’.
When defining a KaTeX macro as a string in the rendering options, however, the number of arguments that it takes is implicit. The documentation states:
Each macro is a property with a name like
\name(written"\\name"in JavaScript) which maps to a string that describes the expansion of the macro, or a function that accepts an instance ofMacroExpanderas first argument and returns the expansion as a string.MacroExpanderis an internal API and subject to non-backwards compatible changes. See src/macros.js for its usage.
The above commands do not work if converted to KaTeX macro definitions simply as strings. With:
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.13.2/dist/contrib/auto-render.min.js" integrity="sha384-vZTG03m+2yp6N6BNi5iM4rW4oIwk5DfcNdFfxkk9ZWpDriOkXX8voJBFrAO7MpVl" crossorigin="anonymous"
onload="renderMathInElement(document.body, {
macros: {
'\\FirstMacro': '#1',
'\\SecondMacro': '#2'
}
});"></script>
the JavaScript console shows:
TypeError: undefined is not an object (evaluating 't.text')
and KaTeX renders \FirstMacro{A}{B}, \SecondMacro{C}{D} incorrectly asAB, \(\SecondMacro{C}{D}\).
There are JavaScript definitions of corresponding commands in src/macros.js, but it isn’t obvious how to write them as objects in the macros rendering option.
Describe the solution you’d like:
I’d like a new rendering option preamble: string. The string would consist entirely of LaTeX command definitions. KaTeX would convert it internally to the corresponding collection of macros.
Ideally, environment definitions and optional arguments would be allowed too.
The commands defined in the preamble would automatically be global.
Link to or name of a (La)TeX package that provides the same feature:
LaTeX allows command definitions before \begin{document}.
The LaTeXiT app allows the default preamble used for formatting equations to be edited.
Describe alternatives you’ve considered:
- For macros that take arguments, the MathJax configmacros extension insists on specifying the number of arguments, and supports optional arguments. However, the macro definitions are not easy to read, and it is tedious to convert between macro definitions and the corresponding LaTeX command definitions.
- Require KaTeX users to be fluent in JavaScript 😄
Additional context:
I’m using the macros rendering option instead of \newcommand because I need to define the same collection of LaTeX commands on many pages on the same website. When providing sample pages on a different website, I wanted to remove the external hyperlinks provided by a macro; but editing the macro definition led to an argument not being used in the expansion, as with the definition of \SecondMacro above. I ended up having to insert \renewcommands on the sample pages.
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (3 by maintainers)

Top Related StackOverflow Question
On a Jekyll website, simply add the command definitions in some file
_includes/my-preamble.sty:Then use the following in (Markdown or HTML) pages where the preamble is needed:
To avoid repetition of that rather ugly mixture of HTML, LaTeX, and Jekyll/Liquid code on multiple pages, it can be moved to a layout, e.g.,
_layouts/my-layout.html:(assuming that the
headelement loads KaTeX whenlayout.math == "katex").Then pages with
layout: my-layoutin the front matter load both KaTeX and the command definitions inmy-preamble.sty. (Jekyll’s front-matter defaults allow repetition of the layout to be avoided.)This technique avoids the need for encoding KaTeX command definitions in the
macrosobject, and for escaping backslashes. The constraints are that it requires the use of Jekyll and the rendering optionglobalGroup: true. See the source files at https://github.com/plancomps/cbs-latex for a demonstration of its use.I was looking for something to put in the
headelement, together with the KaTeX script and options, so it would automatically be included on all KaTeX pages on my site.With
globalGroup: trueI can use kramdown math blocks to insert the required command definitions manually at the beginning of the Markdown source for the bodies of individual web pages:To use the same preamble for a collection of pages, I could put it in a custom layout, so Jekyll would insert it automatically on pages using that layout instead of the default one. It’s easy enough to use custom layouts with Jekyll, so that looks like a reasonably straightforward way of adding a preamble using pure LaTeX command definitions (at least for Jekyll/kramdown users). But using a special
preambleenvironment seems more principled and flexible.The same as for
renderMathInElement– it would hide the details of accessingdocument.getElementById('preamble')and adding the definitions in it to themacrosobject.The MIME type
application/x-latexalready exists. I’ve never tried using a script with anidto provide data to another script, but it appears to be a standard technique.