Implementing label, tag and eqref in KaTeX

There have been many user requests for implementation of \label, \ref and \eqref with linking in KaTeX. It hasn't been implemented so far because of issues surrounding server-side rendering.

Here's a possible workaround until (or if) it's finally implemented. (See also my macro solution.)

See more info below the demo.

[DEMO STARTS]

Demo: \label, \tag, \ref, and \eqref

Link to Einstein \eqref{eins}, and VolSolRev \eqref{volsolrev} and Vol2Curves \eqref{vol2curves} and first line \eqref{gat} or even the second line \eqref{got} and Imaginary \eqref{imag} and Calculus \eqref{calc}, Newton's Law \eqref{newtlaw}, but \eqref{alat} Newton's Second Law is not like this: \eqref{newtlaw2} and an equation with split \eqref{splitone2} and binomials \eqref{binom2}

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

A sprinkling of Euler with a split (no labels or tags, so no links pointing to this): \begin{equation} \begin{split} e^{i\pi} + 1 &= 0 \\ e^{i\pi} &= -1 \end{split} \end{equation}

and imaginary: \begin{equation} i^2 = -1 \label{imag} \end{equation}

Einstein concluded (after considering Newton's 1st Law \eqref{newtlaw}): \begin{equation} E=mc^2.\label{eins} \end{equation}

The first line \eqref{gat} or even the second line \eqref{got} of that environment

Of course, he stood on the shoulders of giants, including Newton.

After allowing for imaginary numbers \eqref{imag}, we have a numbered equation without labels or tags (green background to highlight this): \begin{equation} e^{i\pi} + 1 = 0 \end{equation}

Now, gather around, everyone, here's one with 2 labels: \begin{gather} \text{quantum}=b \label{gat} \\ e=\text{physics} \label{got} \end{gather}

Elsewhere, we'll see how to define the position, velocity and accelration vectors, at \eqref{rva_a}, but first we all need better column alignment: \begin{alignat}{2} 109&x+&3&y=2 \nonumber\\ 3&x+&125&y=4 \tag{alat} \end{alignat} and \begin{equation} \begin{split} \text{an} &= \text{equation} \\ &=\text{with}+\text{split} \label{splitone2} \end{split} \end{equation}

Newton's calculus allowed us to find the general equation for the volume of a solid of revolution for the area bounded by $y=f(x)$ and between $x=a$ and $x=b$, which is: \begin{equation} V_\text{rev} = \pi\int_{a}^b [ {f(x)} ]^2\,dx\label{volsolrev} \end{equation}

Extending volsolrev \eqref{volsolrev} to the case of rotating an area bounded by two curves, we get vol2curves:

\begin{equation} V_\text{rev} = \pi\int_{a}^b [ {y_2}^2-{y_1}^2 ]\, dx \label{vol2curves} \end{equation}

Here is a numbered equation without labels or tags (so no links pointing to it): \begin{equation} \frac{df}{dt}=\lim\limits_{h \to 0}\frac{f(t+h)-f(t)}{h} \end{equation}

Using \eqref{vol2curves}, the volume of the solid of revolution resulting from rotating the area bounded by $y_1=\sin^2(2x)$ and $y_2=\sin^2(x)$ between $x=1$ and $x=3$ is given by: \begin{align} V_\text{rev}&= \pi\int_{a}^b [ {y_2}^2-{y_1}^2 ]\,dx\nonumber\\ &= \pi\int_{1}^3 [ {\sin^2(x)}-{\sin^2(2x)} ]\,dx\nonumber\\ &= \pi(1/8 (2 \sin(2) - \sin(4) - 2 \sin(6) + \sin(12)))\nonumber\\ &\approx 1.0201 \label{calc} \end{align}

We can have a non-numbered environment with a label (which is pmat): \begin{pmatrix} a & b \\ c & d \label{pmat} \end{pmatrix} and we can have velocity \eqref{rva_v}.

We can have another non-numbered environment this time with a tag: \begin{Vmatrix} i & j \\ k & m \tag{Vmat} \end{Vmatrix}

Newton determined that :

\begin{equation} \boldsymbol{F}=m\boldsymbol{a} \label{newtlaw} \end{equation} and as an intelligent extension, we could have: \begin{equation} \boldsymbol{F_2}=m_2\boldsymbol{a_2} \label{newtlaw2} \end{equation} and further talked about position at time $t$, \eqref{rva_r}.

We don't necessarily use \eqref{pmat}, nor \eqref{Vmat}, or to define the position vector $\boldsymbol{r}$, the velocity vector $\boldsymbol{v}$, and the acceleration vector $\boldsymbol{a}$ by \begin{align} \boldsymbol{r} &= x\boldsymbol{i}+y\boldsymbol{j}+z\boldsymbol{k},\label{rva_r}\\ \boldsymbol{v} &=\dot{x}\boldsymbol{i}+\dot{y}\boldsymbol{j}+\dot{z}\boldsymbol{k}, \label{rva_v}\\ \boldsymbol{a} &=\ddot{x}\boldsymbol{i}+\ddot{y}\boldsymbol{j}+\ddot{z}\boldsymbol{k}. \label{rva_a} \end{align}

But Einstein's idea in \eqref{eins} was a conjecture on acceleration \eqref{rva_a} until proof was found of time dilation effects \eqref{volsolrev}, pmatrices \eqref{pmat}, black holes \eqref{imag} and quantum physics \eqref{gat}.

Then again, most school children learn Newton's Law \eqref{newtlaw}, but Newton's Second Law is not like this: \eqref{newtlaw2}, \eqref{alat}. He preferrred to work on calculus \eqref{calc}.

Quadratic formula

\begin{equation} \label{eq:quadratic} x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a} \end{equation}

Reference equation \eqref{eq:quadratic} (that was an \eqref, so it has parentheses) in the text, or \ref{eq:quadratic} (this one was a \ref, so no parentheses).

Proof of quadratic formula.

\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.

Equations with missing items

These next two would mess up the counting if they came earlier in the page (so each one throws an error message):

Here is an equation with label, but is missing a \nonumber (which throws an error, so the author can fix it): \begin{align} r&=\frac{a^2-c^2}{a+c\cos\theta}\\& =\frac{a^2(1-\frac{c^2}{a^2}\,)}{a(1+\frac{c}{a}\;\cos\theta)}\nonumber\\& =\frac{a(1-e^2)}{1+e\cos\theta}\nonumber\\& =\frac{k}{1+e\cos\theta}\label{ellippolar} \end{align}

This one has a tag, but is missing a \nonumber (so also throws an error): \begin{alignat}{2} 109&x+&3&y=2 \nonumber\\ i&x+&77&j=2c \\ 3&x+&125&y=4 \tag{alat2} \end{alignat}

Orphan eqref's

Here's an orphan eqref for demo purposes (gives error message): \eqref{wheresWally} and another \eqref{foo}.

[DEMO ENDS]

Further explanation

This solution works as follows:

  1. If there is one equation per display mode <span> we gives it an id corresponding to the label (or tag) of the environmnt.
  2. If the label is in a numbered environment, the \eqref (or \ref) points to the entire display mode <span>
  3. Where there is more than one label in an environment, the links to those labels point back to the number associated with that label (actually, just a bit above so it's more likely the user sees the whole line without having to scroll. (In MathJax, links point to the actual number of a numbered environment. This is annoying, as you always have to scroll up to see the whole equation.)
  4. For numbering to work correctly, and for consistency when authoring, each line in a numbered environment either needs to contain a \label, a \tag or a \nonumber.
  5. The eqref links are just ordinary <a> tags using KaTeX font. Making these into math objects is overkill (and adds even more spans).
  6. We can have the environment within <p> tags, or outside, no change from normal KaTeX behaviour.

This solution

Currently, this method handles (at least for the examples in this demo):

  1. \labels
  2. \tags
  3. \eqrefs
  4. \refs
  5. Linking to an environment where there is one label or tag in that environment
  6. Linking to individual lines of an environment where there are more than one label or tag in the environment

The code