question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support a rendering option for a preamble string of LaTeX command definitions

See original GitHub issue

Is 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 of MacroExpander as first argument and returns the expansion as a string. MacroExpander is 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:

  1. 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.
  2. 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:open
  • Created 2 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
pdmossescommented, Apr 18, 2021

that looks like a reasonably straightforward way of adding a preamble using pure LaTeX command definitions (at least for Jekyll/kramdown users)

On a Jekyll website, simply add the command definitions in some file _includes/my-preamble.sty:

\newcommand{\First}[2]{#1}
\newcommand{\Second}[2]{#2}

Then use the following in (Markdown or HTML) pages where the preamble is needed:

<div style="display: none">
  \(
  {% include my-preamble.sty %}
  \)
</div>

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:

---
layout: default
math: katex
---
<div style="display: none">
  \(
  {% include cbs-katex.sty %}
  \)
</div>

{{ content }}

(assuming that the head element loads KaTeX when layout.math == "katex").

Then pages with layout: my-layout in the front matter load both KaTeX and the command definitions in my-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 macros object, and for escaping backslashes. The constraints are that it requires the use of Jekyll and the rendering option globalGroup: true. See the source files at https://github.com/plancomps/cbs-latex for a demonstration of its use.

0reactions
pdmossescommented, Apr 9, 2021

I was looking for something to put in the head element, together with the KaTeX script and options, so it would automatically be included on all KaTeX pages on my site.

With globalGroup: true I 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:

<div style="display: none"  markdown="block">
$$
  \newcommand{\First}[2]{#1}
  \newcommand{\Second}[2]{#2}
$$
</div>

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 preamble environment seems more principled and flexible.

I’m not sure what interface you had in mind for renderMathInElementWithPreamble.

The same as for renderMathInElement – it would hide the details of accessing document.getElementById('preamble') and adding the definitions in it to the macros object.

I also don’t know how easy it is to add custom script languages.

The MIME type application/x-latex already exists. I’ve never tried using a script with an id to provide data to another script, but it appears to be a standard technique.

Read more comments on GitHub >

github_iconTop Results From Across the Web

make4ht cannot render newcommand in mathjax mode - TeX
I find some solution says I have to add something to cfg file, but I do not want to do that, because I...
Read more >
LaTeX customization - Sphinx documentation
A string which will be positioned early in the preamble, designed to contain \\PassOptionsToPackage{options}{foo} commands.
Read more >
LatexModePlugin < Plugins < TWiki
Rendering can be performed by ( latex and dvipng ) or ( latex and dvips and convert ) or ( pdflatex and convert...
Read more >
Text rendering with LaTeX — Matplotlib 3.6.2 documentation
Only a small number of font families (defined by the PSNFSS scheme) are supported. They are listed here, with the corresponding LaTeX font...
Read more >
pelican-katex - PyPI
The KATEX_PREAMBLE option allows you to share definitions between all of your math blocks across all files. It takes a string of any...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found