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.

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

  • 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 5 '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 5 '17 at 19:17
  • is there a simple way to compute the equation numbers instead of writing a script from scratch? – Manu Jul 5 '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 5 '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 5 '17 at 21:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.