quarto-dev / quarto-cli

Open-source scientific and technical publishing system built on Pandoc.
https://quarto.org
Other
3.93k stars 325 forks source link

Defining custom macros is not possible with Katex #7518

Open abdalazizrashid opened 1 year ago

abdalazizrashid commented 1 year ago

Bug description

Enabling katex for doesn't expand macros

Steps to reproduce

---
format:
  html:
    html-math-method: katex
    include-in-header:
       text: |
        $$\newcommand{\E}{\mathbb{E}}$$
---

$\E$

Expected behavior

---
format:
  html:
    # html-math-method: katex
    include-in-header:
       text: |
        $$\newcommand{\E}{\mathbb{E}}$$
---

$\E$

Actual behavior

image

Your environment

Quarto check output

Quarto 1.4.489 [✓] Checking versions of quarto binary dependencies... Pandoc version 3.1.8: OK Dart Sass version 1.55.0: OK Deno version 1.33.4: OK [✓] Checking versions of quarto dependencies......OK [✓] Checking Quarto installation......OK Version: 1.4.489 Path: /Applications/quarto/bin

[✓] Checking tools....................OK TinyTeX: (not installed) Chromium: (not installed)

[✓] Checking LaTeX....................OK Using: Installation From Path Path: /Library/TeX/texbin Version: 2022

[✓] Checking basic markdown render....OK

[✓] Checking Python 3 installation....OK Version: 3.11.4 Path: /opt/homebrew/opt/python@3.11/bin/python3.11 Jupyter: 5.5.0 Kernels: python3

[✓] Checking Jupyter engine render....OK

[✓] Checking R installation...........OK Version: 4.2.0 Path: /Library/Frameworks/R.framework/Resources LibPaths:

mcanouil commented 1 year ago

Could please edit your title and/or post as currently it is very confusing? Your title mentioned KaTeX, your post is using HTML.

Also I am pretty sure, using a LaTeX macro definition is not going to work for JavaScript Math libraries such as KaTeX or MathJax. Please take a look at the library's documentation on how to define custom macros:

cscheid commented 1 year ago

EDIT: (I was wrong about katex vs mathjax)

@mcanouil It's pretty wild, but it kind of works. This works, for example:

---
format: html
---

$\newcommand{\E}{\mathbb{E}}$

## Hello.

$\E$

What's going on here is that MathJax actually knows how to deal with \newcommand.

But katex doesn't. That's not something we can fix.

mcanouil commented 1 year ago

Pandoc does let those passthrough as for LaTeX format and those libraries catch them in the body. 🤔😮

By the way, that's how it is stated in KaTeX documentation. if you want to define macro in the header, you need actual JavaScript code (also documented in KaTeX documentation).

if it does not work, it might a matter of version.

cderv commented 1 year ago

Pandoc does let those passthrough as for LaTeX format and those libraries catch them in the body.

You can defined Macros for MathJax in a math block and this will be available to other math block. https://docs.mathjax.org/en/latest/input/tex/macros.html?highlight=defining-tex-macros#defining-tex-macros So I don't think this is related to Pandoc letting those passthrough. Pandoc sees a Math block and make it a Mathjax compatible block syntax in HTML. Then Mathajx will process the \newcommand inside the math block.

But katex doesn't. That's not something we can fix.

KaTeX will by default do the opposite and consider each Math Block as independent in term of rendering. This means that a \newcommand in a blog will only apply to the current block

---
format: html
---

## Hello.

$$
\newcommand{\E}{\mathbb{E}}
\E
$$

It can work as Mathjax but I believe it requires to set the option globalGroup in katex.render(). Currently Pandoc does not allow to configure that, and Quarto does not modifies this.

There may be a KaTeX way but does not seem as easy as with MathJax through a script in header.

So I am not even sure there is a way to add Macros with KaTeX renderer easily without post processing the HTML. Maybe this is something we can offer with Quarto 🤔

i'll poke around

cderv commented 1 year ago

Side note from my tries:

cderv commented 1 year ago

@cscheid For future reference, I will reopen this as this is something we may want to consider adding until Pandoc supports it maybe - we already post process HTML for KaTeX related tweaks so we could probably offer the feature at some point if this is useful to users.

baptiste commented 12 months ago

By the way (I've read this cursorily), pandoc has the machinery to expand Latex macros (not too sure when it does/doesn't do it)

cderv commented 12 months ago

Wow this is wild ! Thanks @baptiste

This means this works

---
format: html
html-math-method: katex
---

\newcommand{\E}{\mathbb{E}}

## Hello.

$\E$

because \newcommand{\E}{\mathbb{E}} is going through Markdown parser as Raw LaTeX, and go through macros expension for all Math. This leads to this HTML to process by KaTeX

<section id="hello." class="level2">
<h2 class="anchored" data-anchor-id="hello.">Hello.</h2>
<p><span class="math inline">\mathbb{E}</span></p>
</section>

Note the \mathbb{E} and \newcommand{\E}{\mathbb{E}} is removed from the document, (as raw LaTeX are ignored in HTML outputs anyway)

However, this does not

---
format: html
---

$\newcommand{\E}{\mathbb{E}}$

## Hello.

$\E$

Because it leads to

<p><span class="math inline">\newcommand{\E}{\mathbb{E}}</span></p>
<section id="hello." class="level2">
<h2 class="anchored" data-anchor-id="hello.">Hello.</h2>
<p><span class="math inline">\E</span></p>
</section>

where $\newcommand{\E}{\mathbb{E}}$ is seen as inline Math - so not expanded by Pandoc, but pass through to the Math engine, and \E is kept as is.

I forgot Pandoc is working this way - quite useful but probably hard to explain ! I wonder if we could leverage that somehow 🤔 I believe this macros expansion is done in the Markdown.hs reader while processing Raw LaTeX block as part of raw_tex Pandoc's extension

baptiste commented 12 months ago

I've been using this trick to inject macros into each chapter of my book, for the html version:

_setup.qmd

```{r, echo=FALSE, results='asis'}
if (knitr::is_html_output()) {
  macros <- readLines('_macros.tex')
  writeLines(macros)
} 

and each chapter starts with 

{{< include _setup.qmd >}}



It's not very elegant, but that's [the only way I found](https://github.com/quarto-dev/quarto-cli/discussions/2845) to include a file full of LaTeX macros. For the pdf version, it's simply `\include{_macros.tex}` injected in the template header.
allefeld commented 2 weeks ago

@baptiste In my experience, {{< include _macros.tex >}} works just as well.

Strictly speaking, included this way into Markdown source, this is no longer LaTeX code (e.g. %-comments don't work) but Pandoc Markdown code with the by-default-enabled extension latex_macros. This works independent of the output format (though of course the resulting expanded LaTeX math needs to be supported).