Ipython: Equation numbers in the notebook.

Created on 26 Aug 2013  ·  45Comments  ·  Source: ipython/ipython

IPython's inline LaTeX doesn't include equation numbering. It would be great if LaTeX sequences that are normally numbered (i.e. \begin{equation} ... \end{equation} blocks) got (optional?) numbers. A slam dunk would be if we could attach references to equations and reference them somehow later in the text.

notebook

Most helpful comment

is this already solved or should I +1 this?

All 45 comments

+1
This is a rather important feature for any kind of mathematical document.
I believe that MathJax already has this capability:

http://docs.mathjax.org/en/latest/tex.html#automatic-equation-numbering

As far as references go, I think that it is crucial to develop a generic cross-reference system with a unified syntax, and not one which is specific to LaTeX equations (and LaTeX backends).

I agree that there must be generic cross referencing system, but would add that it should also be able to interface with the python code. This would allow latex in the markdown to reference figures produced in the code.

This would probably have to wait until a system for accessing python variables from markdown cells is available, as it would probably use a similar system.

@ahmadia what is the problem why equations cannot be numbered by default? Not being able to number and reference equations is something that's quite annoying currently.

+1. Seems like implementing #5921 would allow this easily.

+1. Hope this being implemented very soon

+1

+1.
I am using ipython notebooks to supplement course material for a university junior-level electromagnetics course, and am doing so as a test case for whether to push for broad ipython notebook implementation throughout our undergraduate curriculum. Lack of consistent equation numbering in a notebook, or within sections of a notebook, is a serious limitation, along with the ability to reference equation numbers in the text. I am fine with such numbering being specific to LaTeX portions of a notebook, especially if trying a more general approach means a longer wait to get this functionality.

+1.
Same here, I am writing my notes for a Numerical Calculus course using ipython and reference numbering is really missing.

+1

This is the only thing stopping me from using iPython Notebooks as my main document writing tool (save for the lack of real-time collaboration, but that's not as important). Instead, I have to do rough drafts here and then port them over to a LaTeX editor.

+1 :+1: We are using this to give lectures and this feature is absolutely necessary!

Ok, I finally tried the "solution" described in this post where you modify mathjaxutils.js. As long as you refresh the ipython notebook webpage after making changes to markdown cells that contain latex, equation numbers show up and do so in the proper order. Refreshing the page also fixes labels, which become unresolved when the cell in which they are defined is re-run (i.e., shift-enter). However, when the notebook is rendered in nbviewer.ipython.org the equation numbers are completely missing, and labels are unresolved so they are replaced with "???" where they are referenced in markdown text cells. The bottom line is that this is not much of a solution for most use cases, although I'm glad the original poster asked the question and figured out this much.

^ Is this the currently recommended solution?

Bump. I am using Jupyter notebooks for my course notes and this is a serious issue. Would a convenient syntax for manually numbering equations be a decent compromise?

Would a convenient syntax for manually numbering equations be a decent compromise?

That's a good idea @poulson and there's the \tag syntax in MathJaX that supports this.
Manual MathJax Equation Tags in the Jupyter Notebook example. Same limitations (re-executing a Markdown cell will cause MathJaX to break if you don't refresh the browser), but at least you don't have to reconfigure the notebook to do it.

@ahmadia Thanks! Re-executing breaking the cell is definitely a bit frustrating, but this is huge progress from \begin{equation} not labeling!

@ahmadia Is it expected that the equation references don't resolve in your link or in the live notebook (even after refreshing)?

Try refresh then execute all cells. I don't think the links work in GitHub
because GH strips URLs.

On Saturday, October 3, 2015, Jack Poulson [email protected] wrote:

@ahmadia https://github.com/ahmadia Is it expected that the equation
references don't resolve in your link or in the live notebook (even after
refreshing)?


Reply to this email directly or view it on GitHub
https://github.com/ipython/ipython/issues/4113#issuecomment-145305340.

That didn't work for me, but since everything is being hardcoded, I don't see any reason to insist on using \ref. I therefore hardcoded the equation numbers for the references and produced the final product that can be seen here: http://web.stanford.edu/class/math53/notebooks/Week2.html

Thanks @poulson for pushing this. I am hit by this over and over again, and hardcoding equation numbers is pretty bad, but what can one do... IPython should have native support for this.

Best work-around so far, thanks guys!

If you include the code:

MathJax.Hub.Config({
  TeX: { equationNumbers: { autoNumber: "AMS" } }
});

in a javascript extension, or even in a javascript output in the notebook, automatic equation numbering will be turned on. It will have all of the problems that prevent us from doing it by default, mainly that mathjax equation numbers are ordered by render time, not location on the page, so numbering will only be correct on first page load.

Actually, you can reset the equation numbering and rerender the equations in the notebook.

I made a simple notebook extension that does this:
https://github.com/ipython-contrib/IPython-notebook-extensions/pull/335

@juhasch great! Given the very poor experience of equation numbers under most circumstances, I think defaulting to off is the best choice. But making this a frontend-config option with the action to renumber would be great (toolbar button is probably too-precious space to devote to it, but a menu action would be fine).

I imagine using the re-render/re-number rather often when creating notebooks, so I'd vote for a toolbar button or, if it goes into the menu, at least a normal-mode hotkey.

@lucasb-eyer I think that's a fine thing to do for an extension like @juhasch has provided, but we probably wouldn't do it by default, since both default keyboard shortcuts and toolbar space are extremely precious. But it would be possible to add either or both via custom.js or nbextension.

@minrk: The extensions can be easily activated/deactivated and re-rendering turn on/off using the nbextensions server extension:
clipboard01

If you press the button toolbar button, equation numbering is reset/re-renderd.

@juhasch thanks for your work! This is a great step forward.

@minrk in your experience, what would you propose as the long term proper solution to the equation numbering? @juhasch's extension is just a workaround for now. I am not asking you to implement it, just outline what the solution should be. I think there is plenty of people truly bothered by this, and if we know what the right way forward is, we can try to give it a shot.

what would you propose as the long term proper solution to the equation numbering?

You can't have it. MathJax assumes that it has access to the entire page when it performs equation numbering, and IPython renders Markdown on a cell-by-cell basis, which is the only sane way to do it for large notebooks. It would require work/implementation on the MathJax side of things, not the notebook.

Most people (including me) just want equation numbering. I don't think we care so much how it is technically implemented. So I can see several possible ways forward, for example adding some patches to MathJax that allow the notebook to tell it the equation number without it having access to the whole page, or another solution is to just use MathJax to render the equation without the number, and then render the number by the notebook itself. There might be more options. But I would like to have some official blessing on which way is the best, as I am not well versed in the internals.

what would you propose as the long term proper solution to the equation numbering?

For now, I would basically do what @juhasch has done with his extension, with the following changes if merged into master:

  1. make it off by default
  2. store toggle in frontend-config, so you only need to turn it on once
  3. add renumbering action, so it can be bound to a keyboard shortcut
  4. put the default UI for renumbering in the menu instead of the toolbar

Basically, I would make it slightly worse than the extension for those for whom this is a priority, since that doesn't make sense as a default. Once the action is available, though, adding things like shortcuts and toolbar buttons becomes a simple customization for those who have different priorities.

I don't know how feasible always-correct numbering is, because it would mean that on _any_ rendering of a markdown cell or HTML output, numbering would need to reset, and _all_ markdown cells and HTML outputs would need to be re-rendered, every single time.

Given documentation, that sounds like a reasonable plan to me as a user. :+1:

@minrk: as a user, I too would find this a useable solution. How onerous would it be to re-render all markdown and HTML outputs?

@gregnordin that's going to depend on the size of the notebook, and grow unbounded with the size of the notebook. It would mean that every time you edit a markdown cell, it could take a similar amount of time to render as loading the entire notebook when you first open it. Definitely not okay for a default behavior, but if an extension wanted to try to take a stab at it, they would be welcome to try.

+1

+1 for this feature. I'm preparing lectures on physics for students and equation numbering is essential.

Another option, that allows the equation numbers to be updated, without rerendering everything, is a javascript that searches the HTML output for elements with equations or references, and replaces their text with the appropriate value.

To get that fully functional would require a few modifications in MathJax, setting additional attributes for the elements that need to be updated, so that the script can recognize them.

At the moment that support is not there, but the following work arounds will do the trick

  • use \tag{labelname} to create an equation number. Note that here the tag is the label
  • reference it in markdown with raw html code <span class=reference data-target=labelname></span> This is necessary because the HTML output of \ref or \eqref does not include the labelname.

for example

$$
\begin{equation}
  A = 1 \tag{eq:sample}
\end{equation}
$$

The amazing result in <span class=reference data-target="eq:sample"></span> can ...blah..blah

The following script updates the equation numbers. It needs to be run after new equation numbers or references have been rendered. For now you can put the script in a separate cell and run it manually when needed. A full solution needs some mechanism to trigger a rerun at appropriate times.

%%javascript

// find all equation numbers (tags) that have no data-label attribute and set
// it to the tag text
$("span.mtd[id|='mjx-eqn']").not("[data-label]").each(
    function (index)
    {
        $(this).attr("data-label", $(this).text().slice(1,-1));
    }
);

// loop over all equation numbers and set the text 
$("span.mtd[id|='mjx-eqn']").each(
    function (index)
    {
        $(this).text("(" + (index+1) + ")");
    }
);

// loop over all references and resolve them by finding the
// equation number with a matching data-label attribute
$("span.reference").each(
    function (index)
    {
        var target = $(this).attr("data-target");
        var eqn = $("span.mtd[id|='mjx-eqn'][data-label='" + target + "']").text()
        $(this).text(eqn)
    }
);

Note that the script only updates the numbers, leaving all layout as it is. It should be far more efficient that letting MathJax rerender everything.

@basvandertol Thanks for the sample, but I don't see how this is useful as the results are only visible on the current screen: they aren't saved, can't be printed, can't be viewed in nbviewer, nor seen in any output (PDF, HTML, etc.) I don't see that this is a work-around. Did I misunderstand you? Or is this just part of a solution?

Thanks for the feedback @dsblank. It is indeed only a partial solution, specifically to the problem of updating the equation numbers while editing the notebook without rerendering everything. I was experimenting with HTML data attributes to achieve this. I later discovered that nbconvert uses a similar approach to deal with Latex citations. http://nbconvert.readthedocs.io/en/latest/latex_citations.html

At the moment MathJax does not add sufficient attributes to the HTML output to resolve references after rendering. That's why I use these hackish labels and references to get the HTML output I need. With these labels the normal conversion to Latex ->pdf is broken.

I am now familiarizing myself with the MathJax source code to see if there is some easy way to add the HTML attributes to the normal labels and references.

The next step would be to add support in nbconvert to recognize these HTML attributes, just as it already does with citations. If nbconvert could also scan the output of code sections for HTML with these attributes, then a HTML caption/label can be a added to code-generated figures, and nbconvert
can generate the correct Latex output. Figures can then be referenced in markup cells.

It is just an outline of an approach to full support for references in ipython notebooks. It seems feasible to me, but if anyone already sees a showshopper now, please let me know. I know very little about the internals of the ipython notebook. This seems like a fun project to learn more, but right now I can not oversee all implications.

Just found this (long) thread...

May be that this could be of interest: I have attempted something to support rendering of LaTeX environments, including _automatic numbering and update_ of both equations and environments, document-wide.
It used a button for refreshing but now uses an idea similar to that mentioned by @basvandertol above.

Of course all this adds some overload, but this is largely acceptable for me, even for quite long documents. Export of notebook to html and LaTeX documents is available;

You can have a look at the extension here or on Pypi. Best.

+1 for integrating some version of the proposed solutions into master.

is this already solved or should I +1 this?

Was this page helpful?
0 / 5 - 0 ratings