Cross-referenceable math equation in RMarkdown 🔗
You can cross-reference equations in Rmarkdown if you set output to
bookdown::pdf_document2 and write equations within
\begin{align} ~ \end{align} or \begin{equation} ~ \end{equation}
To make a tag, put (\#eq:label_name) inside a math environment. The equation
can be cross-referenced by \@ref(eq:label_name). See this stackoverflow answer by Yihui Xie and
the related section of his bookdown book for more detail.
\begin{equation*} ~ \end{equation*} also produces an equation without number.
Drawback 🔗
A drawback of using \begin{align} ~ \end{align} or the like is that
RStudio doesn’t support math preview for them (yet). You must embrace
the whole math environment with $$.
The former looks nicer but causes the “Bad math delimiter” error at the time of tex compilation.
Workaround 🔗
Step 1 🔗
Put the following code snippet in .Rprofile file of the project.
.beginMath = c(
"\\begin{equation}",
"\\begin{equation*}",
"\\begin{align}",
"\\begin{align*}"
)
.endMath = c(
"\\end{equation}",
"\\end{equation*}",
"\\end{align}",
"\\end{align*}"
)
.render_for_tex = function(input, ...){
output_file = gsub("\\.[R|r]md$", ".tex", input)
lines = readLines(input, encoding = "UTF-8");
for (i in seq_along(lines)) {
# Remove $$ before \begin{equation} or the like.
if (stringr::str_trim(lines[i]) == "$$") {
if (any(startsWith(lines[i + 1], .beginMath))) {
lines[i] = ""
} else if (any(endsWith(lines[i - 1], .endMath))) {
lines[i] = ""
}
}
}
writeLines(lines,"temp.Rmd"); on.exit(unlink('temp.Rmd'))
rmarkdown::render("temp.Rmd", output_file = output_file)
}
Step 2 🔗
Add knit: .render_for_math to the YAML header of your Rmd file.
Then the Knit button of RStudio is overwritten with the custom renderer
with preprocessing defined in .Rprofile.
The YAML fromtmatter looks like
---
title: title
author: author
output:
bookdown::pdf_document2:
toc: false
fig_caption: yes
knit: .render_for_tex
---
Example 🔗
This PDF file is generated by the Rmd file and .Rprofile stored here.