Tex4ht 在 mathjax 模式下使用 dmath 时生成无效数学运算

Tex4ht 在 mathjax 模式下使用 dmath 时生成无效数学运算

以下 MWE 使用 mathjax 模式在 HTML 中生成无效数学。这仅在使用时发生dmath*。我正在使用来自的解决方案在 TeX4ht 中使用 \ifdefined\HCode 时出错,但在 LuaTeX 中可以正常工作 并在下面提供使用 MWE 重现此问题所需的所有代码。

Latex 来自 Mathematica 转换:

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

给予

\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将上述内容放入方程式中时,转换上述 Latex 成功。但当 Latex 在其中时,dmath给出的 HTML 无效。(无法通过 mathjax 呈现)

这是 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}

使用编译

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

给予

在此处输入图片描述

以下是原始 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>

通过反复试验,我发现删除\left[和后问题就消失了!我还注意到,当和存在right]时,tex4ht 会&amp;在上面的原始 HTML 行尾附近生成,这可能是问题的原因(\left[right]需要检查)。

是的。已确认&amp;当从生成的 HTML 中 删除时,mathjax 现在可以将其呈现为 OK。

在此处输入图片描述

这种情况仅在使用dmath*环境而不是正常方程\[ \]或正常align*环境时发生。

附录

以下是上述命令中使用new.cfg的文件filter.lua

新建配置文件

\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

过滤器.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)

在 Linux ubuntu 20.04 上使用 TL 2021

答案1

问题似乎在于 位于&=... 内\left[\right]这似乎是 MathJax 的问题。&字符应该用在内,align*以便正确对齐多行方程,但在这种情况下不起作用。也许我们可以省略它。

尝试这个版本的文件build

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)

变化是它现在不会将所有内容转换为环境align*,但它遵循breqn,所以dmath-> equation,和dmath*-> \[ ... \]。它也不会转义等号。

这是生成的 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>   

并由 MathJax 渲染:

在此处输入图片描述

相关内容