It is possible to convert latex to html with make4ht or htlatex in which mathematics content gets converted into svg. Is it possible to pre-compile mathematics content of latex file into mathjax (html-css) in produced html file? Can mathjax node be used in make4ht or htlatex to achieve this?
1 Answer
Edit:
The current version of make4ht now contains an extension for mjcli. It can be requested using
make4ht -f html5+mjcli filename.tex
Here is a sample document.
There is a command line application provided by mathjax-node-page, mjpage
, which can process the HTML page and replace the LaTeX or MathML code with plain HTML or SVG code, which can be rendered by most modern web browsers correctly and fast.
You can install it using
npm install -g mathjax-node-page
command.
I've created an experimental filter which add support for older version of mathjax-node
to make4ht
some time ago. Fortunately, it works even for the current version after some minor fixes.
It is more complex than it need to be, because mjpage
generates quite a lot of CSS
style information and inserts it to every HTML page it processes. Because tex4ht
can create separate HTML file for each section, it seems like unnecessary waste of space to me. So it tries to extract this CSS information to a separate CSS file, which is then referenced in the HTML pages.
The other thing it tries is to support the local fonts. The generated CSS references online fonts by default, but it may be useful to support the local fonts, for example when the output is an Epub file, which should be self-contained.
This is the filter, mathnode.lua
:
-- local mathnodepath = os.getenv "mathjaxnodepath"
--
-- print("mathnode", mathnodepath)
local mkutils = require "mkutils"
-- other possible value is page2svg
local mathnodepath = "mjpage"
-- options for MathJax command
local options = "--output CommonHTML"
-- math fonts position
-- don't alter fonts if not set
local fontdir = nil
-- if we copy fonts
local fontdest = nil
local fontformat = "otf"
local function compile(src)
local tmpfile = os.tmpname()
local filename = src
print("Compile using MathJax")
local command = mathnodepath .. " ".. options .. " < " .. filename .. " > " .. tmpfile
print(command)
local status = os.execute(command)
print("Result written to: ".. tmpfile)
mkutils.cp(tmpfile, src)
os.remove(tmpfile)
end
-- save the css code from the html page generated by MathJax
local function extract_css(file)
local f = io.open(file, "r")
local contents = f:read("*all")
f:close()
local css = ""
local filename = "mathjax-chtml.css"
contents = contents:gsub('<style [^>]+>(.+)</style>', function(style)
-- replace only the style for mathjax
if style:match "%.mjx%-math" then
css = style
return '<link rel="stylesheet" type="text/css" href="'..filename ..'" />'
end
end)
local x = assert(io.open(file, "w"))
x:write(contents)
x:close()
return filename, css
end
-- Update the paths to fonts to use the local versions
local function use_fonts(css)
local family_pattern = "font%-family:%s*(.-);.-%/([^%/]+)%.".. fontformat
local family_build = "@font-face {font-family: %s; src: url('%s/%s.%s') format('%s')}"
local fontdir = fontdir:gsub("/$","")
css = css:gsub("(@font%-face%s*{.-})", function(face)
if not face:match("url%(") then return face end
-- print(face)
local family, filename = face:match(family_pattern)
print(family, filename)
local newfile = string.format("%s/%s.%s", fontdir, filename, fontformat)
Make:add_file(newfile)
return family_build:format(family, fontdir, filename, fontformat, fontformat)
-- return face
end)
return css
end
local function save_css(filename, css)
local f = io.open(filename, "w")
f:write(css)
f:close()
end
return function(text, arguments)
-- if arguments.prg then mathnodepath = arguments.prg end
mathnodepath = arguments.prg or mathnodepath
options = arguments.options or options
fontdir = arguments.fontdir or fontdir
fontdest = arguments.fontdest or fontdest
fontformat = arguments.fontformat or fontformat
compile(text)
filename, css = extract_css(text)
-- use local font files if fontdir is present
if fontdir then
css = use_fonts(css)
end
save_css(filename, css)
Make:add_file(filename)
-- print(css)
print(filename)
end
It can be requested from the mk4
build file in the following way:
local mathjax_node = require "mathnode"
local format = "woff"
Make:match("html$", mathjax_node, {fontdir = format, fontformat = format})
Using Make:match
we request to run this filter on each HTML file and pass a configuration table to the filter. The fontdir
and fontformat
options are used if you want to use the local fonts. There should be a woff
subdirectory in your working directory with MathJax fonts in the woff
format for this example.
If you want to use the online fonts, which would be the case if you want to create a normal WWW page on the Internet, you don't need these options.
Another option is options
, which can be used to pass command line options to mjpage
. For example if you want the SVG
output, you can use:
local mathjax_node = require "mathnode"
Make:match("html$", mathjax_node, {options = "--output SVG"})
You can use the MathJax font for the document text as well, using the following .cfg
file:
\Preamble{xhtml,mathml}
\begin{document}
\Css{body{font-family: MJXc-TeX-main-Rw, MJXc-TeX-main-Iw, MJXc-TeX-main-Bw, sans-serif;}}
\EndPreamble
The following document:
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[czech]{babel}
\usepackage[utf8]{inputenc}
\usepackage{amsmath}
\begin{document}
hello world
Simple: $(\overline{x+y})=\overline{x}\overline{y}$
\begin{equation}
\label{eq:hello}
a = \sqrt{b^2 + c^2}
\end{equation}
See equation~\ref{eq:hello}
Now some multiline
\begin{multline*}
p(x) = 3x^6 + 14x^5y + 590x^4y^2 + 19x^3y^3\\
- 12x^2y^4 - 12xy^5 + 2y^6 - a^3b^3
\end{multline*}
Align:
\begin{align*}
2x - 5y &= 8 \\
3x + 9y &= -12
\end{align*}
Align*:
\begin{align*}
x&=y & w &=z & a&=b+c\\
2x&=-y & 3w&=\frac{1}{2}z & a&=b\\
-4 + 5x&=2+y & w+2&=-1+w & ab&=cb
\end{align*}
\end{document}
It can be compiled using:
make4ht -uc mycfg.cfg -e mybuild.mk4 filename.tex html5
Will be rendered in the following way:
-
-
-
1@raf the current recommended extension is
mjcli
. it uses github.com/michal-h21/mjcli, and can be requested usingmake4ht -f html5+mjcli
. Jul 23, 2021 at 10:22