Last active
December 1, 2020 05:15
-
-
Save kenjisato/38a646042ab6d64788c24c51cf36aae7 to your computer and use it in GitHub Desktop.
Cross Referenceable Equation with Preview in RMarkdown: http://en.kenjisato.jp/rmarkdown-math/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
title: Math environment inside $$ | |
author: Kenji Sato | |
output: | |
bookdown::pdf_document2: | |
toc: false | |
fig_caption: yes | |
knit: .render_for_tex | |
--- | |
# Matheamtical equation with `bookdown::pdf_document2` | |
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}` | |
An example: | |
$$ | |
\begin{equation} | |
f(x) = f(0) + \int_0^x f'(y) dy, (\#eq:ftc) | |
\end{equation} | |
$$ | |
which we can cross-reference with a syntax different from LaTeX: Equation \@ref(eq:ftc). See [this stackoverflow answer by Yihui Xie](http://stackoverflow.com/a/38884378/1877682) and | |
[the related section of his bookdown book](https://bookdown.org/yihui/bookdown/markdown-extensions-by-bookdown.html#equations) for more detail. | |
`\begin{equation*} ~ \end{equation*}` also produces an equation without | |
number: | |
$$ | |
\begin{equation*} | |
a^n + b^n = c^n | |
\end{equation*} | |
$$ | |
# 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 `$$`. (Figure \@ref(fig:preview)) | |
```{r preview, fig.cap="Math preview", echo=FALSE} | |
knitr::include_graphics("fig/math.png") | |
``` | |
The former however causes the "Bad mathe delimiter" error | |
in the process of tex compilation. | |
# Workaround | |
### Step 1 {-} | |
Put the following code snippet in .Rprofile file of the project. | |
```{r} | |
.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. | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.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) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment