Looking around more, I see this conversation https://groups.google.com/g/mathjax-users/c/51PeC3HKuQM "Equations converted to images" asking for markup-to-SVG image files. Looking into the GitHub entry, it appears that NodeJS (?) needs to be installed, and a headless Chrome browser is used. Is this the best I'm going to be able to do?
It's a lot to ask of users who want equation support when creating PDFs, but as long as it's well-supported programs being used, they may be willing to go through this. I presume that I would feed either a file containing the TeX markup, or export as a file, to a command line tex2svg and a little later get back an SVG file?
Is any external command-line utility going to be NodeJS or other Javascript-based?
I can understand a preference for that from the MathJax end, as they only have to concentrate on their JS implementation, and not have to translate/maintain other systems, but from the Perl community standpoint it's a bit awkward.
It sounds like the use of Node.js is going to be my best bet. I have never used it before, and reading the Node.js pages they talk a lot about things "on the server". I'm hoping that by this they mean just the server side of the system, and not that they require a full-fledged web server.
In other words, this whole thing should run on my Windows PC, or any other box, where I'm creating a PDF with equations?
Is there any guidance on what additional or optional pieces are needed to be able to use MathJax? It's a bit overwhelming, and I don't want to have to do a lot of trial and error finding out what I need to install from Node.js in order to use MathJax, as well as what I need to install from MathJax.
You say that a headless Chrome browser is not necessary in most cases. What sort of things might someone do that would come out much better using Chrome?
Of course, I already have the browser, but I have no idea if I need to obtain or install something else to do the headless bit.
I looked around CPAN, and there are the two JS engines you mentioned, but they both appear to require manual installation of various libraries and subsystems, which is a big turn-off for most users (more so on Windows).
There is also a claimed pure Perl JS engine (JE), but its development seems to have stalled some time ago. I think I'm better off using a nice clean Node.js + MathJax "name brand" system. Worst case, I can always switch over to one of the three JS engines at a later date.
Regarding the use of files to send markup out, and get HTML or SVG back, that's a last resort if I can't get pipes running. I think it can be done, but I don't have a lot of experience in that area.
I like the idea of starting up the whole thing when a MathJax equation is found, and leaving it running until the PDF creation program is finished, dropping markup into the outbound pipe and grabbing the result from the inbound pipe.
From the MathJax end, is this well documented, and maybe some examples?
I'm guessing that the 'tex2svg' example might be a good starting point (I'll have to try it first), and maybe an HTML-output one too.
Rather than having my users install the MathJax-demos package, would I just supply a program derived from tex2svg?
Is that all that's needed, once Node.js is installed?
Of course, it will likely have to be modified to use pipes.
I wouldn't ask the MathJax people to rewrite in Perl (not that popular anymore, anyway)!
A C or C++ version might be useful,
On Monday, June 6, 2022 at 9:49:39 AM UTC-4 Davide Cervone wrote:Looking around more, I see this conversation https://groups.google.com/g/mathjax-users/c/51PeC3HKuQM "Equations converted to images" asking for markup-to-SVG image files. Looking into the GitHub entry, it appears that NodeJS (?) needs to be installed, and a headless Chrome browser is used. Is this the best I'm going to be able to do?Since MathJax is written in Javascript, the most direct solution is to use node.js to run it as an external program. You don't actually need the headless Chrome, however, as MathJax can run with its own internal DOM implementation, but if you will be using characters outside of MathJax's fonts, however, the results will be better if you do use headless Chrome.I did some poking around, and there seems to be a very old Javascript package for perl (https://metacpan.org/dist/JavaScript) that seems to be based on libjs, in turn based on mozilla's engine, and a more recent one that works with the V8 engine (https://metacpan.org/dist/JavaScript-V8). I have not tried either of these, but the later seems that it might have a chance at running MathJax. But both still require external library installations, and in either case, you would still need to have a MathJax installation. This can be done easily via npm (node package manager), or via a ZIP file from GitHub.It's a lot to ask of users who want equation support when creating PDFs, but as long as it's well-supported programs being used, they may be willing to go through this. I presume that I would feed either a file containing the TeX markup, or export as a file, to a command line tex2svg and a little later get back an SVG file?You could do that, but it may be more efficient to use pipes to do it rather than intermediate files. It is not clear whether you want to process each equation separately, or process an entire page at once (either is possible). If you are doing individual equations, you may want to use a single program that starts up once (rather than incurring the overhead of starting a separate process that needs to load and compile MathJax for each equation), where you send each equation to it via a pipe, followed by some "end-equation" marker, it processes the expression and sends the SVG back on a return pipe (followed by an "end of output" marker). Your program sends are receives the expressions and their output using the same sub-process for all of them.Is any external command-line utility going to be NodeJS or other Javascript-based?Most likely.I can understand a preference for that from the MathJax end, as they only have to concentrate on their JS implementation, and not have to translate/maintain other systems, but from the Perl community standpoint it's a bit awkward.MathJax's main use-case is in web pages in a browser, and that is naturally javascript-based. It's other main use case is preprocessing web pages on a server, and that is readily done via javascript as well. Using the same language in both settings is a significant advantage, as it means the same code works in both places, maintaining consistency and reducing maintenance costs. The MathJax code is both large and complex, and makes significant use of Javascript prototype-based inheritance mechanism, which is significantly different from Perl's package-based class structure. A conversion to Perl would be a major undertaking, and is not something we have the resources to provide.Davide
--
You received this message because you are subscribed to the Google Groups "MathJax Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mathjax-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mathjax-users/a7e4b1f4-37cc-4534-a24f-9ce5feb96131n%40googlegroups.com.
I hope that the pipe-usage code will be platform-agnostic, but as I can only test with Windows, I'll have to cross my fingers and hope that someone on Linux etc. can test for me (I know a Dutch user on Linux who will probably be willing to try it).
At some point, I'd like to test out "with Chrome" to see what difference that makes for non-standard fonts, and include instructions. I hope there's an example around somewhere so I can test it out. That also applies to SVG output, and not just HTML?
By the way, does the Node.js-based processor know about inline versus display equations? For the former, I'm guessing I would have to pass some information about the available line height? For the latter, I may or may not make use of any equation numbering that MathJax provides -- I'll have to see what's provided.
To view this discussion on the web visit https://groups.google.com/d/msgid/mathjax-users/98c501d0-f5cc-46be-8f87-2c66fa6d98a4n%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mathjax-users/31a4eaa8-86fc-47fe-819d-4eb77c838787n%40googlegroups.com.
Your instructions said "node install mathjax" but it complained it couldn't find the module "install". Did you mean "npm install mathjax"? That seemed to work.
Then I installed the MathJax demos: "npm install https://github.com/mathjax/MathJax-demos-node" seemed to do the trick.
Then I had to find where tex2svg had been hidden,
I looked in the SVG file and was a bit distressed to see that it included paths (with ABSOLUTE COORDINATES! ... maybe the translate() takes care of relocation?) to draw all the glyphs, rather than text instructions, but I guess that the MathJax developers felt that was the better way.
I haven't checked yet, but I'm hoping that if I use "A" twice, it doesn't put the glyph path in twice!
I still need to
- write some Perl code to send an arbitrary equation from PDF::Builder to MathJax and retrieve the SVG file, via tex2svg (as proof of concept)
- write a tex2svg replacement module sending either a file or a command-line string, and retrieving a file
- implement your piped interface (I haven't had a chance to look at it yet) in the tex2svg replacement (keep file interface if user has trouble with the pipe)
- take a look at inline vs. display (per your note), and equation numbers for display (at least, leave space for me to write them)
- take a look at headless vs browser for certain cases, and implement such support for users who need it
- finish implementing SVG support for PDF (now that I know what sort of support MathJax will be expecting)
- consider HTML support, as I need at least limited HTML support for some other stuff (see how complex the CSS turns out to be)
By the way, I do have IPC::Open2 installed (v1.04). Regarding where the install is made, I guess that a user can always update the Perl code to point to wherever the module lives (node_modules/ path), since there doesn't seem to be a single standard repository for installed modules.
Is there any way to reply on this group without copying the entire previous post, or at least, allow editing of it to show selected parts? You're doing it, so I take it there's a way...
Sigh. My reply appears to have gone directly to Davide and not to
here. Try again.
OK, let's try a mail reply rather than using the webpage
interface.
Apparently I copied the MathJax.pl code into the mathjax.js file accidentally rather than the needed javascript. I've updated the gist, so give it another try (you can just download the mathjax.js file, as that is the only one changed).
By the way, I do have IPC::Open2 installed (v1.04). Regarding where the install is made, I guess that a user can always update the Perl code to point to wherever the module lives (node_modules/ path), since there doesn't seem to be a single standard repository for installed modules.
The problem was that node was trying to run the perl code (since I pasted the wrong file into mathjax.js), and was complaining about the syntax of "use IPC::Open2", since that is not value javascript. It has nothing to do with whether IPC::Open2 is installed in perl or where. That will be in the user's perl installation, not the node_modules directory.
Where you place the files from the gist is up to you, but once you have it where you want it to be, you will need to do "npm install" in that directory, and that will create the node_modules subdirectory there. That is the correct place for it, and should not be changed, or node won't be able to find its needed modules.
I get the messages via email and reply to them that was as well, so can edit out the piece that I don't want to include. I have not used the on-line interface, but I suspect you can edit out the original message there as well.Is there any way to reply on this group without copying the entire previous post, or at least, allow editing of it to show selected parts? You're doing it, so I take it there's a way...
OK, here are the results, with some added print debugs:
C:\Users\Phil\Desktop\MathJax.pipe>main.pl
START <=== print OPIPE returned $line from pipe-handler
start
\frac{x^2}{2} <=== print $tex LaTeX to convert
ERROR Unexpected end of JSON input <=== print OPIPE
returned $line after TYPESET command
MathJax Error: Unexpected end of JSON input at ./MathJax.pl
line 41, <OPIPE> line 2.
It doesn't look happy. 3 debug lines were added, so the original error message was line 38.
Two further questions:
1. Is it sending the "display" flag over to MathJax, some place?
2. Does anything need to be sent to shut down MathJax when I'm done with it? The main.pl sends two examples, so I'm guessing that you did implement keeping the pipe open for multiple uses, but does it shut down at the end (such as when Perl goes away)?
By the way, my last message to you is "marked as abuse" when I'm not signed in to Google Groups, but I didn't see that message when I logged in. Did you accidentally hit a "report as abuse" button when looking at it?Apparently I copied the MathJax.pl code into the mathjax.js file accidentally rather than the needed javascript. I've updated the gist, so give it another try (you can just download the mathjax.js file, as that is the only one changed).
I d/l the zip file, unzipped, and copied the new mathjax.js over the bad one. Is that all I needed to do? Or did I need to do a new install?
I was just trying to reassure you, if you saw the error on "use IPC::Open2;" and thought it was because I didn't have IPC::Open2 installed on my Perl. Didn't want to send you down the wrong path and all that.The problem was that node was trying to run the perl code (since I pasted the wrong file into mathjax.js), and was complaining about the syntax of "use IPC::Open2", since that is not value javascript. It has nothing to do with whether IPC::Open2 is installed in perl or where. That will be in the user's perl installation, not the node_modules directory.
I'll probably have the user (who installs and configures PDF::Builder) check where it's looking for the modules (where they installed it), and update the configuration that PDF::Builder looks in to find where MathJax is. Is MathJax itself installed as part of your gist, or does it matter that it's in a different place?Where you place the files from the gist is up to you, but once you have it where you want it to be, you will need to do "npm install" in that directory, and that will create the node_modules subdirectory there. That is the correct place for it, and should not be changed, or node won't be able to find its needed modules.
1. Is it sending the "display" flag over to MathJax, some place?
2. Does anything need to be sent to shut down MathJax when I'm done with it? The main.pl sends two examples, so I'm guessing that you did implement keeping the pipe open for multiple uses, but does it shut down at the end (such as when Perl goes away)?
By the way, my last message to you is "marked as abuse" when I'm not signed in to Google Groups, but I didn't see that message when I logged in. Did you accidentally hit a "report as abuse" button when looking at it?
Great news! Your example (with pipes, from Perl) appears to work
well. Thank you for putting the effort into this. Of course, feel
free to add it to the examples for your next MathJax release.
So the solution is now to update the MathJax.pl file to the one in the current gist. So sorry about the error (one paste mistake has ripple effects).
I'll probably have the user (who installs and configures PDF::Builder) check where it's looking for the modules (where they installed it), and update the configuration that PDF::Builder looks in to find where MathJax is. Is MathJax itself installed as part of your gist, or does it matter that it's in a different place?
I would assume that your PDF::Builder will include your versions of the files from my gist (once you modify them to your liking), and that your installation process will trigger the "npm install" command in the directory containing them (or else ask the user to do that). That will cause the node_modules directory to be created and MathJax to be installed (you should NOT include the node_modules directory in your package directly). That is the correct place for MathJax, and it will be found by the pipe-handler and mathjax.js files automatically. Since the (updated) gist files will be in your PDF::Builder distribution in the location you have placed them, PDF::Builder should know where there are and be able to call them from that location. I don't see why there should be a need for user configuration for that (but I'm not all that familiar with perl package distributions).
2. Does anything need to be sent to shut down MathJax when I'm done with it? The main.pl sends two examples, so I'm guessing that you did implement keeping the pipe open for multiple uses, but does it shut down at the end (such as when Perl goes away)?
On Unix, the mathjax sub-process should end when the perl program ends. But if you want to be explicit about it, you can add an End() command to MathJax.pl that sends the END command to the MathJax pipe. The pipe-handler already has code to handle the END command on the pipe.
By the way, my last message to you is "marked as abuse" when I'm not signed in to Google Groups, but I didn't see that message when I logged in. Did you accidentally hit a "report as abuse" button when looking at it?
I have removed the mark. Not sure whey that happened.
Hmm. I still see it on the web page as a guest, but not when signed in. Quite odd.
So that should pretty much take care of items 1-4 on my list. I
need to think about mapping the SVG coordinate system to PDF's
(and coordinating with text size, especially for inline), and how
to handle the resizable display-with-equation-number. Does
MathJax have any knowledge of the column width to format in, or
is it the responsibility of the author to make sure that
equations fit? It looks like the SVG processing is going to
be a bit more complicated than I had hoped, but it's still
feasible. Then I can play with headless vs browser and see what
the effects are and whether it's worth adding support for browser
use (the default, in your sample code, is headless?). I should
probably add support to return an SVG file in case the
pipes don't work, but I may put that off til later. It may be
pointless to support HTML/CSS from MathJax, unless it gives
significant additional capabilities.
Again, thanks much for all your work. I'll try to remember to
drop a note here when I've got everything working later this year.
The use of MathJax will be an optional package, so I'll probably have them install NodeJS and then MathJax manually,
as well as your piped version of tex2svg.
I'm assuming that the full MathJax still needs to be installed, even with your package -- is that correct?
They may have to manually set a path to where MathJax things are, in Perl code (or a config file) -- I don't know yet where things will sift out to. To Be Seen.
Per your suggestion, I added in MathJax.pl a new sub End { print IPIPE "END\n"; } and at the end of main.pl I added MathJax::End();. I guess it's working (at least, no errors reported). Does that code sound about right?2. Does anything need to be sent to shut down MathJax when I'm done with it? The main.pl sends two examples, so I'm guessing that you did implement keeping the pipe open for multiple uses, but does it shut down at the end (such as when Perl goes away)?
On Unix, the mathjax sub-process should end when the perl program ends. But if you want to be explicit about it, you can add an End() command to MathJax.pl that sends the END command to the MathJax pipe. The pipe-handler already has code to handle the END command on the pipe.
I won't be firing up MathJax unless Equation code is encountered, and then when PDF::Builder is done it will call End() if MathJax is running. That should avoid repeated startups and shutdowns while a document is being processed.
By the way, my last message to you is "marked as abuse" when I'm not signed in to Google Groups, but I didn't see that message when I logged in. Did you accidentally hit a "report as abuse" button when looking at it?
I have removed the mark. Not sure whey that happened.Hmm. I still see it on the web page as a guest, but not when signed in. Quite odd.
So that should pretty much take care of items 1-4 on my list. I need to think about mapping the SVG coordinate system to PDF's (and coordinating with text size, especially for inline), and how to handle the resizable display-with-equation-number.
Does MathJax have any knowledge of the column width to format in, or is it the responsibility of the author to make sure that equations fit?
It looks like the SVG processing is going to be a bit more complicated than I had hoped, but it's still feasible. Then I can play with headless vs browser and see what the effects are and whether it's worth adding support for browser use (the default, in your sample code, is headless?).
plus some other information about it (most of which is optional). See
for documentation on that. With the mathjax package as a dependency of your package, it will be install automatically when yours is installed.
Does MathJax have any knowledge of the column width to format in, or is it the responsibility of the author to make sure that equations fit?
Version 2 includes automatic line breaking, but that hasn't yet been ported to v3
Well, I think we are using the terminology differently. The gist I provided you does not use a browser (headless or otherwise), but instead uses a limited DOM implementation in javascript. That DOM does not include computations of the sizes of things, or handle CSS or other fancy bits; it is just for the structure of the DOM. The "puppeteer" directory in the node demos repository shows how to hook MathJax to a "headless chrome", which is a full Chrome application, but set up not to open any windows (that is the meaning of "headless" in this context). Doing that makes it possible to handle all the CSS and size measurements that are possible in a normal browser, but without seeing the page in a window (so it can work on a server that doesn't even have a monitor to show windows on). It is a more complicated arrangement (both in terms of installation and programming), and does take longer to spin up since it launches Chrome to do it, but once it is running, it should be reasonably efficient. With the pipe-handler approach, that would certainly be a viable mechanism, if a bit more complicated.
Good luck with the project.
Davide
Thanks much for all your help!
Phil
OK, I presume I can figure out how to have my install package pull in the necessary MathJax package.
One other thought regarding some sort of line breaking -- is it considered good typography to potentially split an equation across a page break?
Splitting up an equation to fit in a narrower column isn't too bad, but how hard should one strive to keep it all on the same page?
As far as the mechanics of line breaking go, would the result be a series of SVG files (one per resulting line)?
OK, for the time-being, I'll just advise users to pay attention to their column width (that an equation should fit in) and to manually adjust the equation to fit (including breaking into multiple pieces). When creating a PDF, a page's column width should be pretty much fixed -- no need to worry about dynamically varying widths. Perhaps some day some sort of automatic or optional line breaking will be handled by MathJax, and my code will be updated to accommodate that.
Regarding breaking across pages, it's understandable that it's not desirable, so for the time-being I will keep equations (including multi-line ones) on one page, much like an image would be handled. Perhaps in the future, something can be done to allow splitting at a page break, while honoring typographic and mathematical standards.
While display equations are pretty straightforward, I can
see issues with inline equations. Some could be
potentially long enough, if not wrapped (split in the middle), to
cause a huge hole in a paragraph if the whole thing has to be
shoved off to the next line. Even worse, if it's longer than an
available line width, it can't fit at all without breaking it. For
now, I'll just have to warn users to be careful about long inline
equations, and give an error message if it won't fit at all. A
user could possibly manually split an inline equation by turning
it into two or more adjacent inline equations, assuming the
fragments will fit nicely next to each other. Support for breaking
an inline equation at reasonable places (given the remaining space
available) would be much appreciated, if it's not already there,
as would be guidance on handling such things. Maybe something like
a \b given at reasonable break points (such as after a +
or -) could help. For multiplication, perhaps a \cdot or something
could be added at a break (like a hyphen when breaking a word)?
A user could possibly manually split an inline equation by turning it into two or more adjacent inline equations, assuming the fragments will fit nicely next to each other.
I just tried this out with HTML in a browser. Say, you have a longish inline equation \(a long equation\) that might cause a large gap at the end of a line if it doesn't fit. Splitting it into \(a\)\(long\)\(equation\) breaks nicely at the end of the line, although the fragments (on the same line) are too close together. Putting a single space between each fragment seems to work pretty well: \(a\) \(long\) \(equation\). The spaces disappear at the line break, which is better than using ~. Any recommendations on this, or experience to report?
Support for breaking an inline equation at reasonable places (given the remaining space available) would be much appreciated, if it's not already there, as would be guidance on handling such things. Maybe something like a \b given at reasonable break points (such as after a + or -) could help. For multiplication, perhaps a \cdot or something could be added at a break (like a hyphen when breaking a word)?