Open abdalazizrashid opened 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:
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.
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.
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
Side note from my tries:
globalGroup: true
works when post processing the HTML to add it for test
Inserting this JS command
katex.renderToString("\\newcommand{\\E}{\\mathbb{E}", {macros, globalGroup: true})
but
var macros
is definedkatex.render
. Not possible right now with pandoc and QuartoDoing var macros = {"\\E": "\\mathbb{E}"};
also in postprocessing HTML for test works, but still now way to change this from Pandoc variable, and from Quarto for now.
@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.
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)
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
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.
@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).
Bug description
Enabling katex for doesn't expand macros
Steps to reproduce
Expected behavior
Actual behavior
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:
/Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/library knitr: (None) rmarkdown: (None)
The rmarkdown package is not available in this R installation. Install with install.packages("rmarkdown")