--- title: "epoxy in Reports" output: cleanrmd::html_document_clean: theme: new.css toc: true toc_depth: 2 vignette: > %\VignetteIndexEntry{epoxy in Reports} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` [glue]: https://glue.tidyverse.org ## Setup ```{r child = "../man/fragments/setup.Rmd"} ``` ## Using epoxy chunks ```{r child = "../man/fragments/first-example.Rmd"} ``` ## Inline transformers **epoxy** provides inline transformations inspired by [cli's inline markup](https://cli.r-lib.org/reference/inline-markup.html). This transformer is enabled by default in `epoxy()`, `epoxy_html()` and `epoxy_latex()` and their respective knitr chunk engines. ```{r child = "../man/fragments/example-movie.Rmd"} ``` Read more about inline transformations in `?epoxy_transform_inline`. ### Transform replaced values You can use the `epoxy_transform_wrap()` with the `epoxy_transform` chunk option to wrap the evaluated R expression in formatting or templating text. Or you can use the pre-set `epoxy_transform_bold()`, `epoxy_transform_italic()`, or `epoxy_transform_code()` transformers or with `epoxy_transform()`. ```` ```{epoxy, .transformer = epoxy_transform("bold")}`r ''` All cars stopped between {min(cars$dist)} and {max(cars$dist)} feet from a starting speed of {min(cars$speed)}---{max(cars$speed)} ``` ```` ```{epoxy, .transformer = epoxy_transform("bold")} All cars stopped between {min(cars$dist)} and {max(cars$dist)} feet from a starting speed of {min(cars$speed)}---{max(cars$dist)} 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}`r ''` {1:4}. "{letters[1:4]}" is for {c("apple", "banana", "coconut", "donut")} ``` ```` ```{epoxy} {1:4}. "{letters[1:4]}" is for {c("apple", "banana", "coconut", "donut")} ``` You can collapse fields automatically using the `epoxy_transform_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, .transformer = epoxy_transform("collapse")}`r ''` - The first three letters are {letters[1:3]*}. - When capitalized, they are {LETTERS[1:3]&}. - They're indexed by {1:3|}. ``` ```` ```{epoxy, .transformer = epoxy_transform("collapse")} - The first three letters are {letters[1:3]*}. - When capitalized, they are {LETTERS[1:3]&}. - They're indexed by {1: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_transform_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. ```{r} 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}`r ''` - A {manufacturer} {model} gets {cty} city and {hwy} highway miles per gallon. ``` ```{epoxy ref.label="car-name", .data = mpg}`r ''` ``` ```` ```{epoxy car-name, eval=FALSE} - A {manufacturer} {model} gets {cty} city and {hwy} highway miles per gallon. ``` ```{epoxy ref.label="car-name", .data = mpg} ``` ## 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}`r ''` contestant <- list(name = "R User", value = 1000, taxed = 600, in_ca = TRUE) ``` ```{whisker .data = contestant, echo=FALSE}`r ''` Hello {{name}}: You have just won ${{value}}! {{#in_ca}} Well, ${{taxed}}, after taxes. {{/in_ca}} ``` ```` ```{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}} ``` ## HTML and LaTeX chunks ### Markdown chunks The `epoxy` chunk engine can be used in any output format. In practice, it works best in markdown (i.e. generally in R Markdown or Quarto) ````{verbatim} ```{epoxy, .data = mpg} - **{manufacturer}** _{model}_ ``` ```` where it renders as: ```` ```{epoxy, .data = mpg} - **{manufacturer}** _{model}_ ``` ```` If you're writing for an HTML or LaTeX output, however, you may need to write literal HTML or LaTeX in your document. With the `epoxy` chun, you'd need to escape any `{` or `}` in your text by doubling them, otherwise the content within will be treated as a template expression. To avoid this friction, epoxy provides two additional chunk engines, `epoxy_html` for writing raw HTML and `epoxy_latex` for writing raw LaTeX. ### Raw HTML chunks Use the `epoxy_html` block to epoxy (glue) R and HTML together. The output is [raw HTML](https://pandoc.org/MANUAL.html#raw-htmltex). By default, expressions in these types of blocks are wrapped in `{{` and `}}`, like whisker templates above. ````{verbatim} ```` ```` ```` Notice that the output is HTML but wrapped in a [pandoc raw html block](https://pandoc.org/MANUAL.html#extension-raw_attribute), which tells pandoc that the content is HTML that shouldn't be modified[^raw-html]. It also means that the output of the chunk will [only be included in HTML documents](https://bookdown.org/yihui/rmarkdown-cookbook/raw-content.html). If your `epoxy_html` block is contained within another a raw html block, or if you want to force the output to appear, you can set the chunk option `html_raw = FALSE`. [^raw-html]: Without the raw html block, pandoc can do unexpected things to HTML, even if your output is HTML-friendly. If you are explicitly writing HTML markup in your R Markdown or Quarto document, you should probably wrap that markup in an `{=html}` block. `````{verbatim} ````{=html} ```` ````` `epoxy_html` uses two custom transformers, `epoxy_transform_inline()` and `epoxy_transform_html()`, applying the html transformer before the inline transformer. With `epoxy_transform_html()` you can use `element.class#id` syntax to wrap expressions in HTML elements (all parts are optional). Let's use this syntax to place manufacturer and model in `` and `` elements, each with a custom class. ````{verbatim} ```` ```` ```` Because the `epoxy_transform_html()` transformer uses `.` to create `` elements, `epoxy_html()` also recognizes `@` to access the inline transformers. So `{{.uppercase manufacturer}}` is assumed to be a CSS class and not an inline transformer class. ````{verbatim} ```{epoxy_html .data = mpg[1,]} {{.uppercase manufacturer}} {{@uppercase manufacturer}} ``` ```` ```` ```{epoxy_html .data = mpg[1,]} {{.uppercase manufacturer}} {{@uppercase manufacturer}} ``` ```` ### Raw LaTeX chunks Similarly, you can also use `epoxy_latex` chunks to epoxy R and LaTeX together. Wrap expressions in these types of chunks with `<<` and `>>`. ````{verbatim} \begin{itemize} ```{epoxy_latex, .data = mpg} \item <<.strong manufacturer>> <<.emph model>> gets <> city and <> highway miles per gallon. ``` \end{itemize} ```` In R Markdown knitting into a LaTeX output, this renders as: ```` \begin{itemize} ```{epoxy_latex, .data = mpg} \item <<.strong manufacturer>> <<.emph model>> gets <> city and <> highway miles per gallon. ``` \end{itemize} ```` Note that, like `epoxy_html` chunks, `epoxy_latex` places the output in [raw latex blocks]( https://bookdown.org/yihui/rmarkdown-cookbook/raw-latex.html). This behavior can be disabled by setting the chunk option `latex_raw = FALSE`. ⚠️ **Note:** Prior to v1.0.0, epoxy used single `<` and `>` characters for expression delimiters in `epoxy_latex()` chunks. This can lead to subtle but inescapable problems if you need to use these characters _inside_ your expression. As a result, `epoxy_latex()` now uses `<<` and `>>` to delimit inline expressions.