我用来htlatex
制作屏幕可读的(https://www.nvaccess.org/) MathML。使用以下文件
麦格
\documentclass{article}
\begin{document}
Here is a function $f(x)=15$.
Here is a number $326$.
\end{document}
和
配置文件
% https://tex.stackexchange.com/questions/20218/how-to-make-htlatex-split-large-html-file-into-sub-documents
\Preamble{xhtml,mathml,html5}
% https://tex.stackexchange.com/questions/68916/convert-latex-to-mathjax-html/68962
\Configure{@HEAD}{\HCode{<script type="text/javascript"\Hnewline
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"\Hnewline
></script>\Hnewline}}
\Configure{@HEAD}{\HCode{<style type="text/css">\Hnewline
.MathJax_MathML {text-indent: 0;}\Hnewline
</style>\Hnewline}}
% arial font
\Css{body{font-family: Arial, Helvetica, sans-serif; font-size: 1.0em;}}
\begin{document}
\EndPreamble
以及以下命令
htlatex.exe mwe.tex "mwe.cfg, charset=utf-8" " -cunihtf -utf8"
输出结果如下:
mwe.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/)" />
<link rel="stylesheet" type="text/css" href="mwe.css" />
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
></script>
<style type="text/css">
.MathJax_MathML {text-indent: 0;}
</style>
</head><body
>
<!--l. 5--><p class="noindent" >Here is a function <!--l. 5--><math
xmlns="http://www.w3.org/1998/Math/MathML"
display="inline" ><mi
>f</mi><mrow ><mo
class="MathClass-open">(</mo><mrow><mi
>x</mi></mrow><mo
class="MathClass-close">)</mo></mrow> <mo
class="MathClass-rel">=</mo> <mn>1</mn><mn>5</mn></math>.
</p><!--l. 7--><p class="indent" > Here is a number <!--l. 7--><math
xmlns="http://www.w3.org/1998/Math/MathML"
display="inline" ><mn>3</mn><mn>2</mn><mn>6</mn></math>.
</p>
</body>
</html>
输出中最重要的部分是
<mn>1</mn><mn>5</mn>
使用 NVDA(和 MathPlayer 插件)阅读时https://www.dessci.com/en/products/mathplayer/安装)该文件被读取为:
这是 x 的函数 f,等于一五点。这是数字三二六。
这不是最佳选择;如果我调整 html,使其具有
<mn>15</mn>
然后输出将按照我希望的方式读取:
这是 x 的函数 f 等于十五点。
我怎样才能调整调用htlatex
以便 MathML 输出<mn>15</mn>
而不是<mn>1</mn><mn>5</mn>
?
答案1
编辑2:
更新后的LuaXML
库位于 CTAN 和 TL 中,因此不再需要手动更新。我还添加了修改 DOM 的过滤器机制make4ht
。可以使用common_domfilters
开发版本中的扩展来请求基本 DOM 过滤器make4ht
:
make4ht -uc mwe.cfg -f html5+common_domfilters mwe.tex
编辑1:
我们发现tex4ht
包含后处理脚本,可以准确处理 MathML 中的数字。可以使用以下方式请求它:
htlatex.exe mwe.tex "mwe,charset=utf-8" " -cunihtf -utf8" " -cxhtmml"
如果你想使用htlatex
.make4ht
相当于:
make4ht -uc mwe.cfg mwe.tex "" "" "-cxhtmml"
它有一些问题,因为它会生成无效的 HTML5,因为它会保存空元素(例如<meta>
或)的结束标记<link>
,并将utf8
字符转换为 HTML 实体。但这证明原作者tex4ht
Eitan Gurari 知道这个问题,他的解决方案是使用后处理。因此,我将在即将发布的make4ht
版本中添加一些 Lua 过滤器,以解决常见的 HTML 问题。
原始答案:
此问题是由处理器中的错误引起的tex4ht
DVI
。它可以为使用与文档中使用的主字体不同的字体的文本添加一些标记。因此,它可以支持以下情况:
hello {\bfseries world}
上述代码无法在 TeX 宏级别上得到支持,必须由 DVI 处理器添加标记。结果如下:
Hello <span class='ecbx-1000'>world</span>
CSS 文件包含将文本渲染<span class='ecbx-1000'>
为粗体文本的指令。问题是,如果它包含一些重音字母,它将为每个重音字母创建 span 元素:
\textit{Příliš}
变成:
<span
class="ecti-1000">P</span><span
class="ecti-1000">ř</span><span
class="ecti-1000">í</span><span
class="ecti-1000">li</span><span
class="ecti-1000">š</span>
由于数学数字的渲染使用了类似的机制,因此您会得到分离的数字。所有这些问题都应该在tex4ht DVI 处理器的来源,但我不认为这很快就会发生。
作为一种解决方法,可以使用make4ht
构建文件。它是驱动现代编译过程的 Lua 脚本tex4ht
。LuaXML库(它尚未在 CTAN 上)提供了很好的 DOM 对象,可用于清理 HTML 文件。
将以下代码保存为mybuild.mk4
:
local filter = require "make4ht-filter"
local dom = require "luaxml-domobject"
-- elements which can be joined
local charclases = {
span=true,
mn = true
}
local function dom_process(s)
local obj = dom.parse(s)
-- join adjanced span and similar elements inserted by
-- tex4ht to just one object.
obj:traverse_elements(function(el)
local get_name = function(curr)
return string.lower(curr:get_element_name())
end
local get_class = function(next_el)
return next_el:get_attribute("class")
end
local is_span = function(next_el)
return charclases[get_name(next_el)]
-- return get_name(next_el) == "span"
end
local function get_next(curr, class)
local next_el = curr:get_next_node()
if next_el and next_el:is_element() and is_span(next_el) then
return next_el
end
end
-- loop over all elements and test if the current element is in a list of
-- processed elements (charclasses)
if is_span(el) then
local next_el = get_next(el)
-- loop over the following elements and test whether they are of the same type
-- as the current one
while next_el do
-- save the next element because we will remove it later
local real_next = get_next(next_el)
if get_name(el) == get_name(next_el) and get_class(el) == get_class(next_el) then
-- it the following element match, copy it's children to the current element
for _, child in ipairs(next_el:get_children()) do
el:add_child_node(child)
end
-- remove the next element
next_el:remove_node()
end
-- use the saved element as a next object
next_el = real_next
end
end
end)
-- serialize the DOM object back to HTML
return obj:serialize()
end
local process = filter {dom_process}
Make:match("html$", process)
该文档可以使用以下方式编译
make4ht -uc mwe.cfg -e mybuild.mk4 mwe.tex
稍微扩展一下的例子:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{siunitx}
\begin{document}
Here is a function $f(x)=15$.
Here is a number $326$. Longer text: $\mbox{hello}$
\textit{Příliš žluťoučký}
Hello {\bfseries world}
\end{document}
生成以下 HTML:
<!-- l. 8 --><p class='noindent'>Here is a function <!-- l. 8 --><math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>f</mi><mo class='MathClass-open'>(</mo><mi>x</mi><mo class='MathClass-close'>)</mo> <mo class='MathClass-rel'>=</mo> <mn>15</mn></math>.
</p><!-- l. 10 --><p class='indent'> Here is a number <!-- l. 10 --><math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mn>326</mn></math>.
Longer text: <!-- l. 10 --><math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mstyle class='mbox'><mtext>hello</mtext></mstyle></math>
</p><!-- l. 12 --><p class='indent'> <span class='ecti-1000'>Příliš</span> <span class='ecti-1000'>žluťoučký</span>
</p><!-- l. 14 --><p class='indent'> Hello <span class='ecbx-1000'>world</span> </p>