Edit 2:
The updated LuaXML
library is on CTAN and in TL, so it is no longer necessary to update it manually. I also added mechanism for filters that modify the DOM to make4ht
. Basic DOM filters can be requested using common_domfilters
extension in the development version of make4ht
:
make4ht -uc mwe.cfg -f html5+common_domfilters mwe.tex
Edit 1:
We found that tex4ht
contains postprocessing script that handles exactly the numbers in MathML. It can be requested using:
htlatex.exe mwe.tex "mwe,charset=utf-8" " -cunihtf -utf8" " -cxhtmml"
if you want to use htlatex
. make4ht
equivalent is:
make4ht -uc mwe.cfg mwe.tex "" "" "-cxhtmml"
It have some issues, because it produces invalid HTML5, because it saves end tags for void elements such as <meta>
or <link>
and it converts utf8
characters to HTML entites. But it proves that original tex4ht
author, Eitan Gurari knew about this issue and his solution was to use a post-processing. So I will add some Lua filters for common HTML problems fixing to an upcoming make4ht
release.
Original answer:
This issue is caused by a bug in the tex4ht
DVI
processor. It can add some markup for text that use different font than the main font used in the document. Because of this, it can support such cases:
hello {\bfseries world}
The previous code cannot be supported on the TeX macro level, the markup must be added by the DVI processor. This is the result:
Hello <span class='ecbx-1000'>world</span>
The CSS file contains instruction to render <span class='ecbx-1000'>
as a bold text. The issue is that if it contains for example some accented letters, it will create span elements for each accented letter:
\textit{Příliš}
becomes:
<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>
Because a similar mechanism is used for rendering of the math numbers, you get the separated numbers. All of these issues should be fixed in the sources of tex4ht DVI processor, but I don!t think that it will happen any time soon.
As a workaround, it is possible to use make4ht
build file. It is a Lua script that drives the modern tex4ht
compilation process. The development version of the LuaXML library (it is not on CTAN yet) provides nice DOM object, which can be used for cleanup of the HTML file.
Save the following code as 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)
The document can be compiled using
make4ht -uc mwe.cfg -e mybuild.mk4 mwe.tex
A slightly expanded example:
\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}
Produces the following 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>
sed -i -e 's@</mn><mn>@@g'
to merge them before serving the html.sed
orperl
) is my back up, but I wondered if a 'native' solution is availabletex4ht
command, which is known and no one found a fix yet.\num
that did the right thing.