Installation
You can install the latest version of epoxy with remotes
# install.packages("remotes")
remotes::install_github("gadenbuie/epoxy")
or from gadenbuie.r-universe.dev.
options(repos = c(
gadenbuie = "https://gadenbuie.r-universe.dev/",
getOptions("repos")
))
install.packages("epoxy")
Setup
Loading epoxy adds four new knitr
engines, or chunk types. Each type lets you intermix text with R
code or data (expr
in the table below), and each is geared
toward a different output context.
Engine | Output Context | Delimiter |
---|---|---|
epoxy |
all-purpose markdown | {expr} |
epoxy_html |
HTML | {{expr}} |
epoxy_latex |
LaTeX | <expr> |
whisker |
all-purpose | mustache template language |
⚠️ Caution: Previously, epoxy provided a
glue
engine, but this conflicts with a similar chunk engine
by the [glue] package. You can update existing documents to use the
epoxy
engine, or you can explicitly use epoxy’s
glue
chunk by including the following in your setup
chunk.
Use epoxy
To use epoxy in your R Markdown document, create a new chunk using the engine of your choice. In that chunk, write in markdown, HTML, or LaTeX as needed, wrapping R expressions inside the delimiters for the epoxy chunk.
```{epoxy}
The average speed of the cars was **{mean(cars$speed)} mph.**
But on average the distance traveled was only _{mean(cars$dist)}_. ```
The average speed of the cars was 15.4 mph. But on average the distance traveled was only 42.98 ft.
epoxy
is built around glue::glue()
, which
evaluates the R expressions in the { }
and inserts the
results into the string. The chunk above is equivalent to this call to
glue::glue()
:
glue::glue("The average speed of the cars was **{mean(cars$speed)} mph**.
But on average the distance traveled was only _{mean(cars$dist)} ft_.")
#> The average speed of the cars was **15.4 mph**.
#> But on average the distance traveled was only _42.98 ft_.
One immediate advantage of using epoxy
instead of
glue::glue()
is that RStudio’s autocompletion feature works
inside epoxy
chunks! Typing cars$
in the chunk
will suggest the columns of cars
.
Inline styles
epoxy provides inline styling inspired by cli’s inline
markup. This styling is enabled by default in epoxy()
,
epoxy_html()
and epoxy_latex()
and their
respective knitr chunk engines.
Here’s an example using a small list containing data about a movie.
movie <- list(
year = 1989,
title = "Back to the Future Part II",
budget = 4e+07,
domgross = 118450002,
imdb_rating = 7.8,
actors = c(
"Michael J. Fox",
"Christopher Lloyd",
"Lea Thompson",
"Thomas F. Wilson"
),
runtime = 108L
)
We can use the inline styles to format the replacement text as we build up a description from this data.
```{epoxy echo = FALSE}
The movie {.emph {.titlecase movie$title}}
was released in {.strong movie$year}.
It earned {.dollar movie$domgross}
with a budget of {.dollar movie$budget},
and it features movie stars
{.and movie$actors}. ```
The movie Back to the Future Part II was released in 1989. It earned $118,450,002 with a budget of $40,000,000, and it features movie stars Michael J. Fox, Christopher Lloyd, Lea Thompson and Thomas F. Wilson.
Read more about inline styles in
?epoxy_style_inline
.
Style replaced values
You can use the epoxy_style_wrap()
with the
epoxy_style
chunk option to wrap the evaluated R expression
in formatting or templating text. Or you can use the pre-set
epoxy_style_bold()
, epoxy_style_italic()
, or
epoxy_style_code()
style transformers or with
epoxy_style()
.
```{epoxy, epoxy_style = epoxy_style("bold")}
All cars stopped between {min(cars$dist)} and {max(cars$dist)} feet
from a starting speed of {min(cars$speed)}---{max(cars$speed)}
```
All cars stopped between 2 and 120 feet from a starting speed of 4—120 mph.
epoxy chunks are vectorized
Unlike inline R code, the epoxy
chunks are vectorized.
This can be something to watch out for or it can be an advantage:
```{epoxy}
{1:4}. "{letters[1:4]}" is for {c("apple", "banana", "coconut", "donut")}
```
- “a” is for apple
- “b” is for banana
- “c” is for coconut
- “d” is for donut
You can collapse fields automatically using the
epoxy_style_collapse()
transformer. You can then choose how
vectors are collapsed by adding *
, &
or
|
to the end of the expression.
-
*
collapses with commas, e.g.{letters[1:3]*}
. -
&
collapses with commas and adds" and "
between the last two items -
|
collapses with commas and adds" or "
between the last two items.
```{epoxy, epoxy_style = epoxy_style("collapse")}
- The first three letters are {letters[1:3]*}.
- When capitalized, they are {LETTERS[1:3]&}.
- They're indexed by {1:3|}.
```
- The first three letters are a, b, c.
- When capitalized, they are A, B and C.
- They’re indexed by 1, 2 or 3.
You can change the separator between entries and between the last
entry using the sep
, last
and the
_and
and _or
specific arguments of the
epoxy_style_collapse()
function.
Templating with epoxy chunks
It’s also possible to create a reusable template. Use the
ref.label
chunk option to reuse a template using the values
in the data
chunk option, which can be a list or data
frame.
mpg <- data.frame(
manufacturer = c("Chevrolet", "Dodge", "Ford"),
model = c("Malibu", "Caravan", "Expedition"),
cty = c(19, 7, 11),
hwy = c(27, 24, 17)
)
```{epoxy car-name, eval=FALSE}
- A {manufacturer} {model} gets {cty} city and {hwy} highway miles per gallon.
```
```{epoxy ref.label="car-name", data = mpg}
```
- A Chevrolet Malibu gets 19 city and 27 highway miles per gallon.
- A Dodge Caravan gets 7 city and 24 highway miles per gallon.
- A Ford Expedition gets 11 city and 17 highway miles per gallon.
Whisker Engine
Sometimes the epoxy
engine doesn’t quite deliver the
template power you need. In these cases, you can use the
whisker
engine instead.
```{r}
contestant <- list(name = "R User", value = 1000, taxed = 600, in_ca = TRUE)
```
```{whisker data = contestant, echo=FALSE}
Hello {{name}}:
You have just won ${{value}}!
{{#in_ca}}
Well, ${{taxed}}, after taxes.
{{/in_ca}}
```
contestant <- list(name = "R User", value = 1000, taxed = 600, in_ca = TRUE)
Hello R User: You have just won $1000! Well, $600, after taxes.
Raw Blocks
HTML Blocks
Use the epoxy_html
block to epoxy (glue) R and HTML
together. The output is raw HTML. By
default, expressions in these types of blocks are wrapped in
{{
and }}
, like whisker templates above.
<ul>
```{epoxy_html, data = mpg}
<li><strong>{{manufacturer}}</strong> <em>{{model}}</em></li>
```
</ul>
- Chevrolet Malibu
- Dodge Caravan
- Ford Expedition
LaTeX Blocks
Similarly, you can also use epoxy_latex
blocks to epoxy
R and LaTeX together. By default, expressions in these types of blocks
are wrapped in <
and >
.
\begin{itemize}
```{epoxy_latex, data = mpg}
\item \textbf{<manufacturer>} \textit{<model>} gets <cty> city and <hwy> highway miles per gallon.
```
\end{itemize}
In R Markdown knitting into a LaTeX output, this renders as:
\begin{itemize}
\item \textbf{Chevrolet} \textit{Malibu} gets 19 city and 27 highway miles per gallon.
\item \textbf{Dodge} \textit{Caravan} gets 7 city and 24 highway miles per gallon.
\item \textbf{Ford} \textit{Expedition} gets 11 city and 17 highway miles per gallon.
\end{itemize}