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

Feature request: LaTeX using MathJax #249

Open
wkjarosz opened this issue Sep 12, 2024 · 7 comments
Open

Feature request: LaTeX using MathJax #249

wkjarosz opened this issue Sep 12, 2024 · 7 comments

Comments

@wkjarosz
Copy link
Contributor

I realize one goal of this project is to be javascript-free, but it would be nice to have the option to output latex equations not as svg, but simply using MathJax. This option would also allow sidestepping the various hoops to get dvisvgm to work properly with libgs on recent version of macOS.

@mosra
Copy link
Owner

mosra commented Sep 12, 2024

I'm sorry but I don't want to maintain such a feature 😅 MathJax with its "async loading" popups and flickers due to relayout is exactly one of the things I despise with passion.

What I could do is exposing the M_MATH_RENDER_AS_CODE option to the Doxygen theme (which makes the math equations displayed as either inline or block fixed-width font), and possibly equip those with some additional CSS class. That you could then hook MathJax to on your end. Both the Doxygen theme and the Pelican theme have options for expanding the HTML <head> with additional tags which you could use to include all necessary MathJax machinery, and then I assume the way it operates is transforming the page DOM, so it could work even without anything MathJax-specific being explicitly done by m.css itself.

But in any case I'd like to try to first solve the issue that made you consider MathJax in the first place -- what is the problem you're facing with dvisvgm on Mac? There used to be a brief window of time on Linux where it didn't work with Ghostscript 10 because version 10 wasn't yet whitelisted in dvisvgm's internal lookup routine, but that felt like it's gone now and that workaround isn't needed anymore. Similarly, all issues that were very common with broken latex installations on Ubuntu distros from 5 to 10 years ago are no longer a problem.

Or are you facing a problem where you need several people to be able to build & view a website or Doxygen docs locally, and LaTeX is a pain point for many of them? That's a valid concern. I'm fine with adding Mac-specific hints or hardcoding common paths or whatever to make it more likely to "just work" on common setups -- tell me what's the common issue and how can I make that smoother.

@wkjarosz
Copy link
Contributor Author

Understood.

Your proposed solution with exposing M_MATH_RENDER_AS_CODE would be perfect for me. I already use an expanded <head> element anyway.

I'll reply with a fuller explanation of the troubles I ran into on macOS when I have a bit more time. Stay tuned

@wkjarosz
Copy link
Contributor Author

wkjarosz commented Sep 12, 2024

Ok, some details of the problems I ran into:

I used m.css and doxgen to create this course website back in 2022. I was generally very happy with the process.

I'm teaching the class again, so needed to create the 2024 edition. I haven't touched the code since then, and was surprised to see that things didn't "just work" anymore.

First, I ran into the issue described in #241. To overcome this, I looked into how to downgrade doxygen to a lower version, but seemingly homebrew does not maintain multiple versions of doxygen, so the solution that worked was to brew remove doxygen, then download the an old version of the doxygen formula off github from the time it did work for me in 2022, and install that manually instead. This resolved the issue described in #241 for me (I haven't checked the fix you have posted for that in the meantime).

Unfortunately, I still had build errors for the website. This time it was with an exception about dvisvgm and libgs. After some stackexchange hunting, it seemed that the version of dvisvgm that I had installed via homebrew didn't work with ghostscript. Notably this did not list Ghostscript:

% dvisvgm -V1
dvisvgm 3.2.2 (aarch64-apple-darwin20.6.0)
------------------------------------------
brotli:   1.1.0
clipper:  6.2.1
freetype: 2.13.2
kpathsea: 6.4.0
mutool:   1.23.11
potrace:  1.16
xxhash:   0.8.2
zlib:     1.3.1

Based on a suggestion on stackoverflow I downloaded and installed the Ghostscript and GhostscriptExtras packages from here. This did not seem to fix anything, even when passing in the location of the ghostscript library via --libgs or via the LIBGS environment variable.

What ended up working is installing macports, installing Ghostscript via macports, and pointing the LIBGS environment variable to the location of that macports ghostscript library. I would then get this result:

% dvisvgm -V1
dvisvgm 3.2.2 (aarch64-apple-darwin20.6.0)
------------------------------------------
brotli:      1.1.0
clipper:     6.2.1
freetype:    2.13.2
Ghostscript: 10.03.1
kpathsea:    6.4.0
mutool:      1.23.11
potrace:     1.16
xxhash:      0.8.2
zlib:        1.3.1

All of this was to bypass errors that stemmed from only a few LaTeX math equations I have on the site. The reason I'd like the option for using MathJax is that the whole experience of resurrecting 2-year old code made me feel that my workflow with m.css was more brittle than I would like. My hope was that reducing my need for additional components like latex2svg.py and dvisvgm (that each have their own versions and installation intricacies) might make things more robust for me going forward.

@crisluengo
Copy link
Contributor

You shouldn't install dvisvgm through Homebrew. It's part of your LaTeX installation. I prefer installing TeX Live (even though the TeX Live page points macOS users to MacTeX, it is easier to follow the generic Unix instructions, MacTeX comes with all sorts of editors and tools that seem quite useless to me).

The only change I would make to the latex2svg.py plugin here is adding /opt/homebrew/lib/libgs.dylib as a potential libsg location. It currently uses /usr/local/opt/ghostscript/lib/libgs.dylib on the Mac, which is true for Intel Macs. For the new Apple Silicon Macs, Homebrew is installing itself in a different location (so you can have both versions installed at the same time). If both are available, then you need to figure out which one is compatible with the dvisvgm program (which depends on which architecture it's built for).

I just realized I'm still using TeX Live 2020, which must be for the Intel chips. I am installing the 2024 release for the Apple Silicon architecture, I'll report back if there are some problems running dvisvgm.

@mosra
Copy link
Owner

mosra commented Sep 12, 2024

I haven't touched the code since then, and was surprised to see that things didn't "just work" anymore.

Hah yes, that pretty much sums up my experience with just about any software nowadays, Python and web-related especially. Even just adapting to new versions of python, matplotlib, graphviz, docutils etc. requires significant effort, to the point I often don't have energy left to add any new features, just barely keeping the project afloat. (With my C++ projects I ended up rewriting most dependencies including large part of STL myself, and the UX and general API stability improved significantly as a result. Sigh.)

First, I ran into the issue described in #241.

Yeah sorry about that, I was building up the courage to touch Doxygen for way too long. I was working on this for the past week and today I have Doxygen 1.12 working for my projects with some patches locally. Now I "just" need to submit all the bugreports and fixes to them, and implement matching workarounds on my end. The progress is tracked in #215 and yes, it's a nightmare too.

it seemed that the version of dvisvgm that I had installed via homebrew didn't work with ghostscript

It's possible that it just didn't see it if it dvisvgm was e.g. in /usr/local/lib but ghostscipt in /opt/homebrew. Or it wasn't whitelisted in its autodetection routine (which is what this workaround in latex2svg fixes). What helps, in my experience at least, is passing a hardcoded path to it, so I "only" need to list enough of those paths in that latex2svg wrapper.

@crisluengo here's a patch corresponding to what you suggested, does it work / does it make sense? @wkjarosz are there any other paths where libgs usually lives (from homebrew, from macports, etc etc), that I could add there?

diff --git a/plugins/latex2svg.py b/plugins/latex2svg.py
index e4a5c520..86ca731c 100755
--- a/plugins/latex2svg.py
+++ b/plugins/latex2svg.py
@@ -52,9 +52,15 @@ libgs = find_library('gs')
 if not hasattr(os.environ, 'LIBGS') and not libgs:
     if sys.platform == 'darwin':
         # Fallback to homebrew Ghostscript on macOS
-        homebrew_libgs = '/usr/local/opt/ghostscript/lib/libgs.dylib'
-        if os.path.exists(homebrew_libgs):
-            default_params['libgs'] = homebrew_libgs
+        for homebrew_libgs in [
+            # Homebrew on ARM Macs
+            '/opt/homebrew/lib/libgs.dylib',
+            # Homebrew on Intel Macs
+            '/usr/local/opt/ghostscript/lib/libgs.dylib',
+        ]:
+            if os.path.exists(homebrew_libgs):
+                default_params['libgs'] = homebrew_libgs
+                break
     if not default_params['libgs']:
         print('Warning: libgs not found')
 # dvisvgm < 3.0 only looks for ghostscript < 10 on its own, attempt to supply

In any case, I'll look into exposing M_MATH_RENDER_AS_CODE right once I'm done with the Doxygen upgrade mess from #215.

@crisluengo
Copy link
Contributor

here's a patch corresponding to what you suggested, does it work / does it make sense?

On older Macs, there will only be /usr/local/opt. On newer Macs, there will be /opt/homebrew, but possibly also /usr/local/opt (as on mine, as there used to be things you had to do in intel-compatibility mode). So looking in /opt/homebrew first I think is the correct way.

Of course, which version of libgs you need depends on which version of dvisvgm you're using. And finding that out is a bit too involved. You'd need to parse the output of the shell command f"file {params['dvisvgm_cmd']}", examining platform.uname().machine if it's a universal binary. I'm not sure this is very useful. If you assume dvisvgm runs natively (as Intel on an Intel chip, as arm on an arm chip), then you can skip all this nonsense.

On my machine, find_library finds libgs in /opt/homebrew, so the fallback is not needed.

@mosra
Copy link
Owner

mosra commented Sep 15, 2024

As of 7baa5a3 the Doxygen theme supports M_MATH_RENDER_AS_CODE.

Additionally, since 4f413bc the math-as-code <pre> and <code> elements contain m-code and m-math CSS classes, which should be unique enough to allow picking them up from the DOM to perform whatever MathJax needs to perform to turn them into actual math. A side effect of this change is that any other CSS classes get propagated there as well, so for example the equation coloring is visible even with this fallback.

Let me know if the suggested addition to latex2svg.py from above would make things any easier on your end, or if more is needed. I think I could even perform that PATH fiddling before invoking MacTeX, if that's something Mac allows me to do, so it's not left on the user.

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

No branches or pull requests

3 participants