James-Yu / LaTeX-Workshop

Boost LaTeX typesetting efficiency with preview, compile, autocomplete, colorize, and more.
MIT License
10.47k stars 519 forks source link

Expand macros defined by NewDocumentCommand for math previews #4205

Closed kaba2 closed 4 months ago

kaba2 commented 4 months ago

Pre-checks*

The Missed*

I wish the math preview panel expanded macros. I write mathematics semantically, not with specific symbols. For example, here's how I declare that f is a continuous function from a subspace of Z to another space.

image

The preview I get is:

image

That is, the macros have not been expanded. Expanding the macros manually, right now it corresponds to:

f: \mathcal{T}_Z|D \xrightarrow{c} \mathcal{T}

And this the preview view renders correctly:

image

The intent is that, if needed, I can change my notations easily later if I come up with something better. That is, like Latex text separates structure from how the article should look, similarly here the mathematics is separated from how it should look. So right now, because of writing mathematics semantically, the math preview is not usable for me. What I instead do is that I write some math in that form, and then recompile the pdf to confirm I got it right. But that is probably slower than what it could be.

The Solution*

Expand macros in an equation before math previews.

jlelong commented 4 months ago

Math preview uses mathjax. If you use personal macros, you have to tell mathjax about them. Beware that mathjax only understands a subset of LaTeX. See

Can you post a complete minimal example to reproduce the problem?

kaba2 commented 4 months ago

It seems that \newcommand is supported, but \NewDocumentCommand is not.

\documentclass{article}

\NewDocumentCommand{\notworking}{mm}{#1^#2}
\newcommand*{\working}[2]{#1^#2}

\begin{document}
$\notworking{1}{2}$
$\working{1}{2}$
\end{document}

image

image

jlelong commented 4 months ago

Unfortunately, mathjax does not understand NewDocumentCommand. See the list of LaTeX commands supported by mathjax https://docs.mathjax.org/en/latest/input/tex/macros/index.html

Converting a macro declaration from NewDocumentCommand to newcommand is not so obvious. Maybe we could restrict to a signature of the form O{[^{}]*}m+, which can be converted quite readily to a newcommand declaration. @James-Yu what do you think?

See https://www.texdev.net/2010/05/23/from-newcommand-to-newdocumentcommand/ for explanations on NewDocumentCommand signatures

kaba2 commented 4 months ago

The ultimate solution would be for MathJax to support \NewDocumentCommand. This has been proposed already in 2021, and the motivation back then was... math preview in Latex Workshop!

https://github.com/mathjax/MathJax/issues/2684

I added my support for it.

kaba2 commented 4 months ago

Perhaps of interest is this small piece of code which adds \NewDocumentCommand parsing to MathJax directly. This was mentioned in the comments in the MathJax issue.

jlelong commented 4 months ago

Unfortunately, the piece of code is quite large and has to be incoporated into mathjax not the extension. If we wish to add minimal support, I believe turning the NewDocumentCommand to a newcommand is probably the easiest way to go.

lucasvreis commented 4 months ago

@jlelong the code mentioned is a Mathjax extension, so it is not meant to be incorporated into Mathjax itself. I'm not familiar with VSCode but perhaps it's possible to make Mathjax load it in the preview window like in a browser window... in a browser you can load it like this: https://github.com/lucasvreis/xparsejax/tree/main?tab=readme-ov-file#usage

kaba2 commented 4 months ago

Handling only a subset of \NewDocumentCommands would not work for me, since I sometimes (although rarely) use multiple optional arguments. Also, simply replacing \NewDocumentCommand with \newcommand does not work, at least in Latex. For example, if do this for my macros, then things break horribly in Latex. I think it has to do with so called robust commands, of which I don't know much, but \NewDocumentCommand provides them out of the box. This breakage happens somewhat unpredictably for example when you compose commands, and pass one with an optional as an optional argument of another, as in \foo[\bar[x]{a}]{asdfdsa}.

An example of macro with multiple optionals: f \tin \continuousxy[A][B] says that f is a continuous function from a subspace A of X to a subspace B of Y.