4

The following MWE generates invalid math in HTML using mathjax mode. This only happens when using dmath*. I am using the solution from Error using \ifdefined\HCode with TeX4ht, but it works in LuaTeX and give below all code needed to reproduce this problem using a MWE.

The Latex come from Mathematica conversion:

 sol = DSolve[y'[x] == 2*y[x]/x + x^3/y[x] + x*Tan[y[x]/x^2], y[x], x]
 TeXForm[sol]

Gives

\text{Solve}\left[3 \log (x)-\log \left(y(x) \sin \left(\frac{y(x)}{x^2}\right)+x^2 \cos \left(\frac{y(x)}{x^2}\right)\right)=c_1,y(x)\right]

tex4ht converts the above Latex OK when putting the above inside an equation. But when the Latex is inside dmath it given HTML which is not valid. (can't be rendered by mathjax)

Here is the MWE

\documentclass[12pt]{article}%

\usepackage{amsmath}
\usepackage{breqn}

\begin{document}    

\[
\text{Solve}\left[3 \log (x)-\log \left(y(x) \sin \left(\frac{y(x)}{x^2}\right)+x^2 \cos \left(\frac{y(x)}{x^2}\right)\right)=c_1,y(x)\right]
\]

\begin{dmath*}
\text{Solve}\left[3 \log (x)-\log \left(y(x) \sin \left(\frac{y(x)}{x^2}\right)+x^2 \cos \left(\frac{y(x)}{x^2}\right)\right)=c_1,y(x)\right]
\end{dmath*}

\end{document}

Compiled using

 make4ht  -ulm default -c ./new.cfg -e ./filter.lua -a debug index.tex "mathjax,htm"

Gives

enter image description here

Here is the raw HTML

<!DOCTYPE html> 
<html lang='en-US' xml:lang='en-US'> 
<head> <title></title> 
<meta charset='utf-8' /> 
<meta content='TeX4ht (https://tug.org/tex4ht/)' name='generator' /> 
<meta content='width=device-width,initial-scale=1' name='viewport' /> 
<link href='index.css' rel='stylesheet' type='text/css' /> 
<meta content='index.tex' name='src' /> 
<script>window.MathJax = { tex: { tags: "ams", maxBuffer: 40*1024, packages: {'[+]': ['textmacros']}, environments: { "dgroup*": ["", ""], "dmath*": ["", ""], "dgroup": ["", ""], "dmath": ["", ""] }, macros: { sp: "^", sb: "_", noalign: ["\#1", 1], }, packages: {'[+]': ['noerrors','textmacros']} }, loader: { load: ['[tex]/noerrors','[tex]/textmacros'] } }; </script> 
 <script async='async' id='MathJax-script' src='https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml-full.js' type='text/javascript'></script>  
</head><body>
<!-- l. 11 --><p class='noindent'>\begin {align*}  \text {Solve}\left [3 \log (x)-\log \left (y(x) \sin \left (\frac {y(x)}{x^2}\right )+x^2 \cos \left (\frac {y(x)}{x^2}\right )\right )=c_1,y(x)\right ]  \end {align*}

</p><!-- l. 15 --><p class='noindent'>\begin{align*}  \text {Solve}\left [3 \log (x)-\log \left (y(x) \sin \left (\frac {y(x)}{x^2}\right )+x^2 \cos \left (\frac {y(x)}{x^2}\right )\right )&amp;=c_1,y(x)\right ]  \end{align*}
</p>   
 
</body> 
</html>

By trial and error, I found the problem goes away when removing \left[ and right] ! I also noticed that tex4ht generates &amp; in the raw HTML above near the end of the line, when \left[ and right] are present which might be the cause of the problem (need to check).

YES. Confirmed When removing &amp; from the HTML generated, now mathjax renders it OK.

enter image description here

This happens only when using dmath* environment and not normal equation \[ \] or normal align* environment.

Appendix

Here are the files new.cfg and filter.lua used in the above command

new.cfg

\Preamble{xhtml}
%V3.0
\Configure{MathJaxConfig}{{
  tex: {
    tags: "ams",
    maxBuffer: 40*1024,
    packages: {'[+]': ['textmacros']},
    \detokenize{%
      environments: {
        "dgroup*": ["", ""],
        "dmath*": ["", ""],
        "dgroup": ["", ""],
        "dmath": ["", ""]
      }},
    \unexpanded{%
    macros: {
        sp: "^",
        sb: "_",
      noalign: ["\#1", 1],
    }},
    packages: {'[+]': ['noerrors','textmacros']}
  },
  loader: {
    load: ['[tex]/noerrors','[tex]/textmacros']
  }
};
}

%Thanks to https://tex.stackexchange.com/questions/620104/error-using-ifdefined-hcode-with-tex4ht-but-it-works-in-luatex/620138?noredirect=1#comment1548405_620138
%IMPORTANT. Need also .config folder in my HOME folder for this to work.
\VerbMath{dgroup*}
\VerbMath{dmath*}
\VerbMath{dgroup}
\VerbMath{dmath}


\begin{document}
\EndPreamble

filter.lua

local filter = require "make4ht-filter"

local function process_options(options)
  -- convert [number={foo}] to \tag{foo}
  local number = options:match("number%s*=%s*{?(%w+)")
  if number then
    return "\\tag{" .. number .. "}"
  end
  return ""
end


local function escape_equal(str)
  -- there can be multiple equal characters in the string. we should put the & character
  -- just before the one which is not inside any group
  -- escape nested equal signs
  str = str:gsub("({[^{^}]+)=([^{^}]+})", "%1:EQUAL:%2")
  -- replace remaining =
  str = str:gsub("=", "&=")
  -- return escaped =
  str = str:gsub(":EQUAL:", "=")
  return str
end

local function make_align(dgroup)
  -- change breqn environment contents to align*
  -- change = to &=
  local dgroup = escape_equal(dgroup)
  -- return the fixed text in align* environment
  return "\\begin{align*}" ..  dgroup .. "\\end{align*}"
end

local function process_dgroup(s, env_name)
  return s:gsub("\\begin%s*{" .. env_name .. "}(.-)\\end%s*{" .. env_name .. "}",
  function(dgroup)
    -- remove environemnts
    -- change dmath[...,number={label}] to \tag{label}
    dgroup = dgroup:gsub("\\begin%s*{dmath}%s*(%b[])", process_options)
    -- remove all other environemnts
    dgroup = dgroup:gsub("\\begin%s*{.-}","")
    dgroup = dgroup:gsub("\\end%s*{.-}", "\\\\")
    return make_align(dgroup)
  end)
end

-- process remaining dmath environments
local function process_dmath(s, env_name)
  return s:gsub("\\begin%s*{" .. env_name .. "}(.-)\\end%s*{" .. env_name .. "}",
  function(dmath)
    -- options can be still here
    local dmath = dmath:gsub("^%s*(%b[])", process_options)
    return make_align(dmath)
  end)
end

local process = filter {
  -- find all dgroup* environments and convert them to align*
  function(s)
    local s = process_dgroup(s,"dgroup%*")
    s = process_dgroup(s, "dgroup")
    -- process remaining dmath environments in the document
    s = process_dmath(s, "dmath%*")
    s = process_dmath(s, "dmath")
    return s
  end
}


-- install filter to match HTML files
Make:match("html?$", process)

Using TL 2021 on Linux ubuntu 20.04

1 Answer 1

5

It seems that the issue is that the &= is inside \left[ ... \right]. It seems like a MathJax issue. The & character should be used inside align* for correct alignment of multiline equations, but it doesn't work in this case. Maybe we can just omit it.

Try this version of the build file:

local filter = require "make4ht-filter"

local function process_options(options)
  -- convert [number={foo}] to \tag{foo}
  local number = options:match("number%s*=%s*{?(%w+)")
  if number then
    return "\\tag{" .. number .. "}"
  end
  return ""
end


local function escape_equal(str)
  -- there can be multiple equal characters in the string. we should put the & character
  -- just before the one which is not inside any group
  -- escape nested equal signs
  str = str:gsub("({[^{^}]+)=([^{^}]+})", "%1:EQUAL:%2")
  -- replace remaining =
  str = str:gsub("=", "& =")
  -- return escaped =
  str = str:gsub(":EQUAL:", "=")
  return str
end

local function make_align(dgroup, new_env)
  -- change breqn environment contents to align*
  -- change = to &=
  
  local dgroup = dgroup
  if not new_env then
    dgroup = escape_equal(dgroup) --  <- we don't do this anymore, it leads only to problems
  end
  local new_env = new_env or  "\\begin{align*}\n%s\n\\end{align*}"
  -- return the fixed text in align* environment
  -- return "\\begin{".. new_env .."}" ..  dgroup .. "\\end{" .. new_env .. "}"
  return string.format(new_env, dgroup)
end

local function process_dgroup(s, env_name)
  return s:gsub("\\begin%s*{" .. env_name .. "}(.-)\\end%s*{" .. env_name .. "}",
  function(dgroup)
    -- remove environemnts
    -- change dmath[...,number={label}] to \tag{label}
    dgroup = dgroup:gsub("\\begin%s*{dmath}%s*(%b[])", process_options)
    -- remove all other environemnts
    dgroup = dgroup:gsub("\\begin%s*{.-}","")
    dgroup = dgroup:gsub("\\end%s*{.-}", "\\\\")
    return make_align(dgroup)
  end)
end

-- process remaining dmath environments
local function process_dmath(s, env_name, new_env)
  return s:gsub("\\begin%s*{" .. env_name .. "}(.-)\\end%s*{" .. env_name .. "}",
  function(dmath)
    -- options can be still here
    local dmath = dmath:gsub("^%s*(%b[])", process_options)
    return make_align(dmath, new_env)
  end)
end


local process = filter {
  -- find all dgroup* environments and convert them to align*
  function(s)
    local s = process_dgroup(s,"dgroup%*")
    s = process_dgroup(s, "dgroup")
    -- process remaining dmath environments in the document
    s = process_dmath(s, "dmath%*", "\\[\n%s\n\\]")
    s = process_dmath(s, "dmath", "\\begin{equation}\n%s\n \\end{equation}")
    return s
  end
}

-- install filter to match HTML files
Make:match("html?$", process)

The change is that it now don't convert everything to the align* environment, but it follows breqn, so dmath -> equation, and dmath* -> \[ ... \]. It also doesn't escape the equals sign.

This is a resulting HTML:

<!-- l. 10 --><p class='noindent'>\[ \text {Solve}\left [3 \log (x)-\log \left (y(x) \sin \left (\frac {y(x)}{x^2}\right )+x^2 \cos \left (\frac {y(x)}{x^2}\right )\right )=c_1,y(x)\right ] \]
</p><!-- l. 14 --><p class='indent'>   \[
  \text {Solve}\left [3 \log (x)-\log \left (y(x) \sin \left (\frac {y(x)}{x^2}\right )+x^2 \cos \left (\frac {y(x)}{x^2}\right )\right )=c_1,y(x)\right ]  
\]
</p>   

And rendered by MathJax:

enter image description here

22
  • 1
    It is not a MathJax issue; the LaTeX is incorrect. An ampersand in that position leads to an error in LaTeX as well, since you can't use an ampersand for the outer align environment inside the \left...\right, as the \left...\right act as grouping braces, and the ampersand can't be inside a group. So it seems to be the tex4ht conversion that is at fault. Commented Apr 6, 2022 at 20:00
  • Thanks Michale. I have to test your new version on my large file which has thousands of cases to see if it works OK and does not break anything. I will let you know. On the ampersand issue. Mathematica does not generate one from its Latex conversion as can be seen from above. That ampersand seems to have come from TeX4ht itself somehow.
    – Nasser
    Commented Apr 6, 2022 at 20:09
  • @DavideCervone thanks for clarification. I've added amperesands in the Lua filter, because I thought that they are useful for the alignment. But they do more harm than good, so I removed them from the updated filter in my answer.
    – michal.h21
    Commented Apr 6, 2022 at 21:20
  • 1
    @Nasser the printing of the code was for debuggging, I've removed it from the updated answer.
    – michal.h21
    Commented Apr 7, 2022 at 8:13
  • 1
    @Nasser I think it works now, at least for your example. try the updated code from this answer.
    – michal.h21
    Commented Sep 5, 2023 at 7:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .