5

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?

3

1 Answer 1

8

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:

enter image description here

And here is the online version.

3

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .