3

Converting LaTeX to HTML keeping equations as LaTeX explains how to use \VerbMath in tex4ht to convert LaTeX to HTML while keeping equations the same. For reference I'll add that for multiple lines one can use the aligned environment as explained here.

However, these solutions do not work with labels. So what I would like is a way to turn

\begin{equation}
1=1 \label{eq}
\end{equation}

Equation \ref{eq}

into

\begin{equation}
1=1~~~(7)
\end{equation}

Equation (7)

where (7) is correct numbering of the equation. Can this be done with tex4ht, or is there some other script that does that?

Note: Mathjax can resolve labels/references, but I do not want to use Mathjax.

michal.h21
  • 50,697
Manu
  • 493

1 Answers1

1

Edit:

Because you don't want to use MathJax, you need to post-process your text to replace labels and cross-references and to insert equation numbers. Luckily, we can use make4ht build files for that.

Sample file:

\documentclass{article}
% \usepackage[T1]{fontenc}
\usepackage{amsmath}

\newcommand\mjref[1]{\ref{#1}}
\begin{document}
\begin{equation}
1=1 \label{eq}
\end{equation}

\begin{align}
  1 + a = 2\\
  2 - a = 1
\end{align}

Equation \mjref{eq} 
\end{document}

Details about \mjref are in the original answer, these details still apply. We will use modified package for keeping LaTeX math unchanged, latex-unchanged.sty:

\RequirePackage{verbatim,etoolbox}
\AtBeginDocument{%
  \def\AltMathOne#1${\HCode{\detokenize{\(#1\)}}$}
  \Configure{$}{}{}{\expandafter\AltMathOne} 
  \def\AltlMath#1\){\HCode{\detokenize{\(#1\)}}\)}
  \Configure{()}{\AltlMath}{}
  \def\AltlDisplay#1\]{\HCode{\detokenize{\[#1\]}}\]}
  \Configure{[]}{\AltlDisplay}{}
% 
\newcommand\VerbMath[1]{%
\ifcsdef{#1}{%
  \renewenvironment{#1}{%
    \NoFonts%
    \Configure{verbatim}{}{}
    \HChar{92}begin\{#1\}%
    \verbatim}{\endverbatim\HChar{92}end\{#1\}\EndNoFonts}%
}{}%
}

\VerbMath{align}
\VerbMath{equation}
\VerbMath{equation*}
  }

Slightly modified .cfg file:

\RequirePackage{latex-unchanged} 
\Preamble{xhtml,html5}
\begin{document}
\renewcommand\mjref[1]{\NoFonts\HChar{92}eqref\{#1\}\EndNoFonts}
\EndPreamble

And now the interesting stuff:

The build file, named youfilename.mk4:

local filter = require "make4ht-filter"
local crossref = require "crossref"
local process = filter { crossref }

Make:match(".html$", process)

This declares that all html files should be processed with crossref library, which will do all the hard work. Save the following code as crossref.lua:

-- counter values for particular counters will be saved here
local eqcounter = 0
-- pattern which will be inserted as equation number
local counter_pattern = "~~~(%i)"

-- list of environments to insert counters
local processed = {"equation", "align"}
local labels = {}


-- this function takes pattern for ending text (it is end environment or
-- \\ as line breaks in aligns) and insert counter numbers before the matched text
-- it also removes \labels and store them for future use
local function insert_counter(text, pattern, counter)
  local counter_pat = string.format(counter_pattern, counter)
  -- remove labels
  local removed_labels = text:gsub('%s*\\label{(.-)}', function(name)
    -- save counter under label name
    print("save label", name, counter)
    labels[name] = counter
    return ''
  end)
  local inserted = removed_labels:gsub(pattern, counter_pat .. '%0')
  print("inserted", inserted)
  return inserted
end

local function handle_counter(env, name)
  eqcounter = eqcounter + 1
  -- we need to support align environments, which will have multiple counters
  if env:match('\\\\') then
    local parts = {}
    local ending = env:gsub('(.-)\\\\', function(part)
      table.insert(parts, part)
      return ''
    end)
    local results = {}
    -- we first process lines ending with \\, the last line without this will be processd
    -- with usual code for end environment
    for _, part in ipairs(parts) do
      print("part", part)
      table.insert(results, insert_counter(part, '(%s*)$',eqcounter))
      eqcounter = eqcounter + 1
    end
    env  = table.concat(results, '\\\\') .. '\\\\' ..ending
  end
  -- now insert counter for the whole environment
  return insert_counter(env, '(%s*\\end{'.. name ..'}', eqcounter)
end

local function handle_refs(text)
  -- modify the pattern to match the referencing macro you use
  return text:gsub('\\eqref{(.-)}', function(label)
    local counter = labels[label]
    if not counter then return '??' end
    return string.format("(%i)", counter)
  end)
end

return function(s)
  -- process math environments defined in processed table
  for _, name in ipairs(processed) do
    -- match the whole environments and replace them with modified version
    s = s:gsub('(\\begin{' ..name .. '}.-\\end{'.. name ..'})', function(environment)
      return handle_counter(environment, name)
    end)
  end
  -- handle ref commands in text
  s = handle_refs(s)
  return s
end

Details are in the comments in the source code.

Compile using:

make4ht -uc myconfig4.cfg -e youfilename.mk4 sample.tex

This is the result:

<!--l. 7--><p class="noindent" >\begin{equation}
1=1~~~(1)
\end{equation}

</p><!--l. 11--><p class="noindent" >\begin{align}
1+a=2~~~(2)\\
2-a=1~~~(3)
\end{align}
</p><!--l. 16--><p class="noindent" >Equation (1)</p> 

Original answer:

MathJax supports labels and cross-references itself, so maybe it is more realistic to let it handle not only \label, but also \ref. I would define custom macro for referencing to math environments, which can be redefined to insert \ref{labelname} when the document is compiled with tex4ht. I wouldn't redefine \ref itself, because you probably don't want to loose ability to make references to sections or figures.

Something like this:

\documentclass{article}
\usepackage{amsmath}

\newcommand\mjref[1]{\ref{#1}}
\begin{document}
\begin{equation}
1=1 \label{eq}
\end{equation}

Equation \mjref{eq} 
\end{document}

The current version of the code for MathJax with LaTeX macros can be found helpers4ht bundle. It is not on CTAN, you can use just mathjax-latex4ht.sty package.

The configuration file can be simplified a bit:

\RequirePackage{mathjax-latex-4ht} 
\Preamble{xhtml}
\begin{document}
\renewcommand\mjref[1]{\NoFonts\HChar{92}eqref\{#1\}\EndNoFonts}
\EndPreamble

The only interesting thing is redefinition of \mjref command, which temporarily disables inserting HTML tags for fonts and it uses \HChar{92} to insert the \ character by it's ASCII code.

The resulting HTML code is following:

<!--l. 7--><p class="noindent" >\begin{equation}
1=1\label{eq}
\end{equation}
</p><!--l. 11--><p class="noindent" >Equation \eqref{eq}</p> 

It is rendered this way by MathJax:

enter image description here

michal.h21
  • 50,697
  • Thank you for the answer. However at the moment I am not using Mathjax (want this for a free wordpress blog), so I need to resolve the \label issue differently. – Manu Jul 05 '17 at 19:01
  • @EmanueleViola in this case it would be best to post-process this code and insert equation numbers with some external script. – michal.h21 Jul 05 '17 at 19:17
  • is there a simple way to compute the equation numbers instead of writing a script from scratch? – Manu Jul 05 '17 at 20:15
  • @EmanueleViola I am already working on that script. I think it is easier to compute the numbers within that script. – michal.h21 Jul 05 '17 at 20:21
  • thank you so much for the script! A dumb question: what is exactly the command line to run it? I tried htlatex sample.tex "myConfig4,youfilename.mk4" but doesn't give your output (\label{eq} is unchanged). – Manu Jul 05 '17 at 21:21
  • @EmanueleViola you need to use make4ht command. I've updated the answer. – michal.h21 Jul 05 '17 at 21:38
  • Thanks. I haven't checked your solution since I can't easily install make4ht (I have an old version of Mixtex) (any suggestions on how to install it easily appreciated as well ;-). But since it may take me a while I have accepted your answer. – Manu Jul 06 '17 at 20:45
  • @EmanueleViola I think that make4ht should be installed even in older Miktex (I think it is included at least since 2015). The installation on Windows wouldn't be straightforward otherwise, see https://github.com/michal-h21/make4ht/blob/master/INSTALL.md – michal.h21 Jul 06 '17 at 21:05
  • I am afraid that mine is much older than that. It would be great if there was an executable of make4ht. – Manu Jul 07 '17 at 00:23
  • @EmanueleViola make4ht is just Lua script which can be executed using texlua command. so if you have texlua available, then it should be possible to use make4ht. I hope this guide https://d800fotos.wordpress.com/2015/01/19/create-e-books-from-latex-tex-files-ebook-aus-latex-tex-dateien-erstellen/ might help you. – michal.h21 Jul 07 '17 at 09:14