MobileRead Forums

MobileRead Forums (https://www.mobileread.com/forums/index.php)
-   Sigil (https://www.mobileread.com/forums/forumdisplay.php?f=203)
-   -   How to use MathML/MathJax (https://www.mobileread.com/forums/showthread.php?t=338460)

snarkophilus 03-31-2021 09:12 AM

How to use MathML/MathJax
 
Hi folks,

How do I get Sigil to render MathML/MathJax the the preview window? I've only just discovered MathML and wanted to have a bit of a tinker.

I've got two sample epubs, one from the Calibre documentation and a linear algebra epub from this EPUB 3 samples page, neither of which render anything math like in the preview window.

I've also tried creating a new epub3 and putting this following snippet in the body (this from Accessible Publishing Knowledge Base MathML page):
Code:

<math xmlns="http://www.w3.org/1998/Math/MathML"
      alttext="Frac Root a EndRoot Over b EndFrac">
  <mfrac>
      <msqrt>
        <mtext>a</mtext>
      </msqrt>
      <mi>b</mi>
  </mfrac>
</math>

Both epubs and the above snippet in a new epub work with the calibre epub editor.

I've tried ticking the two boxes ("epubs may access remote resources" and "epubs may use javascript") in the General Settings / Security prefs but no change to preview rendering. I've seen references to MathML in the Sigil forums (eg here and here and this thread), so I figure I must be missing something simple. There's no mention of "math" in the Sigil User's Guide.

This is with Sigil 1.5.1 on Windows 10.

DiapDealer 03-31-2021 10:01 AM

Looks like we broke something. It's not working like it should with 1.4.3, either. At least on Windows. Looks like the url for the mathjax javscript file is being blocked. Shoot. Sorry about that. I'll see if I can figure out what version of Sigil it last worked with. We'll get it fixed for the next release, but that may be a bit.

snarkophilus 03-31-2021 10:22 AM

Good to know I'm not going (totally) crazy! I upgraded from 1.4.3 to 1.5.1 before posting too because I couldn't get it working there either.

If you can post in this thread when it's fixed, I'll pick up one of the CI builds (if I can recall where they live :)).

KevinH 03-31-2021 11:30 AM

1 Attachment(s)
FWIW, this must be a Windows issue.

It works just fine on macOS with 1.3.0, 1.4.3, and 1.5.1.

Has anyone tried Linux?

See my screenshot.

DiapDealer 03-31-2021 11:41 AM

Yeah... it's broken on Linux in 1.5.x, too.

KevinH 03-31-2021 11:53 AM

The exact same approach is used to inject user css into preview? Is that broken on Windows and Linux too?

Try his simple example, and the fire up Preview's Inspector and check to make sure the injected mathjax javascript file url is correct in head.

If it is, then the issue must be in URLInterceptor as it explicitly allows file calls inside of the mathjax folder. The MainWindow determines both the maxjaxurl which it passes to Preview and the enclosing mathjax folder which URLInterceptor takes from the MainWindow via a GetMathjaxFolder call defined in MainWindow.h.

Something there must be broken.

DiapDealer 03-31-2021 12:03 PM

The injected url is correct. It's percent-encoded, but it always has been, and a quick browser test ensures that the percent-encoded file url can be located/loaded.

I'll do some more testing.

DiapDealer 03-31-2021 12:39 PM

I've got to go back to Sigil 1.2.0 for it to work on Windows!?

The issue on Linux is completely different. The MathJax failure is directly tied to me defining a custom temp folder for Sigil. Once I change that back to the automatic default location, MathJax works again in Sigil 1.5.1 on Linux. I'm hoping that can be corrected some time, but it's not a big deal.

From what I can see, the url is fine on Windows, too. It's the exact same url as the one used in Sigil 1.2.0 when MathJax was working on Windows. GetMathJaxFolder is identifying the correct folder as well.

KevinH 03-31-2021 12:43 PM

Hmm, perhaps enable debug in URLInterceptor so we can see what is going on. I am betting some strange drive letter or initial path / nonsense.

KevinH 03-31-2021 12:46 PM

If it is not being blocked, then the issue might be in the URLSchemeHandler loading the resource from the file url. Again perhaps there is an error in converting that file url back to a functioning local file path that can be opened and read from.

DiapDealer 03-31-2021 12:48 PM

Well the drive letter after the colon is being percent-encoded (file:///C:/) when viewed in inspector, but it always was, even back when mathjax was working.

DiapDealer 03-31-2021 12:50 PM

It's definitely being blocked on Windows.

Code:

Failed to load resource: net::ERR_BLOCKED_BY_CLIENT
For MathJax.js

KevinH 03-31-2021 01:00 PM

Have you by any chance disabled client javascripts in Sigil's Preferences?

Under Sigil Preferences -> General Settings - > Security:

Control Use of Javascript by Epubs

check Epubs may use javascript.

Then restart Sigil so the new MainWindow will get that new setting. The current one has already opened and its setting is the old one.

If I uncheck that and open a new Window (macOS allows that without restarting), then try the example, all I get is "a b". If I enable it (and mathjax is javascript) and then open a new window and try the example it works.

KevinH 03-31-2021 01:10 PM

If it was being blocked by our URLInterceptor you would see the following in qDebug:

Code:

        // otherwise block it to prevent access to any outside Sigil user file path
        info.block(true);
        qDebug() << "Warning: URLInterceptor blocking access to url " << destination;
        qDebug() << "    from " << info.firstPartyUrl();
        return;

So if you are not seeing that Warning then QtWebEngine itself is blocking that url not anything we are doing. My guess is missing a restart after changing that setting is the issue.

KevinH 03-31-2021 01:11 PM

If that turns out to be the case, we should make Sigil restart after playing with the "may use javascripts" setting at least on Windows and Linux. On macOS, no restart is needed because we can just open a new Window and it will have javascript enabled.

DiapDealer 03-31-2021 01:12 PM

No. Client Javascripts have been enabled all along. It's definitely the URLInterceptor:

Code:

Debug: Warning: URLInterceptor blocking access to url  QUrl("file:///C%3A/Program Files/Sigil/polyfills/MJ/MathJax.js?config=local/SIGIL_EBOOK_MML_SVG")
The only thing I can think of is that we may have to find a way to keep the colon after the drive-letter from being percent-encoded on Windows. I'll try to quickly brute that change and see if it makes a difference.

KevinH 03-31-2021 01:17 PM

I am sure it is drive letter related but it should not be % url encoding related
as that is converted to a local file path before comparison.

So in URLInterceptor.cpp, the the following code snippet:

Code:

        QString destpath = destination.toLocalFile();

      ...

        // or the path must be inside the Sigil's MathJax folder                                                               
        if (destpath.startsWith(mathjaxfolder)) {
            info.block(false);
            return;
        }

Immediately after this snippet but before it reaches the debug warning that it will be blocked, it might be useful to add the following:

qDebug() << destpath;
qDebug() << mathjaxfolder;

I am guessing there is some drive letter case or leading / difference going on.

KevinH 03-31-2021 01:25 PM

Do you want me to push that change and then add [deploy] for you to test with?

DiapDealer 03-31-2021 01:28 PM

Actually, I think it may be the way the mathjax folder/url is being concatenated on Windows

Debug: mathjax: "/C:/Program Files/Sigil/polyfills/MJ/"
Debug: usercss: "C:/Users/Doug/AppData/Local/sigil-ebook/sigil/"

Both are resulting in technically correct urls for the user css file and the mathjax javascript file when all is said and done, but in the case of the mathjax folder: if the URLInterceptor is being told to specifically allow file calls from inside the "/C:/Program Files/Sigil/polyfills/MJ/" folder then that's why it's failing. No such folder exists (that starts with a forward slash).

We either build the mathjax folder/url differently for Windows, or we special-case the starts-with section of the URLInterceptor's mathjax exemption on Windows to strip the leading slash

KevinH 03-31-2021 01:31 PM

So the path to the mathjaxfolder is built in MainWindow.cpp Perhaps the bug is there. The mathjax folder should not have a leading "/" in it, right.

From MainWindow.cpp:

Code:

#ifdef Q_OS_MAC
    // On Mac OS X QCoreApplication::applicationDirPath() points to Sigil.app/Contents/MacOS/                                 
    QDir execdir(QCoreApplication::applicationDirPath());
    execdir.cdUp();
    mathjaxurl = execdir.absolutePath() + "/polyfills/MJ/";
#elif defined(Q_OS_WIN32)
    mathjaxurl = "/" + QCoreApplication::applicationDirPath() + "/polyfills/MJ/";
#else

On MacOS it is built as an absolute path.

On Windows I am not so sure. What does QCoreApplicationDirPath() return?

But then later on we need to build a file url from it and we do it manually.

Maybe that is why the "/" is prepended?

Code:

    m_mathjaxfolder = mathjaxurl;
    mathjaxurl = mathjaxurl + "MathJax.js";
    mathjaxurl = "file://" + Utility::URLEncodePath(mathjaxurl);
    mathjaxurl = mathjaxurl + "?config=local/SIGIL_EBOOK_MML_SVG";

Perhaps we should use QUrl::fromLocalFile() here instead of building the url manually?

KevinH 03-31-2021 01:40 PM

So we could remove the addition of the leading "/" for Windows in the first snippet:

Code:

#ifdef Q_OS_MAC
    // On Mac OS X QCoreApplication::applicationDirPath() points to Sigil.app/Contents/MacOS/                                 
    QDir execdir(QCoreApplication::applicationDirPath());
    execdir.cdUp();
    mathjaxurl = execdir.absolutePath() + "/polyfills/MJ/";
#elif defined(Q_OS_WIN32)
    mathjaxurl = QCoreApplication::applicationDirPath() + "/polyfills/MJ/";
#else

and then change the second snippet to:

Code:

    m_mathjaxfolder = mathjaxurl;
    mathjaxurl = mathjaxurl + "MathJax.js";
    mathjaxurl = QUrl::fromLocalFile(mathjaxurl).toString();
    mathjaxurl = mathjaxurl + "?config=local/SIGIL_EBOOK_MML_SVG";

Or something close. That should work on all platforms, right?

DiapDealer 03-31-2021 01:50 PM

I think should, yes. Let me give it a whirl on Windows and Linux and I'll get back to you.

QCoreApplicationDirPath() returns the folder where the Sigil exe is, by the way. That's also where the poyfill folder is located as well.

KevinH 03-31-2021 01:52 PM

Just tried it and it works fine on MacOS.

DiapDealer 03-31-2021 02:18 PM

It fixed things on Windows and continued to work without issue on Linux! Seem a lot cleaner method too.

I'm consistently getting a few errors in inspector related to MathJax on Windows and Linux, though. Are you seeing anything about missing MathMenu.js files and MathZoom.js files? MathJax seems to be looking for them in polyfills/MJ/extensions. The files are definitely not there, I'm just wondering what's looking for them (and if they should be there).

KevinH 03-31-2021 02:25 PM

The MathMenu can not be used was was intentionally removed as it allowed the user to change MathJax settings and it can not be interacted with as Preview is not a Browser.

MathZoom is an accessibility features but Prefix's Zoom takes precedence and so it is unneeded as well. MathJax will dynamically load only those extensions that are present.

So we should be good to go.

KevinH 03-31-2021 02:27 PM

Can you push push that MainWindows Mathjax fix with [deploy] or do you want me to do it?

DiapDealer 03-31-2021 02:44 PM

I'll take care of it.

I know you've already pushed some bigger changes beyond 1.5.1, so I won't be able to use CI to deploy something on the order of a 1.5.2, but that's fine. This has been broken on Windows since July of last year and this is the first report we've gotten on it! So I don't think there's a huge need. We can definitely hold off until Sigil 1.6.

I'll make a patch for the 1.5.1 source for anyone who wants to roll their own, and can make an installer available for @snarkophilus and the few others who might not want to live without the fix. :)

This one's on me. I clearly only tested MathJax functionality on my main Linux machine since version 1.2.0, and didn't look any further when it appeared to work. :o

Also, I can't seem to recreate the issue I was having on Linux where setting a custom Sigil temp folder was breaking MathJax functionality in 1.5.1. Perhaps I just missed a restart after changing the enable javascript setting :blink:

KevinH 03-31-2021 03:11 PM

Sounds good.

snarkophilus 03-31-2021 08:00 PM

Thanks guys for your busy work while I was asleep :)

DiapDealer 04-01-2021 12:07 PM

Quote:

Originally Posted by snarkophilus (Post 4108163)
Thanks guys for your busy work while I was asleep :)

No problem.

It was such a simple change that I replaced the Windows installer packages in the github Sigil 1.5.1 release. Feel free to redownload the installer (don't forget to verify the checksums) and verify that it solves the problem for you.

I included a note and the patch for 1.5.1 in the documentation of the release, as well.

snarkophilus 04-02-2021 03:17 AM

Thanks Diap!

That works for the linear equation epub and the snippet of mathml code, but it doesn't render the example epub from the Calibre documentation.

Both the code snippet and the linear algrabra book in my first post in this thread use "inline" <math xmlns="http://www.w3.org/1998/Math/MathML"> XML for each math equation but the Calibre doco example uses a <script type="text/x-mathjax-config"> phrase in the <head> section to declare it's mathml and then just a bare \[,\] or \(,\) pair in the text to bracket a maths expression. I added the following line (from a random mathml sample I found on the web) to the <head> section and then it did render:

Code:

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
Is that a problem with the sample EPUB or a Sigil problem?

One minor nit: In the "about" popup, it still says Build time: 2021.03.25 14:50:59 UTC. I assume a resource wasn't updated when you uploaded the replacement 1.5.1 build? No biggie, but it was harder to make sure I'd installed the updated 1.5.1 even after I'd verified the new checksum :).

DiapDealer 04-02-2021 06:26 AM

Yeah, you're probably not going to be able to include your own MathJax script (local or remote) with its own config. Sigil's Preview automatically injects the script tags with its own version of MathJax (and its own local config) behind the scenes whenever MathMl tags are encountered.

The build-time is definitely my fault. Since only two lines of one file were changed, I didn't do a full compile from scratch. It probably should have occurred to me that that might happen, but it didn't.

BeckyEbook 04-02-2021 06:45 AM

Quote:

Originally Posted by DiapDealer (Post 4108578)
The build-time is definitely my fault. Since only two lines of one file were changed, I didn't do a full compile from scratch. It probably should have occurred to me that that might happen, but it didn't.


Tip:
I like to see the correct compilation date, so in the build batch, I added an extra line, which by removing the compiled file from "About" forces inserting the current date and time.

Code:

if exist W:\Develop\Sigil\Sigil-master\src\CMakeFiles\Sigil.dir\Dialogs\About.cpp.obj del /Q W:\Develop\Sigil\Sigil-master\src\CMakeFiles\Sigil.dir\Dialogs\About.cpp.obj

DiapDealer 04-02-2021 07:05 AM

Quote:

Originally Posted by BeckyEbook (Post 4108582)
Tip:
I like to see the correct compilation date, so in the build batch, I added an extra line, which by removing the compiled file from "About" forces inserting the current date and time.

Code:

if exist W:\Develop\Sigil\Sigil-master\src\CMakeFiles\Sigil.dir\Dialogs\About.cpp.obj del /Q W:\Develop\Sigil\Sigil-master\src\CMakeFiles\Sigil.dir\Dialogs\About.cpp.obj

What build batch?

This is never a problem under "normal" circumstances. Sigil releases are done with a full, fresh compile of all files starting with an empty build directory. As are all CI builds. This was just a one-off mistake I made looking to save some time.

BeckyEbook 04-02-2021 07:17 AM

I thought you did the build on the local computer for some batch to do it faster, I use one myself (cmake with parameters + ninja -j4).

DiapDealer 04-02-2021 07:52 AM

No. Locally I do it manually. Well, as "manually" as a 3 command process can be, anyway ;)

Too much automation gets me in just as much trouble as not enough. Makes me forget how to fix things when inevitable changes and other disruptions out of my control breaks something. The build environment is automated (paths, qt, python, visual studio, etc), but that's about it.

I've got 50 or so different cmake configurations I experiment with locally. But building Sigil still boils down to 3 commands for me:

cmake (the correct config string pasted in from the file of 50 or so)
ninja
ninja makeinstaller

That's as automated as I'm willing to get and still stay on my toes. I've got the CI deployment if I need fully automated builds for quick testing (and they're always from scratch). But I don't use those builds for official releases. I can't trust that something hasn't crept into their build environments while I wasn't looking.

snarkophilus 04-02-2021 08:27 AM

Quote:

Originally Posted by DiapDealer (Post 4108578)
Yeah, you're probably not going to be able to include your own MathJax script (local or remote) with its own config. Sigil's Preview automatically injects the script tags with its own version of MathJax (and its own local config) behind the scenes whenever MathMl tags are encountered.

I'm happy to include the builtin MathJax somehow!

Is there a way we can key off 'text/x-mathjax-config' as well as the existance of a <math> tag to enable MathML? This seems to be the difference in what Sigil does compared with what Calibre editor does to detect math. Surely this isn't as simple as adding something like '<script\\s+type="text/x-mathjax-config"' to the regex that's looking for the math tags?

snarkophilus 04-02-2021 09:04 AM

A bit of a play around (whilst admitting I don't really know what I'm doing) seems to indicate something more is needed than just detecting 'script type="text/x-mathjax-config"'.

Inspecting the preview window with a <math ...> line and grabbed the inserted MathJax script and added that to a "simple" file, but it doesn't render:

Spoiler:
Code:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <script type="text/x-mathjax-config"></script>
  <script type="text/javascript" async="async" src="file:///C:/Program Files/Sigil/polyfills/MJ/MathJax.js?config=local/SIGIL_EBOOK_MML_SVG"></script>
</head>
<body>
<p>
\(\frac{\sqrt{a}}{b}\)
</p>
</body>
</html>



Using the random google-found script line I mentioned earlier does render:

Spoiler:
Code:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <script type="text/x-mathjax-config"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</head>
<body>
<p>
\(\frac{\sqrt{a}}{b}\)
</p>
</body>
</html>



I'm hoping(!) that I can get this simple sample to render:
Spoiler:
Code:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <script type="text/x-mathjax-config"></script>
</head>
<body>
<p>
\(\frac{\sqrt{a}}{b}\)
</p>
</body>
</html>


Doitsu 04-02-2021 10:06 AM

1 Attachment(s)
Since JavaScript isn't supported in epub2 books, I converted it to an epub3 book and I also embedded the MathJax JavaScript library.
It displays more or less fine in Sigil, Azardi and Apple Books, but not in Adobe Digital Editions 4.5.x.
OTOH, ADE displays the old IDPF test file fine. (So does Sigil 1.5.1.)

DiapDealer 04-02-2021 10:35 AM

Yes. The basic inline <math></math> stuff is the only thing that's going to stand a chance of working in an epub2 in Sigil. And it's probably not even technically spec. Epub3 is necessary for your sample epub (to comply with spec and work with Sigil).

The MathML section of the IDPF EPUB3 test epub is what we used when implementing the support in Sigil. The only places Sigil falls down in their tests (at least on Windows) is the optional "CSS Styling test (mathml-021)" and the required "BiDi, RTL and Arabic alphabets test (mathml-070)".

I think at least one of those was a Windows-only failure.


All times are GMT -4. The time now is 10:54 PM.

Powered by: vBulletin
Copyright ©2000 - 3.8.5, Jelsoft Enterprises Ltd.
MobileRead.com is a privately owned, operated and funded community.