![在 TeX4ht 中使用 \ifdefined\HCode 时出错,但在 LuaTeX 中可以正常工作](https://linux22.com/image/441195/%E5%9C%A8%20TeX4ht%20%E4%B8%AD%E4%BD%BF%E7%94%A8%20%5Cifdefined%5CHCode%20%E6%97%B6%E5%87%BA%E9%94%99%EF%BC%8C%E4%BD%86%E5%9C%A8%20LuaTeX%20%E4%B8%AD%E5%8F%AF%E4%BB%A5%E6%AD%A3%E5%B8%B8%E5%B7%A5%E4%BD%9C.png)
我现在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 &= B \\ C &= D \\ \end{align*}
</p><!-- l. 17 --><p class='indent'> test 2 FAIL
</p><!-- l. 26 --><p class='indent'> \begin{align*} A &= B \\ \tag{1} C &= D \\ \end{align*}
</p><!-- l. 29 --><p class='indent'> test 3 OK
</p><!-- l. 33 --><p class='indent'> \begin{align*} A &= B \end{align*}
</p><!-- l. 35 --><p class='indent'> test 4 FAIL
</p><!-- l. 39 --><p class='indent'> \begin{align*}\tag{1} A &= B \end{align*}
</p><!-- l. 41 --><p class='indent'> test 5 OK
</p><!-- l. 45 --><p class='indent'> \begin{align*} A &= 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
条件将不匹配。您需要条件围绕整个环境。