在 TeX4ht 中使用 \ifdefined\HCode 时出错,但在 LuaTeX 中可以正常工作

在 TeX4ht 中使用 \ifdefined\HCode 时出错,但在 LuaTeX 中可以正常工作

我现在breqn只在 LuaTeX 模式下使用该包。不在 TeX4ht 模式下使用,因为它在那里不起作用并且不需要。因此,我只在非 TeX4ht 模式下加载 breqn,并\ifdefined\HCode确保它仅在编译为 PDF 而不是 HTML 时使用。

我发现一些问题,TeX4ht 仍然可以看到{dmath*}dgroup来自的命令breqn,尽管我确保\ifdefined\HCode只有在编译为 PDF 时才能看到这些命令。

编译为 PDF 完全没有显示任何错误。但编译为 HTML 会出现错误。

以下是 MWE:

\documentclass[12pt]{book}
\usepackage{amsmath}
\ifdefined\HCode %only load breaqn when not in TeX4ht mode
\else
\usepackage{breqn}
\fi

\begin{document}
\ifdefined\HCode
\begin{align*}
\else
\begin{dgroup*}
\fi

\ifdefined\HCode
   A &= B
\else
\begin{dmath*}
   A = B
\end{dmath*}     %error is around here
\fi

\ifdefined\HCode
\end{align*}
\else
\end{dgroup*}
\fi
\end{document}

使用编译lualatex foo2.tex不会产生任何错误和正确的输出。

make4ht -ulm default -a debug foo2.tex "mathjax,htm"

给出

(/usr/local/texlive/2021/texmf-dist/tex/generic/tex4ht/html5.4ht)) (./foo2.aux)
(/usr/local/texlive/2021/texmf-dist/tex/latex/base/ts1cmr.fd)

! LaTeX Error: Environment dgroup* undefined.

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...

l.31 \end{dmath*}

我不得不这样做。说来话长,但我的问题是:为什么上面的代码在 LuaTeX 上可以正常工作,但在 TeX4ht 上却不行?我做错了什么吗?如果是,那么为什么 LuaTeX 可以正常工作,而 TeX4ht 却不行?有没有办法让 tex4ht 编译上面的代码?

我在用TeX 直播(TL) 2021,大约两周前更新。在 Linux 上。

2021 年 10 月 25 日更新

我发现建议的解决方案存在一个问题。它不适用于多个dmath*内部dgroup*。它只适用于一个dmath*内部dgroup*。但如果我有一个dmath*,我真的不需要dgroup*

由于很难在答案的评论中展示所有这些内容,因此我在这里展示。

这是 MWE

\documentclass[12pt]{book}    
\usepackage{amsmath} 
\usepackage{breqn}
\begin{document}    

\begin{dgroup*}
\begin{dmath*}
   A = B
\end{dmath*}      
\begin{dmath*}
   C = D
\end{dmath*}    
\end{dgroup*}
\end{document}

使用答案中显示的相同 .cfg 文件,并使用进行编译

make4ht -ulm default -a debug -c ./new.cfg test_breqn.tex "mathjax,htm"

给出这个 HTML

在此处输入图片描述

第二个dmath*需要另起一行。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='test_breqn.css' rel='stylesheet' type='text/css' /> 
<meta content='test_breqn.tex' name='src' /> 
<script>window.MathJax = { tex: { tags: "ams", environments: { "dgroup*": ["", ""], "dmath*": ["", ""], }  } }</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. 13 --><p class='noindent'>\begin {dgroup*} \begin {dmath*} A = B \end {dmath*} \begin {dmath*} C = D \end {dmath*} \end {dgroup*}
</p>   
 
</body> 
</html>

这是 PDF 版本:

在此处输入图片描述

我希望有办法解决这个问题。

答案1

编辑:

您还可以使用make4ht过滤器编辑 HTML 文件中的数学内容以获取 MathJax 支持的内容。例如,以下构建文件将dgroup*环境转换为align*,并且还将数学内容更改为合适的形式:

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)

它生成以下 HTML 代码:

<p class='noindent'>test 1, OK
</p><!-- l. 15 --><p class='indent'>   \begin{align*}  A &amp;= B \\  C &amp;= D \\ \end{align*}
</p><!-- l. 17 --><p class='indent'>   test 2 FAIL
</p><!-- l. 26 --><p class='indent'>   \begin{align*}  A &amp;= B \\ \tag{1} C &amp;= D \\ \end{align*}
</p><!-- l. 29 --><p class='indent'>   test 3 OK
</p><!-- l. 33 --><p class='indent'>   \begin{align*} A &amp;= B \end{align*}
</p><!-- l. 35 --><p class='indent'>   test 4 FAIL
</p><!-- l. 39 --><p class='indent'>   \begin{align*}\tag{1} A &amp;= B \end{align*}
</p><!-- l. 41 --><p class='indent'>   test 5 OK
</p><!-- l. 45 --><p class='indent'>   \begin{align*} A &amp;= B \end{align*}
</p>

MathJax 显示如下:

在此处输入图片描述

原始答案:

或者,您可以使用此配置文件向 MathJax 添加对数学环境的支持:

\Preamble{xhtml} 
\Configure{MathJaxConfig}{{ 
    tex: { 
      tags: "ams", 
      \detokenize{% 
      environments: {
        "dgroup*": ["", ""],
        "dmath*": ["", ""],
      } 
  } 
} 
}} 
\VerbMath{dgroup*}
\begin{document} 
\EndPreamble

\VerbMath{dgroup*}命令确保 TeX4ht 将dgroup*环境的全部内容传递到 HTML 文件。然后您需要配置 MathJax 以支持dgroup*dmath*环境。这要归功于:

  environments: {
    "dgroup*": ["", ""],
    "dmath*": ["", ""],
  } 

我发现您不需要提供任何其他代码,MathJax 只需切换到显示数学模式并打印内容。

你的 TeX 文件可以简化:

\documentclass[12pt]{book}    
\usepackage{amsmath} 
\usepackage{breqn}

\begin{document}    
\begin{dgroup*}
\begin{dmath*}
   A = B
\end{dmath*}     %error is around here           
\end{dgroup*}
\end{document}

结果如下:

在此处输入图片描述

答案2

如果\Hcode已定义,\begin{align*}则将执行,并且作为第一个操作,它将抓取到的所有代码\end{align*}。此主体将执行多次,一次是测量过程,然后是主排版过程。收集的主体将是

\else
\begin{dgroup*}
\fi

\ifdefined\HCode
   A &= B
\else
\begin{dmath*}
   A = B
\end{dmath*}     %error is around here           
\fi

\ifdefined\HCode

并且if条件将不匹配。您需要条件围绕整个环境。

相关内容