---
title: "Use R to Write LaTeX Code in R Markdown Documents"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Use R to Write LaTeX Code in R Markdown Documents}
%\VignetteEngine{knitr::rmarkdown}
\usepackage[utf8]{inputenc}
---
Technical reports written in R Markdown usually include mathematical symbols.
R Markdown addresses that by supporting the inclussion of raw LaTeX code.
Depending on the desired output format, the code gets rendered by some LaTeX engine.
This feature is very convenient.
The issue here is that writing LaTeX code can be cumbersome and the result is usually hard to read.
Although the use of `newcommand` can alleviate that, in practice people use it infrequently.
The idea behind this package is that if you're writing an R Markdown report, you're already using R,
so you might as well use it to write your LaTeX code as well.
## Example
This is best explained through an example.
Consider the following equation, encountered in Riemannian geometry:
$$
\frac{d}{dt} \left \langle V,W \right \rangle = \left \langle \frac{DV}{dt}, W \right \rangle + \left \langle V, \frac{DW}{dt} \right \rangle
$$
The straightforward way to code that is:
```{latex}
\frac{d}{dt} \left \langle V,W \right \rangle = \left \langle \frac{DV}{dt}, W \right \rangle + \left \langle V, \frac{DW}{dt} \right \rangle
```
If you were to use `latexSymb`, you would proceed as follows instead.
First you would create objects of class `latex_symb` to represent the vector fields:
```{r}
library(latexSymb)
vf1 <- lsymb("V")
vf2 <- lsymb("W")
```
Then you would write R functions to represent the mathematical concepts being used: the inner product, the covariant derivative and the ordinary derivative:
```{r}
inner <- function(x,y) ang(lsymb(x, ",", y))
cov.der <- function(x) lsymb("D", x)/"dt"
ddt <- function(x) lsymb("d", x)/"dt"
```
Then you would put everything in an `equation` environment:
```{r, results = "asis"}
lenv("equation",
lsymb(
ddt(inner(vf1, vf2)),
"=",
inner(cov.der(vf1), vf2) + inner(vf1, cov.der(vf2))
)
) |> cat()
```
Notice that you need to `cat` instead of `print` to avoid double backslashes.
### Unpacking
Let us unpack all of this.
Notice first that in the definition of `cov.der` an important feature is being used.
Namely, the `/` function is overwritten by `latexSymb` so that if either of its arguments
are objects of class `latex_symb`, the output is another object of that class
that uses `frac` as you would expect.
This is also done with `+`, `-`, `*` and `^`.
Additionally, `under` adds support for the use of subscripts.
Also, in the numerator of `cov.der`, `lsymb("D", x)` concatenates the string `"D"`
and the object `x`, and wraps the result in a new `latex_symb` object.
Further, there's the use of the `latexSymb` function `ang`, which provides the dynamic enclosing for
the inner product, thus avoiding the need to write `left` and `right`.
The functions `br`, `sqbr` and `pths` do the same for braces, square brackets and parentheses respectively.
Finally, there is the function `lenv` that spares the user from writing `begin` and `end`.
The second argument is a list or a vector, whose components represent different lines.
So, for instance, we could have written also
```{r, results = "asis"}
lenv("align*",
c(
lsymb(ddt(inner(vf1, vf2)), "&=\\\\"),
lsymb("&=", inner(cov.der(vf1), vf2) + inner(vf1, cov.der(vf2)))
)
) |> cat()
```
`latex_symb` also exposes `il`, which surrounds expressions in dollar signs,
for inline math environments.
## Discussion
On the whole, `latexSymb` may not significantly reduce the amount of code
users have to write compared to raw LaTeX.
But I do think it makes it more readable and hence less prone to errors.
Users can mostly write what they mean, not what they want to see.
Additionally, `latexSymb` is not limited to RMarkdown.
Actually, it probably makes more sense in `.Rtex` documents.
In any case, any format that `knit` can handle will do.
Finally, for very complicated equations, R's piping should make things even more readable.