Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support \eqref and \label #2003

Open
invkrh opened this issue Jun 15, 2019 · 31 comments
Open

Support \eqref and \label #2003

invkrh opened this issue Jun 15, 2019 · 31 comments

Comments

@invkrh
Copy link

invkrh commented Jun 15, 2019

Before requesting a feature, please search for existing issues.

Is your feature request related to a problem? Please describe.
I am trying to migrate from Mathjax to Katex, however, \eqref and \label are not supported for the moment. Any roadmap on this?

Describe the solution you'd like:
Support \eqref and \lable for equation reference

Link to or name of a (La)TeX package that provides the same feature:
KaTeX's general goal is to render as LaTeX does.

Describe alternatives you've considered:
A clear and concise description of any alternative solutions or features you've considered.

Additional context:
Add any other context or screenshots about the feature request here.

@invkrh invkrh changed the title Support \eqref and \lable Support \eqref and \lable Jun 15, 2019
@edemaine
Copy link
Member

This issue is partly discussed in #350. I agree that \label and \ref would be super useful, but they are also quite nontrivial to implement (even in LaTeX) because you essentially need two passes, one to define the labels, and another to render everything with the current \refs. I don't quite see how to fit this into KaTeX's current architecture... (Though if we just want to be able to \ref earlier \labels, we could do it easily with the macro infrastructure.)

@kevinbarabash kevinbarabash changed the title Support \eqref and \lable Support \eqref and \label Jun 16, 2019
@kevinbarabash
Copy link
Member

We might be to insert a pass on the parse tree to insert labels/refs as needed before doing the render pass.

@edemaine
Copy link
Member

@kevinbarabash Neat idea. One challenge is that labels and refs will generally span multiple equations, so this would need to be done at the autorender level. But maybe if we work out the interface for how autorender could do it, we could get a more general API...

@Nathan-Furnal
Copy link

any update on that ? referencing equations, tables and figures + labels would be super useful and help make the change from mathjax !

@zhangpeng96
Copy link

zhangpeng96 commented May 19, 2021

Inspired by this issue: falgon/roki-web#34
We can use KaTeX's marco command to implement \eqref & \label function by \href & \htmlId command

ATTENTION: \href & \htmlId command are disabled by default, we must add them into trust option

UPDATE: The previous trust setting code is wrong, as @nschloe said, trust only accept boolean or function. We can use function type to allow specific commands. Thank nschloe very much!

KaTeX option:

trust: (context) => ['\\htmlId', '\\href'].includes(context.command),
macros: {
  "\\eqref": "\\href{###1}{(\\text{#1})}",
  "\\ref": "\\href{###1}{\\text{#1}}",
  "\\label": "\\htmlId{#1}{}"
}

example:

Search by definition $\eqref{1-1}$ or $\ref{1-1}$.

$$
\begin{aligned} \sin 2\theta = 2\sin \theta \cos \theta \\ = \cfrac{2 \tan \theta}{1+\tan^2 \theta} \end{aligned} \label{1-1}\tag{1-1}
$$

Used in the same way as LaTeX or MathJax.

@nschloe
Copy link
Contributor

nschloe commented Jun 18, 2021

@zhangpeng96 Your trust parameter is malformed. It doesn't actually accept a list, and the reason why this is work is that KaTeX evaluates the array as true, so everything is allowed. You may want to edit the post.

@nschloe
Copy link
Contributor

nschloe commented Jun 18, 2021

I just converted a small note of mine from LaTeX to Markdown + KaTeX + Plotly.js on a GitHub Wiki page, https://github.com/nschloe/colorio/wiki/On-the-conversion-from-OSA-UCS-to-CIEXYZ. The only thing that was really tedious is the equation labeling. Voting for this in KaTeX!

@zhangpeng96
Copy link

@zhangpeng96 Your trust parameter is malformed. It doesn't actually accept a list, and the reason why this is work is that KaTeX evaluates the array as true, so everything is allowed. You may want to edit the post.

Thank you! I have corrected it. 😆

@CarloLucibello
Copy link

Is #2003 (comment) a satisfactory solution? Can it be made part of Katex?

@zardini123
Copy link

zardini123 commented Jul 11, 2022

Is #2003 (comment) a satisfactory solution? Can it be made part of Katex?

From my testing, it is not fully satisfactory as the \ref macro defined in the comment does not use the equation number that the \label is associated with. The rendered text will instead be the text of the label. As shown in Overleaf's documentation here, this is inconsistent with LaTeX's equation referencing.

In addition, use of \htmlId in \label macro results in the following warning:

LaTeX-incompatible input and strict mode is set to 'warn': HTML extension is disabled on strict mode [htmlExtension]

@mozhewen
Copy link

@zardini123 The warning message can be suppressed by setting strict: "ignore". However, the numbering is still unsatisfactory.

@Npaffen
Copy link

Npaffen commented Jul 16, 2022

Is this the correct way to add this to the auto-renderer extension?

<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css" integrity="sha384-Xi8rHCmBmhbuyyhbI88391ZKP2dmfnOl4rT9ZfRI7mLTdk1wblIUnrIq35nqwEvC" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.js" integrity="sha384-X/XCfMm41VSsqRNQgDerQczD69XqmjOOOwYQvr/uuC+j4OPoNhVgjdGFwhvN02Ja" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/contrib/auto-render.min.js" integrity="sha384-+XBljXPPiv+OzfbB3cVmLHf4hdUFHlWNZN5spNQ7rmHTXpd7WvJum6fIACpNNfIR" crossorigin="anonymous"></script>
<script>
      document.addEventListener("DOMContentLoaded  ", function() {
          renderMathInElement(document.body, {
  trust: (context) => ['\\htmlId', '\\href'].includes(context.command),
  macros: {
  "\\eqref": "\\href{###1}{(\\text{#1})}",
  "\\ref": "\\href{###1}{\\text{#1}}",
  "\\label": "\\htmlId{#1}{}"
}
          });
      });
  </script>

</head>

@jeremy-feng
Copy link

Is this the correct way to add this to the auto-renderer extension?

<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.css" integrity="sha384-Xi8rHCmBmhbuyyhbI88391ZKP2dmfnOl4rT9ZfRI7mLTdk1wblIUnrIq35nqwEvC" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/katex.min.js" integrity="sha384-X/XCfMm41VSsqRNQgDerQczD69XqmjOOOwYQvr/uuC+j4OPoNhVgjdGFwhvN02Ja" crossorigin="anonymous"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.0/dist/contrib/auto-render.min.js" integrity="sha384-+XBljXPPiv+OzfbB3cVmLHf4hdUFHlWNZN5spNQ7rmHTXpd7WvJum6fIACpNNfIR" crossorigin="anonymous"></script>
<script>
      document.addEventListener("DOMContentLoaded  ", function() {
          renderMathInElement(document.body, {
  trust: (context) => ['\\htmlId', '\\href'].includes(context.command),
  macros: {
  "\\eqref": "\\href{###1}{(\\text{#1})}",
  "\\ref": "\\href{###1}{\\text{#1}}",
  "\\label": "\\htmlId{#1}{}"
}
          });
      });
  </script>

</head>

Yes, I have tried it and it works!

@scruel
Copy link

scruel commented Sep 22, 2022

@zhangpeng96 Nice workaround, applied to docsify-latex, thanks!

@edemaine
Copy link
Member

@zhangpeng96's approach of converting \ref into a link with text equal to the label, instead of a number, is a neat way to go, as this can all be done server-side.

Perhaps KaTeX should officially do this, and (perhaps in the auto-render extension) offer a postprocessing phase to turn these labels into numbers if desired?

I also wonder whether \label{foo} should also include \tag{foo}, so that the foo text appears both at the point of \ref and \label? Perhaps unless \tag is already explicitly specified, or implicit via equation numbering (\begin{equation} or \begin{align})? In LaTeX, \label only makes sense when equations are numbered, so defining web-relevant behavior for unnumbered equations is maybe good... though this may be bad given our tag overlap issues (#3066).

@mburghart-qualitrol
Copy link

In the near-term, please at least make \label be pass-thru and show the equation rendering instead of a Parse Error message. In general you should be tolerant of any tex-like components you can't process.

@dudung
Copy link

dudung commented Jun 24, 2023

Any update on this feature?

As I use a Hugo theme, Coder, which implements KaTeX as

  <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.js"
    integrity="sha384-PwRUT/YqbnEjkZO0zZxNqcxACrXe+j766U2amXcgMg5457rve2Y7I6ZJSm2A0mS4" crossorigin="anonymous"></script>
  <script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/contrib/auto-render.min.js"
    integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"
    onload="renderMathInElement(document.body,
      {
        delimiters: [
          {left: '$$', right: '$$', display:true},
          {left: '$', right: '$', display:false},
          {left: '\\(', right: '\\)', display: false},
          {left: '\\[', right: '\\]', display: true}
        ]
      }
    );"></script>

the feature still does not work.

Thank you for any information.

@tavin
Copy link

tavin commented Jul 11, 2023

I think it might be nearly impossible for katex itself to ship a full solution, especially when equations are numbered by CSS counters, which are inflexible and totally inaccessible to javascript. Also katex doesn't know the global numbering scheme if multiple snippets of latex are passed through katex render methods individually and assembled into a larger document. Of course that's why CSS counters are a neat solution for displaying the numbered equations.

Anyway I am working in the scenario of assembling katex outputs, namely in TiddlyWiki5, and I can say that implementing \label and \eqref at such a level is not so hard. Here is a proof of concept.

I took @zhangpeng96's clever workaround as the starting point. The rest is javascript and css to replace the labels with numbers -- merely a realization of what has been said in the discussion so far @edemaine.

My conclusion (cf. the hoops I had to jump through) is that \label should be implemented by injecting a data attribute and/or ID into the corresponding span.eqn-num. Half the code in my PoC is just locating this relationship in the DOM. It would be much better to be able to grab the numbered tag directly. Then all that remains is to calculate the position it occupies among all span.eqn-num elements (in scope).

Summary:

  • There is a simple and beneficial way to implement \label right now.
  • Let \eqref be a separate issue, though for the interim, something like the \href{###1}{#1} hack would be good enough to release -- and easily improved by javascript/css hacking.

@N0rbert
Copy link

N0rbert commented Jul 11, 2023

We are "celebrating" 4 years of this bug.
And it is still does not work with

\begin{equation}
  g\left(k\right) = \binom{n}{k} p^k\left(1-p\right)^{n-k}
\label{binom2}
\end{equation}

katex

@edemaine
Copy link
Member

@tavin This looks great! It's been a while since I've thought about this issue, but I wonder if you'd be willing to take a stab at adapting your PR for the KaTeX repo? I could see the following approach:

  • \label/\ref produces id attributes / a tags, though perhaps moving or copying id to the corresponding equation number if there is one (as I think you're suggesting). This is the default behavior for these commands: text labels.
  • Main KaTeX also provides an option for a prefix for id/class generated for labels, to enable multiple LaTeX documents on the same page. It could be katex- by default, but users could localize by document id.
  • A separate function call on the client side resolves all equation numbers (converting them from counters to explicit values) and at the same time resolves all refs to numbers. To support multiple documents, presumably you would specify a root DOM element, or array of roots, to consider descendants of, or a string for document.querySelectorAll. Something like how it's done for auto-render I guess.

The main question is where to locate that function. I think it makes sense in contrib/auto-render, and maybe auto-render could also call it by default, but importantly it should also be callable separately for those not using auto-render, for more complex applications like TiddlyWiki.

What do you think?

@tavin
Copy link

tavin commented Jul 11, 2023

@edemaine I would like to help but I can't say how soon, as I'm completely unfamiliar with the katex codebase. Also imo the "resolution" aspect should be a separate issue and PR. Yes the main idea for now is to enrich span.eqn-num elements with data/id attributes reflecting the label.

@N0rbert
Copy link

N0rbert commented Oct 7, 2023

The following equation

\begin{equation}
  g\left(k\right) = \binom{n}{k} p^k\left(1-p\right)^{n-k}
\label{binom2}
\end{equation}

still does not render with latest KaTeX 0.16.9 - "KaTeX parse error: Undefined control sequence: \label at position 77: …p\right)^{n-k} \̲l̲a̲b̲e̲l̲{binom2} \end{e…".

@hyliang96
Copy link

hyliang96 commented Jan 26, 2024

I succeeded! Thanks to zhangpeng96's #2033 (comment). The following is my code. Put it in 'demo.html' and open with browser, then \eqref \eq and \label will be rendered as the following screen shot.

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>

        <title>KaTeX-DOM Eq. Ref Test</title>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css" integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X" crossorigin="anonymous">
        <script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.js" integrity="sha384-g7c+Jr9ZivxKLnZTDUhnkOnsh30B4H0rpLUpJ4jAIKs4fnJI+sEnkvrMWph2EDg4" crossorigin="anonymous"></script>
        <script defer src="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/contrib/auto-render.min.js" integrity="sha384-mll67QQFJfxn0IYznZYonOWZ644AWYC+Pt2cHqMaRhXVrursRwvLnLaebdGIlYNa" crossorigin="anonymous"
          onload="renderMathInElement(document.body);"></script>
        <script src="main.js"></script>

        <script>
            document.addEventListener("DOMContentLoaded", function() {
                renderMathInElement(document.body, {
                    // auto-render specific keys
                    delimiters: [
                        {left: '$$', right: '$$', display: true},
                        {left: '$', right: '$', display: false},
                        {left: '\\(', right: '\\)', display: false},
                        {left: '\\[', right: '\\]', display: true}
                    ],
                    // render equation with bug
                    throwOnError : false,
                    // support eqref
                    trust: (context) => ['\\htmlId', '\\href'].includes(context.command),
                    macros: {
                        "\\eqref": "\\href{###1}{(\\text{#1})}",
                        "\\ref": "\\href{###1}{\\text{#1}}",
                        "\\label": "\\htmlId{#1}{}"
                    }
                });
            });
        </script>
    </head>

    <body>
        In Eq. $\eqref{eq:1}$ or $\ref{eq:1}$.<br/>

        $$
        \begin{aligned}
        \sin 2\theta = 2\sin \theta \cos \theta \\ = \cfrac{2 \tan \theta}{1+\tan^2 \theta}
        \end{aligned}
        \label{eq:1} \tag{1}
        $$
    </body>
</html>
image

By the way, as shown in the screen shot above, this solution has a drawback: $\ref{eq:1}$ $\eqref{eq:1}$ will be rendered as 'eq:1' rather than '1' -- the numbering of equation. I wonder how to fix this bug, or is there another way to support label \ref \eqref?

@piszczu4
Copy link

Do I understand correctly that this issue is not resolved for about 4 years, while such a solution already works in MathJax? I was going to use katex for my website but the lack of this feature is a huge drawback :(

@zhangpeng96
Copy link

By the way, as shown in the screen shot above, this solution has a drawback: $\ref{eq:1}$ $\eqref{eq:1}$ will be rendered as 'eq:1' rather than '1' -- the numbering of equation. I wonder how to fix this bug, or is there another way to support label \ref \eqref?

yzhang-gh/vscode-markdown#985 (comment)

The reference name is shown with arguments of \ref or \eqref, so you can fill it with whatever you want. I don't have a more elegant solution in mind at the moment, I'll try it later.

@hyliang96 \ref\eqref 的参数就是最终显示的引用名称,所以直接填写数字就是你想要的结果了

<i>eqref command:</i> $\eqref{8}$, <i>ref command:</i> $\ref{8}$.

<br>
$$
\begin{aligned} \sin 2\theta = 2\sin \theta \cos \theta \\ = \cfrac{2 \tan \theta}{1+\tan^2 \theta} \end{aligned} \label{8}\tag{8}
$$

image

暂时想不到更优雅的实现方式,后面我再试试

@mbourne
Copy link

mbourne commented Apr 9, 2024

I had a go at implementing a solution which may be useful as an interim measure for some developers.

It works by doing a pre-process scan of the environments and keeps track of the equation number and tags for use in replacing the \eqref's with links.

It handles \labels and \tags.

It doesn't play nicely with internal environments (like \split within \equation), but otherwise it appears to work for the kinds of equations used on this demo page.

https://bourne2learn.com/math/katex/katex-label-tag-eqref.php

There's a brief explanation below the demo, and the code used.

Hope it helps.
Regards
Murray

@N0rbert
Copy link

N0rbert commented Apr 9, 2024

It is near 4 years passed while we chatting here.
Please implement support of this

\begin{equation}
  g\left(k\right) = \binom{n}{k} p^k\left(1-p\right)^{n-k}
\label{binom2}
\end{equation}

in the main KaTeX codebase.

@jorenham
Copy link

jorenham commented Apr 9, 2024

I'd like to kindly remind those that are demanding a solution to this feature request, that this is open-source software, and is completely free to use.
Complaining about missing features such as these, is more likely to demotivate the volunteers that work on this project, than to achieve the results that you desire.

Instead, the most effective way to get what you want is to submit a pull-request yourself.
This shouldn't be a difficult task, especially considering the fact that there already is a perfectly fine way to emulate this feature: #2003 (comment)

Open source is one of the most beautiful achievements ever to be created by humankind. It would be sad to see (more) developers leave it because of inconsiderate or disrespectful behavior.

@mbourne
Copy link

mbourne commented Apr 12, 2024

The solutions offered so far don't appear to have a satisfactory numbering system for the eqref's, so I pursued with it some more.

So I have a new version which merges my pre-processing approach to keeping track of equation numbers, with the macro approach suggested earlier: #2003 (comment)

Now we have:

  1. Automatically inserted IDs on the equation number via KaTeX's macro approach, as per the earlier comment
  2. Automatically numbered eqref links based on pre-processing
  3. Changed IDs (to the format id = "katex-lbl-whatever" so they are less likely to conflict with the author's own IDs.
  4. Pointed the links to the top of the KaTeX span (not to the label number, which almost always is troublesome because you have to scroll up to see what the beginning of the equation was all about)
  5. Provided error checking for orphan eqref's (that don't point to any existing equation)
  6. Provided error checking for cases that would mess up the auto numbering (e.g. where authors have omitted a \nonumber thus producing a tag span, but it wouldn't have been picked up in my equation numbering)

Here it is: https://bourne2learn.com/math/katex/katex-label-tag-eqref-macro.php

After thinking about it, it seems to me:

  1. It would be better to actually produce tag numbering during initial KaTeX processing, rather than CSS-based numbering
  2. Then the correct numbering would be available to use for the eqref's. If new dynamically produced content is added, the whole thing would be re-processed, so the equation numbering would work
  3. If that happened, it would be simpler to get properly numbered eqref's, and it would be simpler for authors so that "dangling" line numbering in equations (that didn't have a label) would be no biggie.

I also updated my earlier non-macro proposal, and it handles split now.

https://bourne2learn.com/math/katex/katex-label-tag-eqref.php

Regards
Murray

@branyang02
Copy link

branyang02 commented Aug 8, 2024

I was able to create a working \label and \eqref logic in my own customized application that uses Katex.

$$
\begin{align}
ax^2 + bx + c &= 0 \label{eq:quadratic-general} \\
x^2 + \frac{b}{a}x + \frac{c}{a} &= 0 \label{eq:quadratic-normalized} \\
x^2 + \frac{b}{a}x &= -\frac{c}{a} \label{eq:quadratic-half} \\
x^2 + \frac{b}{a}x + \left(\frac{b}{2a}\right)^2 &= -\frac{c}{a} + \left(\frac{b}{2a}\right)^2 \label{eq:quadratic-complete} \\
\left(x + \frac{b}{2a}\right)^2 &= \frac{b^2 - 4ac}{4a^2} \label{eq:quadratic-squared} \\
x + \frac{b}{2a} &= \pm \sqrt{\frac{b^2 - 4ac}{4a^2}} \label{eq:quadratic-sqrt} \\
x &= -\frac{b}{2a} \pm \sqrt{\frac{b^2 - 4ac}{4a^2}} \label{eq:quadratic-solve} \\
x &= \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} \label{eq:quadratic-final}
\end{align}
$$

Reference equations $\eqref{eq:quadratic-general}$, $\eqref{eq:quadratic-normalized}$, $\eqref{eq:quadratic-half}$, $\eqref{eq:quadratic-complete}$, $\eqref{eq:quadratic-squared}$, $\eqref{eq:quadratic-sqrt}$, $\eqref{eq:quadratic-solve}$, and $\eqref{eq:quadratic-final}$ in the text.
image

Checkout the detailed implementation at https://github.com/branyang02/notie/blob/main/src/utils/MarkdownProcessor.ts

Also feel free to checkout the website: https://notie-markdown.vercel.app/examples/auto-label

However, it is rather not a clean implementation and required a lot of regex matching. Similar to @mbourne's idea, I implemented a custom equation numbering logic for the equation and align environment to extract the corresponding equation number. Overall, my solution seems to work though.

@mbourne
Copy link

mbourne commented Aug 10, 2024

Very neat solution, @branyang02 !

Your question prompted me to revisit my solution, which I did, and have revised it so that it now handles each line in your quadratic equation example (which I added at the bottom of my demo, and which it didn't handle earlier).

https://bourne2learn.com/math/katex/katex-label-tag-eqref.php

I no longer create extra spans, instead I gave the display mode span an id based on the label (where there was only one equation in the display mode span), and gave each equation number an id (where there was more than one equation in the environment).

I also set a scroll margin so the user is more likely to see the whole of the equation (rather then only the bits below the top of the equation number) in the cases of multi-line environments.

Regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests