# Pre-compiled mathjax output using mathjax node in make4ht or htlatex

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?

• yes, I will post ann example later – michal.h21 Nov 19 '17 at 8:50
• – michal.h21 Nov 19 '17 at 8:51
• Quite happy to know that it is possible...!!! Eager to know how is it done with make4ht... – user61681 Nov 19 '17 at 13:01

## 1 Answer

Edit:

The current version of make4ht now contains an extension for mathjax-node-page. It can be requested using

make4ht -f html5+mathjaxnode 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}\$

$$\label{eq:hello} a = \sqrt{b^2 + c^2}$$

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:

• Great work...! Hope it helps many... – user61681 Nov 20 '17 at 0:35