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

Add MathJax "begingroup" extension #5997

Closed
wants to merge 1 commit into from

Conversation

mgeier
Copy link
Contributor

@mgeier mgeier commented Feb 17, 2019

This enables support for \gdef, which allows defining LaTeX macros that also work when exported to LaTeX.

This was already suggested in this very old issue from the Classic Notebook: jupyter/notebook#490 (comment)

The MathJax docs only mention \def: http://docs.mathjax.org/en/latest/tex.html#defining-tex-macros

But when processed with LaTeX, if \def is enclosed in $ signs, it doesn't have an effect outside the current math expression.

Therefore, when exporting to LaTeX/PDF, the equations are broken.

In LaTeX, one would normally use \def without wrapping it in $signs, but this doesn't work in MathJax.

The solution is to use \gdef, which makes the definitions visible in the following math expressions.

Sadly, support for \gdef isn't enabled by default in MathJax, that's where my PR comes in.

Here's an example for a definition that works in JupyterLab and in the exported PDF file, too:

<div hidden>

$\gdef\vec#1{\boldsymbol{#1}}$

\vskip-\parskip
\vskip-\baselineskip

</div>

A usage of this definition could e.g. look like: $\vec{a}$.

This is a bit complicated, but it is the easiest way I could come up with that allows using the same definition in HTML and PDF.

If anybody knows an easier way how to achieve that, please let me know!

@jupyterlab-dev-mode
Copy link

Thanks for making a pull request to JupyterLab!

To try out this branch on binder, follow this link: Binder

@jasongrout
Copy link
Contributor

I think you don't need to specify the newcommand extension. From the MathJax docs: http://docs.mathjax.org/en/latest/tex.html#tex-and-latex-extensions

the \def and \newcommand macros are implemented in the newcommand.js extension, but MathJax loads this extension itself when you use those macros

As for the begingroup extension, that means definitions would actually apply across all of the open windows, right? So if you define a gdef macro in one notebook, it would automatically be available in another notebook that you opened up? This sounds like it is potentially a source of confusion, but perhaps here's where we just say that it's an advanced feature, and you're responsible for making things work well if you use it.

@jasongrout jasongrout added this to the 1.1 milestone Mar 19, 2019
@mgeier mgeier force-pushed the mathjax-extensions branch 2 times, most recently from 282143b to 4ddca07 Compare March 20, 2019 09:35
@mgeier
Copy link
Contributor Author

mgeier commented Mar 20, 2019

@jasongrout Thanks for looking into this!

the \def and \newcommand macros are implemented in the newcommand.js extension, but MathJax loads this extension itself when you use those macros

I've actually read this and I've tried it and for some reason it didn't work. But I must have made a mistake [UPDATE: see my next comment]. I just tried it again and it works fine without explicitly specifying 'newcommand.js'.
I've updated the PR.

As for the begingroup extension, that means definitions would actually apply across all of the open windows, right?

That's an interesting point, I didn't think about that!

Apparently there are no separate MathJax instances per (JupyterLab) tab.
If you define a LaTeX macro in one (JupyterLab) tab, then switch to a different (JupyterLab) tab and then create a new Markdown cell using this macro, it will be recognized.
However, if you then (save and) reload the browser page, it will stop working.

Also, if some LaTeX macro is defined in the current notebook and you open another notebook where this macro is used but not defined, it will still be recognized (until re-loading the page).

OTOH, if you have a notebook opened (without LaTeX macro definitions) and you open a different notebook that defines and uses some LaTeX macros, those will not work! You have to refresh the browser for those to start working.

Having said all this, this is a completely unrelated issue, because this also happens when using \def instead of \gdef. I guess the running MathJax instance would have to be re-triggered whenever the user switches (JupyterLab) tabs?

@mgeier
Copy link
Contributor Author

mgeier commented Mar 20, 2019

FYI: It seems that explicitly specifying 'newcommand.js' is not necessary for JupyterLab. However, it does seem to be necessary when using MathJax with Sphinx, which was where I tried it first: spatialaudio/nbsphinx#288.

I don't really know what's the difference (probably using a CDN URL or not?), but I thought it might be relevant information for someone ...

mgeier added a commit to mgeier/notebook that referenced this pull request Mar 20, 2019
mgeier added a commit to mgeier/notebook that referenced this pull request Mar 20, 2019
@mgeier
Copy link
Contributor Author

mgeier commented Mar 20, 2019

WARNING: This doesn't seem to work on Binder using this URL: https://mybinder.org/v2/gh/mgeier/jupyterlab/mathjax-extensions?urlpath=lab-dev [UPDATE: I've changed the PR, now this branch works again]

I don't know if that's a problem with my PR or something else.

UPDATE: I tried it with explicitly using the newcommand extension, and (tadaa!) it works on Binder: https://mybinder.org/v2/gh/mgeier/jupyterlab/mathjax-with-newcommand?urlpath=lab-dev [UPDATE: this branch doesn't exist anymore]

So I guess I should keep it after all?

@jasongrout
Copy link
Contributor

jasongrout commented Mar 21, 2019

https://math.meta.stackexchange.com/questions/4130/the-scope-of-newcommand-is-the-entire-page has some interesting ideas on how to scope new commands to a part of the page, by automatically surrounding things by groups automatically.

This enables support for \gdef, which allows defining LaTeX macros that
also work when exported to LaTeX.
@mgeier
Copy link
Contributor Author

mgeier commented Mar 21, 2019

@jasongrout That sounds interesting, but I have no idea if something like this would work with JupyterLab's tabs.

But anyway, this PR is not about that.

I've re-added the 'newcommand.js' for it to work on Binder, too.

@jasongrout
Copy link
Contributor

jasongrout commented Mar 21, 2019

I experimented a bit with the require command mentioned in that stack overflow post. This also works for me without changing jlab:

$$\require{begingroup}\require{newcommand}$$
$$\gdef\vec#1{\boldsymbol{#1}}$$

Then I can do:

$$\vec{a}$$

and everything works.

Edit: Does this also work for you? How does this behave in the latex export?

@mgeier
Copy link
Contributor Author

mgeier commented Mar 21, 2019

Thanks for experimenting with this!

The problem with your suggestion is that it doesn't work when exported to LaTeX, because LaTeX doesn't understand \require. And exporting to LaTeX is the whole point of this PR.

mgeier added a commit to mgeier/notebook that referenced this pull request Mar 21, 2019
@jasongrout
Copy link
Contributor

So this would work?

<div hidden>
\newcommand{\require}[1]{}

$\require{begingroup}\require{newcommand}$
$\gdef\vec#1{\boldsymbol{#1}}$

\vskip-\parskip
\vskip-\baselineskip

</div>

@jasongrout
Copy link
Contributor

FYI, I'm exploring other options, like the above, that don't require changes to jlab so that (a) you have backwards compatibility with the classic notebook and older versions of jlab, and (b) so that the complications that come up with gdef redefining things across the page are minimized, or at least exposed to those who presumably better understand the complications.

@jasongrout
Copy link
Contributor

@mgeier - did the above solution in #5997 (comment) work for you?

@mgeier
Copy link
Contributor Author

mgeier commented Mar 27, 2019

@jasongrout Thanks a lot for your suggestions! Well, it indeed works great in JupyterLab and when converting with nbconvert (both HTML and LaTeX output), so I guess there is no reason to merge this PR. Sadly, I couldn't make it work with nbsphinx yet. I don't know why exactly, but I guess some differences in handling the pandoc output break your suggested approach.

I still have to further look into this, if you have some ideas, please let me know!

I guess this PR can be closed, though.

@jasongrout
Copy link
Contributor

Thanks for exploring things here!

@jasongrout jasongrout closed this Apr 22, 2019
@jasongrout jasongrout modified the milestones: 1.1, Reference Apr 22, 2019
@lock lock bot added the status:resolved-locked Closed issues are locked after 30 days inactivity. Please open a new issue for related discussion. label Aug 7, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Aug 7, 2019
@mgeier mgeier deleted the mathjax-extensions branch June 10, 2020 12:29
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
pkg:mathjax2 status:resolved-locked Closed issues are locked after 30 days inactivity. Please open a new issue for related discussion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants