quarto-dev / quarto-cli

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

referencing equations inside `$$ \begin{align}` environment #2275

Open HelenaLC opened 2 years ago

HelenaLC commented 2 years ago

Bug description

I am struggling to label multiple equations placed within $$ \begin{align} ... \end{align} $$.

This works flawlessly...

$$
\begin{align}
a &= 0+1 \\
b &= 2+3 \\
c &= 4+5
\end{align}
$$ {#eq-abc}

see @eq-abc.

...but neither of these work:

$$
\begin{align}
a &= 0+1 \label{eq:a} \\
b &= 2+3 \label{eq-c} \\
c &= 4+5 {#eq-d}
\end{align}
$$

I tried various other versions of Quarto and/or LaTeX syntax, but couldn't achieve the desired results: To have multiple numbered (and cross-referenceable) equations placed within an align-block.

Any suggestions would be greatly appreciated! And, it would be nice to have such an example included in the Equations sections of the Technical Writing documentation here.

Software:

Checklist

justanothergithubber commented 2 years ago

Hello there, if you work with only HTML and PDF, I have the following (probably temporary) workaround:

---
format:
    html: default
    pdf: default
---
\begin{align}
    a &= 0+1 \tag{A}\label{eq:a} \\
    \begin{pmatrix}
        x \\ x \\ x \\ x \\ x \\ x \\ x
    \end{pmatrix} &=
    \begin{pmatrix}
        x \\ x \\ x \\ x \\ x \\ x \\ x
    \end{pmatrix} \notag \\
    b &= 2+3 \tag{B}\label{eq:b} \\
    \begin{pmatrix}
        x \\ x \\ x \\ x \\ x \\ x \\ x
    \end{pmatrix} &=
    \begin{pmatrix}
        x \\ x \\ x \\ x \\ x \\ x \\ x
    \end{pmatrix} \\
    c &= 4+5 \tag{C}\label{eq:c} \\
    \begin{pmatrix}
        x \\ x \\ x \\ x \\ x \\ x \\ x
    \end{pmatrix} &=
    \begin{pmatrix}
        x \\ x \\ x \\ x \\ x \\ x \\ x
    \end{pmatrix}
\end{align}
See Equation \eqref{eq:a}. See Equation \eqref{eq:b}. See Equation \eqref{eq:c}.

If you render this, the HTML should produce references to all 3 tagged equations without issue. If you render PDF, note that the align environment automatically numbers each line. You can add \notag to each equation you want to have no tag, or you can use align* instead. Note that there is no outer $$ in this case. (in case it wasn't obvious, the repeated x blocks are to add vertical space to show that the cross-refs go to the right vertical place)

I do not expect this to remain permanently usable, but for now it should work.

EDIT: I think some interesting background into how raw LaTeX is written in .qmd can be found here

mattocci27 commented 2 years ago

Are there any workaround for MS word documents?

abudden commented 1 year ago

The workaround that uses \label and \eqref is probably better with \ref:

\begin{align}
a & = b + c \label{eq1} \\
c & = d + e \label{eq2}
\end{align}

Referring to equations \ref{eq1} and \ref{eq2}...

The difference is that \eqref renders the equation number as (1) where as \ref renders it as 1. Arguably the \eqref version is better, but it won't match the other equations in the document (ref #2439).

eeholmes commented 1 year ago

update Aug 2024 In a reply on this thread, I suggested adding html-math-method: to the top yaml. However that breaks this solution (now at least). See the added notes regarding the yaml for single qmd and _config.yaml for Quarto books.

tldr; For LaTeX users wanting complex math in both html and PDF using the same Quarto file: 1) Add a mathjax.html file and add to your top yaml (instructions below) to turn-on equation numbering and only use LaTeX equation environments (not $$). 2) For referencing, only use \label{} and \eqref{} or \ref{}. Do not use (#eq-) and @eq- for referencing. Pandoc (and MathJax) knows LaTeX so all your fancy equations should work if you do 1 and 2.


\begin{align}
a & = b + c \label{eq1} \\
c & = d + e \label{eq2}
\end{align}

will not render equation numbers in html. You could add \tag{1} but then you lose the autonumbering feature. The problem is that by default MathJax is set up to not show the numbers. Why the MathJax folks choose the opposite default as LaTeX makes no sense but that is what they did. So you have to turn on numbering. Sadly how you do this depends on the version of MathJax and the documentation is not 100% helpful. 🤯🤯

Here is how to turn on numbering with the MathJax v3+ file that Quarto is using.

Create this file: mathjax.html

<script>
  MathJax = {
    tex: {
      tags: 'ams'  // should be 'ams', 'none', or 'all'
    }
  };
</script>

For MathJax v2.7, the config uses MathJax.Hub.Config so search for that if this doesn't work with the MathJax js file you are using. Note MathJax v2.7 was replaced with v3 in 2017-2018, but you will still see many websites loading MathJax v2.7. :

For a Quarto book, the top yaml in _quarto.qmd should look like

---
title: "test"
format:
  html:
    include-in-header: mathjax.html
  pdf: default
---

Do not add html-math-method to the yaml or it breaks the numbering (Aug 2024 at least).

format:
  html:
    include-in-header: mathjax.html
    html-math-method:
      method: mathjax
      url: "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"

Now this LaTeX code shows your autonumbers in both html and pdf output.

\begin{align}
a & = b + c \label{eq1} \\
c & = d + e \label{eq2}
\end{align}

Something to keep in mind is that the Quarto equation numbering (meaning $$ fence with {#eq-eq1} at the end) is incompatible with LaTeX equation environment numbering in html but works fine in PDF. Weird. Just don't use the (handy) @eq-eq1 for references, instead use \eqref{} or \ref{}, because Pandoc doesn't figure that out for the equation environments. Look at this example that mixes $$ $$ with equation environments (\begin{align}).

$$
S_n = \frac{X_1 + X_2 + \cdots + X_n}{n}
      = \frac{1}{n}\sum_{i}^{n} X_i
$$ {#eq-eq1}

\begin{align}
a & = b + c \label{eq2} \\
c & = d + e \label{eq3}
\end{align}

$$
S_n = \frac{X_1 + X_2 + \cdots + X_n}{n}
      = \frac{1}{n}\sum_{i}^{n} X_i
$$ {#eq-eq4}

\eqref{eq-eq1}, \eqref{eq2}, \eqref{eq3}, \eqref{eq-eq4}

Produces this in html:

image

Produces this in PDF

image

If you only need to render to both html and PDF, then I would say never use $$ $$ and @eq- for equations. Stick to the equation environments (which btw is what LaTeX users would normally use) and use\eqref{} and \ref{}. If you need to render to word though....only $$ $$ is recognized; equations in equation environments are completely removed! 🤯

image

I tested with Quarto docx format and RMarkdown officerdown::rdocx_document format and both showed the same behavior. I don't know how Pandoc is doing the markdown to Word XML (I assume) conversion but seems like the non-recognizing LaTeX equation environments is at a low level. But I also didn't search for a "equation to image" option, which would allow Pandoc to create the equation imagew via LaTeX and bypass the Word Equation engine. I don't know if that is a thing, but that is how I would solve equations in Word docs created with Quarto/RMarkdown.

A note re \eqref{}. Here is how to redefine it for PDF output. I don't know how to do this for html. Pandoc knows \eqref{} so there must be a way to redefine for html. Note, Pandoc will understand \newcommand{} and \renewcommand{} for html but weirdly in html the new definition is recognized only in math environments, like $ $. Anyhow for PDF output this will work

  pdf: 
    include-in-header: 
      text: |
        \renewcommand{\eqref}[1]{Equation~\ref{#1}}
eeholmes commented 1 year ago

Note I tried a mathjax.html file with both ways of turning on numbering, and it still worked. So this file may be a more robust way to turn on numbering since it will work with more versions of MathJax (I think).

<script type="text/x-mathjax-config">
MathJax.Hub.Config({
  TeX: { equationNumbers: {autoNumber: "AMS"} },
  tex2jax: {inlineMath: [ ['$','$'], ["\\(","\\)"] ]}
});
</script>

<!-- This is what works with Quarto -->
<script>
  MathJax = {
    tex: {
      tags: 'ams'  // should be 'ams', 'none', or 'all'
    }
  };
</script>

But weirdly with the MathJax file that RStudio Rmd files loads (v2.7 from 2017), the line up of the equations numbers changes.

image

How do you know what version of MathJax that a js file is? Paste the url in the browser and look at the top of the js file. The info on the version of MathJax will be there.

In Jan 2023, here is the MathJax js file that Quarto is using by default:

"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"

You can change the MathJax version being used like so. Adding this html-math-method code will break numbering! At least it did for me in Aug 2024. This is for example's sake to show how to change the mathjax url. Don't add the html-math-method part to your yaml.

format:
  html:
    include-in-header: mathjax.html
    html-math-method:
      method: mathjax
      url: "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
pglpm commented 1 year ago

@eeholmes Thank you so much for the mathjax config scripts and the detailed explanations.

One question: the Mathjax 3.2 doc pages use window.MathJax at the beginning of configuration files. Is this equivalent to the MathJax at the beginning of the config scripts above? Or are these two completely different things? Cheers!

ikosmidis commented 9 months ago

Just landed on this thread, and here is a proposal using the aligned environment within $$ ... $$.

$$
\begin{aligned}
a &= 0+1 \\
b &= 2+3 \\
c &= 4+5
\end{aligned}
$$ {#eq-abc}

see @eq-abc, or ([-@eq-abc]).

This works with default settings with correct labels in both PDF and HTML ( and I guess word!) and does not require any MathJax hacking.

Useful thing is that

format:
  html:
    crossrefs-hover: true

will display referenced equations on hover in HTML (and PDF, depending on your PDF reader), which is handy with long technical content.

asmaier commented 7 months ago

It should be noted that using aligned instead of align won't work. This document test.md

---
title: "test"
format:
  html:
    include-in-header: mathjax.html
---

$$\begin{aligned}
a & = b + c \label{eq2} \\
c & = d + e \label{eq3}
\end{aligned}$$

Refer to `\eqref{eq2}`{=latex} and `\eqref{eq3}`{=latex}.

will render using quarto preview test.md like

Bildschirmfoto 2024-04-19 um 23 53 26

Instead of two equations with two labels mathjax counts them as one.

Why is this relevant? If one starts with the following latex file test.tex

\documentclass[12pt,a4paper,twoside]{book}
\usepackage[intlimits]{amsmath} 

\begin{document}

\begin{align}
a & = b + c \label{eq2} \\
c & = d + e \label{eq3}
\end{align}

Refer to \eqref{eq2} and \eqref{eq3}.

\end{document}

and converts it to markdown via quarto pandoc --wrap=preserve -t markdown -f latex+raw_tex -o test.md test.tex then pandoc will unfortunately convert the align environment into an aligned environment (because of this issue https://github.com/jgm/pandoc/issues/4104) and one ends up with a markdown file as shown above.

ikosmidis commented 7 months ago

My solution is correct for just a single label for all aligned equations in a single display. I tend not to need more than one label, mainly because I avoid more than three equations in a single display, and then I can always say the first / second / third / etc. equation/expression/ etc. in XYZ.

Labelling more than 1 equation in a single align display in the current quarto version seems impossible without the Mathjax hacks in previous responses. But with those, many nice goodies that quarto provides and guarantees on the outputs between formats may be lost.

mtartari commented 4 months ago

I tried to follow to the letter the instructions by @eeholmes but what I get in my HTML output is this:

Screenshot 2024-07-25 at 12 53 39 AM

To be precise here is what I did:

  1. saved a file named mathjax.html in my project's directory, it has the exact content copied+pasted from @eeholmes post, nothing more nothing less:
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
  TeX: { equationNumbers: {autoNumber: "AMS"} },
  tex2jax: {inlineMath: [ ['$','$'], ["\\(","\\)"] ]}
});
</script>

<!-- This is what works with Quarto -->
<script>
  MathJax = {
    tex: {
      tags: 'ams'  // should be 'ams', 'none', or 'all'
    }
  };
</script>
  1. In my existing_quarto.yml file I have this (note: last 4 lines are copied+pasted from @eeholmes post):

    format:
    html:
    theme: custom.scss
    css: style.css
    pandoc_args: ["--lua-filter=color-text.lua"]
    include-in-header: mathjax.html
    html-math-method:
      method: mathjax
      url: "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
  2. In intro.qmd I copied the LaTeX script:

    \begin{align}
    a & = b + c \label{eq1} \\
    c & = d + e \label{eq2}
    \end{align}

Perhaps I am misunderstanding @eeholmes instructions, I apologize in advance for my total ignorance (in particular regarding the discussion around the version of Mathjack). I appreciate the help because I teach and I need to label equations in a long derivation ALL the time and I just switched from Bookdown (where I could do that) to Quarto and bumped into this issue.

eeholmes commented 4 months ago

@mtartari Look at this repo https://github.com/nmfs-opensci/test-equations. You might be missing the $$ fences. I am using the latest version of Quarto 1.5.55 with RStudio.

image
Scott-Akenhead commented 3 months ago

Using \begin{align} without $$ renders as HTML and as PDF. Here’s the test code and a screen-shot of PDF resulting. For instance, \begin{align} y &= \mathcal{N} (\hat{y}, \ \sigma) \ &= \mathcal{N} (\alpha + X \beta + Z \gamma, \ \sigma) \end{align}
Posit should, please, document this.

image
eeholmes commented 3 months ago

@Scott-Akenhead Yes it works if you don't have \label{eq1} (so that you can ref the equation lines) but does not work if you do have that. If you do have that you'll see this if you don't have the $$ fence:

image
Scott-Akenhead commented 3 months ago

Sheesh. This is messy! I tried your suggestion:

\begin{equation} \begin{aligned} y &= \mathcal{N} (\hat{y}, \ \sigma) \label{eqx}\ &= \mathcal{N} (\alpha + X \beta + Z \gamma, \ \sigma) \label{eqy} \end{aligned} \end{equation}

but result was

ERROR: compilation failed- error Package amsmath Error: Multiple \label's: label 'eqx' will be lost.
l.154 ...a + X \beta + Z \gamma, \ \sigma) \label {eqy}

Same result with the equations inside a tex chunk:

\begin{equation*} \begin{aligned}
y &= \mathcal{N} (\hat{y}, \  \sigma) \label{eq1} \\
y &= \mathcal{N} (\alpha + X \beta + Z \gamma, \  \sigma) \label{eq2} 
\end{aligned} \end{equation*}

and even when equation number is automatic, without labels, there is only 1 equation number:

\begin{equation} \begin{aligned}
y &= \mathcal{N} (\hat{y}, \  \sigma) \\
y &= \mathcal{N} (\alpha + X \beta + Z \gamma, \  \sigma)  
\end{aligned} \end{equation}
image

So hath the Latex Math God decreed and all men shall bow to his/her/its command.

eeholmes commented 3 months ago

Ok, I figured out the problem. This bit in the yaml is breaking things:

    html-math-method:
      method: mathjax
      url: "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"

The top yaml should be

format:
  html:
    include-in-header: mathjax.html
  pdf: default

@Scott-Akenhead Something changed with Quarto since my Jan 20, 2023 answer. Now to get \begin{align} to work I have to put it in a $$ fence not \begin{equation*}. Arg. I realize that is improper LaTeX but that's what I had to do. I am trying to debug what changed with Quarto over the last year.

cscheid commented 3 months ago

I don't think we intentionally changed anything! If you folks can come up with a minimal document where the behavior changed, we will be able to more easily help.

eeholmes commented 3 months ago

@cscheid Sorry we didn't get to meet up at Posit conf! So close...

I am moving my various notes from this issue and another into a repo to chip away at the issues for LaTeX users. Also will provide me a place to send LaTeX users for examples.

I don't think it is any Quarto bug per se. My goal is to figure out what needs to be done to get proper amsmath LaTeX syntax working in Quarto books. https://github.com/nmfs-opensci/quarto-amsmath/issues/2. I realize that Quarto syntax for equation numbering is working, but that is causing too many issues for LaTeX users who are trying to get their amsmath code working. So rather than try to create a new equation syntax, I'd like to figure how to get amsmath syntax working. It is pretty close. Most things work fine. It is just the section numbering that I don't know how to fix.

Scott-Akenhead commented 3 months ago

On behalf of all of us using Quarto to collaborate on science papers: Thanks! Appreciated!

An encompassing, over-the-horizon, goal might be: Submit a paper in Quarto directly to a science journal.

eeholmes commented 3 months ago

@cscheid I added this comment to the issue I am working on. https://github.com/nmfs-opensci/quarto-amsmath/issues/2#issuecomment-2294989880 Maybe it will explain the problem better? Quarto is essentially circumventing the MathJax javascript libraries way of handling and figuring out equation numbering in our complicated equations. Recreating the MathJax library behavior would not be good. It's really complicated and took years of work to make complicated amsmath equations look right with numbers in the right places in html.

The solution is not too hard. I have done it before. It uses the MathJax tagformat extension. Solution is here. But it involves adding <span style="display: hidden">\(\nextSection\)</span> to each chapter qmd. I want to figure out a way to do that automatically. A "mathjax lua filter" might work and feel natural to users (natural in the sense that using lua filters in quarto is natural).

cscheid commented 3 months ago

A "mathjax lua filter" might work and feel natural to users (natural in the sense that using lua filters in quarto is natural)

This might be harder said than done. I have to spend some time investigating to say for sure, but I believe some amount of the processing for MathJax happens after Lua filters are done (some of it is done by Pandoc, and some of it is done by Quarto post-processors). At the point where the document is at a state that you want it to be, there might not be any Quarto extension entry points.

eeholmes commented 3 months ago

@cscheid Here is the repo showing where I am at. I am quite close to a 'proof of concept'. If I can just figure out how to id the <header> tags.

https://github.com/nmfs-opensci/chapnum-equations

bjornasm commented 2 months ago

Is it possible to read some proper documentation on how to handle referencing in equations? There are a lot of suggestions in this thread but I can't really understand which would be the right one.