My R Markdown (.Rmd) file looks like this:
---
title: Foo
author: Marius Hofert
header-includes:
- \\usepackage{bm}
output:
pdf_document
vignette: >
A third solution works well if you are using Mathjax to render equations in your html docs. Mathjax is on by default in pandoc in RStudio. This has the advantage of no flickering and works in $$ $$ and the equation environment. The big downside to this is that pandoc strips \ref{} out of the html so you have to add a knit hook to change to \ref{}. Surely there is a way to tell pandoc not to do this, but I couldn't find it. I tried many different pandoc args with no success.
This example assumes you want equation numbers and you want to crossref those in your text. It also assumes you are knitting from RStudio. Probably works otherwise, but that is what I tested in.
mathjax.js --- define the macros here and tell Mathjax to add eqn #s
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
TeX: {
equationNumbers: {autoNumber: "all"},
Macros: {
AA: "{\\bf A}",
BB: "{\\bf B}"
}
}
});
</script>
defs.tex --- this is for pdf_document
\def\AA{\bf A}
\def\BB{\bf B}
test.Rmd --- now we can make Rmd docs that work with html and pdf. I could not figure out how to tell pandoc not to strip LaTeX commands out of the html. So passed in a knit hook to double \ the \ref{} calls.
---
title: "Test"
knit: ( function(inputFile, encoding) { if(rmarkdown::all_output_formats(inputFile)[1]=="html_document"){ f <- inputFile; x <- readLines(f); y <- gsub("[\\]ref[{]","\\\\\\\\ref{", x); cat(y,file="tmp.Rmd", sep="\n"); rmarkdown::render("tmp.Rmd", encoding = encoding ) }else{ rmarkdown::render(inputFile, encoding = encoding ) } })
output:
html_document:
includes:
before_body: [../tex/mathjax.html]
pdf_document:
includes:
before_body: ../tex/defs2.tex
---
```{r mss-setup, include=FALSE, purl=FALSE}
knitr::opts_knit$set(unnamed.chunk.label = "tvarss-")
```
In the pdf, this will not have a number but in the html it will.
$$
\AA^\top\BB
$$
You can use nonumber if you need the equation numbering to be the same in html and pdf.
$$
\AA^\top\BB\nonumber
$$
If we want to crossref an equation, use equation environment.
\begin{equation}
\AA^\top\BB
\label{eqn1}\end{equation}
This is Equation \ref{eqn1}.
Here is the knit function:
( function(inputFile, encoding) { if(rmarkdown::all_output_formats(inputFile)[1]=="html_document"){ f <- inputFile; x <- readLines(f); y <- gsub("[\]ref[{]","\\\\ref{", x); cat(y,file="tmp.Rmd", sep="\n"); rmarkdown::render("tmp.Rmd", encoding = encoding ) }else{ rmarkdown::render(inputFile, encoding = encoding ) } })
I think your \[ \]
and \begin{align} ... \end{align}
are redundant. When I ran it as written above I got
! Package amsmath Error: Erroneous nesting of equation structures; (amsmath) trying to recover with `aligned'.
See the amsmath package documentation for explanation. Type H for immediate help. ...
l.84 \end{align}
Worked fine for me when I deleted \begin{align} ... \end{align}
...
(It seems that a similar issue arose in your previous question too ...)
(Perhaps you were getting errors that you didn't notice and were accidentally looking at a previously compiled version?)
As far as why you don't get the right HTML output: I'm pretty certain that MathJax (the engine used to render LaTeX embedded in Rmarkdown-produced HTML) doesn't know about \boldmath; adding the package to your LaTeX input won't help, you'll have to use \mathbf
and \boldsymbol
instead. You can play around here to see what works and what doesn't: entering
$\bm X \boldmath X \boldsymbol X \mathbf X$
at that web page gives
Bottom line, if you want fancy math rendered properly, you're probably better off sticking to PDF output.
Another solution is to use the child chunk argument. The downside, which is kind of major, is that it will only work for math surrounded by $ $ or $$ $$. It won't work in the equation environment. The upside is that you do not get your definitions "flashing" at the top of your html pages for a moment, which happens to me with the solution above.
demo.Rmd
---
title: Foo
output:
pdf_document: default
html_document: default
---
```{r child = 'defs.tex'}
```
My math definitions are in defs.tex. Now I can use the defs in equations
but they need to be in math mode for html output. This works for both
pdf and html:
$\AA^\top\BB$ and
$$\AA^\top\BB$$
But using your new commands in the equation environment
only works for pdf output because pandoc will not expand the
definitions if the newcommands are not in $ $ or $$ $$.
\begin{equation}
\AA^\top\BB
\end{equation}
defs.tex
\newcommand{\BB}{\mathbf{B}}
\newcommand{\CC}{\mathbf{C}}
\renewcommand{\AA}{\mathbf{A}}
I don't think Mathjax (which is what Pandoc uses in HTML output) can \usepackage{}
. I work around this by having 2 files: one called preamble-mathjax.tex
, one called preamble-latex.tex
My YAML metadata is set up like this (for rmarkdown
):
output:
html_document:
includes:
before_body: preamble-mathjax.tex
pdf_document:
includes:
in_header: preamble-latex.tex
And preamble-mathjax.tex
has (note surrounding \( \)
so that mathjax parses as a maths block)
\(
\newcommand{\bm}[1]{\boldsymbol{\mathbf{#1}}}
\)
while preamble-latex.tex
has:
\usepackage{bm}
So that whenever I use \bm{..}
in my document, it works whether I compile to HTML or PDF. (stacking the boldsymbol
with the mathbf
so that both greek letters and normal letters are made bold, and bold letters remain upright as they would if you used \bm
).
Peripheral to your question:
Eventually you may wish to have a third file, preamble-both.tex
, with macros that are not package-specific (supposing the relevant preamble-*
has already been included) e.g.
\newcommand{\bX}{\bm{X}} % bold X
\newcommand{\R}{\mathbb{R}} % real numbers
And then you include this with both output formats. This saves you from writing all your macros twice, once for html_document and again for pdf_document. However, MathJax requires the macros to be surrounded by \(
and \)
, whereas LaTeX will error out if this is the case.
The only way I've found to work around this is to have a file bracket-start.txt
containing just \(
and a file bracket-end.txt
containing just \)
, so that my YAML is:
output:
html_document:
includes:
before_body: [preamble-mathjax.tex, bracket-start.txt, preamble-both.tex, bracket-end.txt]
pdf_document:
includes:
in_header: preamble-latex.tex
before_body: preamble-both.tex
which is pretty unwieldy, but it works (there is the Pandoc latex_macros extension, but it has never worked for me)