3

This is tex4ht specific issue only.

This MWE

\documentclass[11pt]{article}
\usepackage{amsmath}
\begin{document}

$ 2\ x\ {\arcsin x} $

\end{document}

is valid latex. It compiles using lualatex to

Mathematica graphics

But when compiled to HTML using mathjax mode

  make4ht -ulm default  foo.tex "htm,mathjax"

The generated latex losses the important white space between x\ { and it becomes x\{. Here is the raw HTML

<!DOCTYPE html> 
<html lang="en-US" xml:lang="en-US" > 
<head><title></title> 
<meta  charset="utf-8" /> 
<meta name="generator" content="TeX4ht (http://www.tug.org/tex4ht/)" /> 
<meta name="viewport" content="width=device-width,initial-scale=1" /> 
<link rel="stylesheet" type="text/css" href="foo.css" /> 
<meta name="src" content="foo.tex" /> 
 <script type="text/x-mathjax-config"> MathJax.Hub.Config({ 'fast-preview': {disabled: true}, TeX: { extensions: ["color.js","AMSmath.js"], equationNumbers: { autoNumber: "AMS" } }, extensions: ["tex2jax.js"], tex2jax: {  inlineMath: [ ["\\\(","\\\)"] ], displayMath: [ ['$$','$$'], ["\\[","\\]"] ], processEscapes: true, processEnvironments: true } }); </script> 
 <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>  
</head><body 
>
<!--l. 6--><p class="noindent" >\( 2\ x\{\arcsin x} \)
</p>   

</body> 
</html>

And because of this mathjax fail to render it.

Mathematica graphics

Manually editing the HTML above and adding the extra white space that was in source, now it works.

 <!--l. 6--><p class="noindent" >\( 2\ x\ {\arcsin x} \)

Mathematica graphics

And before someone complains that one should use something like x\, { and not just x\ {, this code was auto generated by computer algebra program. I did not write it myself.

Using TL 2019 on Linux

2
  • 1
    bug reports are best reported the maintainers rather than just hoping that the maintainers notice it here, While the space shouldn't be dropped it is very unusual input \ is a text space and shouldn't be used in math and the {..} around the subterm also loses all tex's math spacing, making it a \mathord and freezing all internal white space. Apr 20 '20 at 7:05
  • saying the expression is generated by a computer algebra program isn't really a good reason. You are responsible for passing it to latex, so you could improve it with some basic edits such as removing \ before processing. Apr 20 '20 at 7:08
4

This is caused by a workaround that TeX4ht uses to keep the LaTeX math mode code in the HTML. It uses the following code defined in mathjax-latex-4ht.4ht:

\ExplSyntaxOn
\cs_new_protected:Npn \alteqtoks #1
{
  \tl_set:Nx \l_tmpa_tl {\detokenize{#1}}
  % delete spaces before left brackets
  \regex_replace_all:nnN { \x{20} \x{7B} } { \x{7B} } \l_tmpa_tl
  % replace < > and & with xml entities
  \regex_replace_all:nnN { \x{26} } { &amp; } \l_tmpa_tl
  \regex_replace_all:nnN { \x{3C} } { &lt; } \l_tmpa_tl
  \regex_replace_all:nnN { \x{3E} } { &gt; } \l_tmpa_tl
  \tl_set:Nx \l_tmpb_tl{ \l_tmpa_tl }
  \HCode{\l_tmpb_tl}
}
\ExplSyntaxOff

It uses the \detokenize command to keep the code from expansion and saves it in a token list. It then uses LaTeX 3 regular expressions to fix some issues. The relevant one is this:

  % delete spaces before left brackets
  \regex_replace_all:nnN { \x{20} \x{7B} } { \x{7B} } \l_tmpa_tl

The issue that \detokenize command inserts spaces after commands, so for example \sqrt{a} is converted as \sqrt {a}. In some cases MathJax failed to display such code. So this is the reason why we use it. In your case, you have \ {, which also catches this regular expression.

To fix that, we can introduce another regexp to convert \ { to some other space command, for example \::

\regex_replace_all:nnN { \x{5C} \x{20} \x{7B} } { \x{5C} \x{3A} \x{7B} } \l_tmpa_tl

The \x{code} commands contains hexadecimal codes for characters that we want to match, so \x{5C} \x{20} \x{7B} means \ {.

The changed function looks like this:

\ExplSyntaxOn
\cs_new_protected:Npn \alteqtoks #1
{
  \tl_set:Nx \l_tmpa_tl {\detokenize{#1}}
  % delete spaces before left brackets
  \regex_replace_all:nnN { \x{5C} \x{20} \x{7B} } { \x{5C} \x{3A} \x{7B} } \l_tmpa_tl
  \regex_replace_all:nnN { \x{20} \x{7B} } { \x{7B} } \l_tmpa_tl
  % replace < > and & with xml entities
  \regex_replace_all:nnN { \x{26} } { &amp; } \l_tmpa_tl
  \regex_replace_all:nnN { \x{3C} } { &lt; } \l_tmpa_tl
  \regex_replace_all:nnN { \x{3E} } { &gt; } \l_tmpa_tl
  \tl_set:Nx \l_tmpb_tl{ \l_tmpa_tl }
  \HCode{\l_tmpb_tl}
}
\ExplSyntaxOff

The resulting HTML:

<p class='noindent'>\( 2\ x\:{\arcsin x} \)
</p>

Rendered by MathJax:

enter image description here

5
  • Could you please mention which file this change needs to go into, so I can change it on my computer so I can use it? Since source code is now frozen, I can't update sources. This will be something temporary until new version of TL comes up. When I added your code to my .cfg I get error about control sequence \alteqtosk already defined. Thanks
    – Nasser
    Apr 20 '20 at 21:05
  • @Nasser sure it is defined in mathjax-latex-4ht.4ht. TL 2020 is available for install already, BTW :)
    – michal.h21
    Apr 20 '20 at 21:51
  • oh, I had no idea TL 2020 is ready with your fixes! I was trying to do update for TL 2019 and it said it is frozen until new release is out or such. Ok, will go ahead now and try to install TL 2020 that will be easier. Thanks
    – Nasser
    Apr 20 '20 at 21:56
  • @michal.h21 I noticed that texlive 2021 mathjax-latex-4ht.4ht no longer removes spaces before { Is there a reason for this? I'm happy to open a new question, if that's helpful
    – cmhughes
    Oct 18 at 13:29
  • @cmhughes I think that the reason was that sometimes it failed? I don't remember it exactly. But MathJax seems to work correctly even with spaces, so I guess that I felt that it is not necessary anymore.
    – michal.h21
    Oct 18 at 13:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.