ymlthis is a package to help you write YAML metadata for R Markdown documents and related tools like blogdown, bookdown, and pkgdown. YAML serves two main roles: to pass information to be printed in the document, such as the title and author, and to control how the document is rendered, anything from the output type (HTML vs. PDF) and typesetting options to what should happen with files created while rendering. See the YAML: An Overview for a more general introduction to YAML and the YAML Fieldguide for YAML field documentation.
ymlthis makes it easy to write valid YAML by
handling the syntax and documenting the majority of YAML fields in one
place. yml()
creates a yml
object that, by
default, sets the author name and date. ymlthis uses
name options in devtools and usethis
(options(devtools.name = "name")
and
options(usethis.full_name = "name")
, respectively), as well
as the whoami package, to try to find the author’s
name. By default, the date is set to
`r format(Sys.Date())`
, which will update the date when
knitting.
yml()
---
author: Malcolm Barrett
date: '`r format(Sys.Date())`'
---
Functions that start with yml_*()
take and return
yml
objects, so they can be used to add or modify YAML
fields. For instance, to add a title, use yml_title()
yml() %>%
yml_title("An introduction to ymlthis")
---
author: Malcolm Barrett
date: '`r format(Sys.Date())`'
title: An introduction to ymlthis
---
An essential use of YAML in R Markdown is to set the
output type. By default, the output
YAML field looks
like
output: html_document
which calls rmarkdown::html_document()
when knitting.
All of the nested fields passed to output
come from the
output function you are using (so you can check
?pkg::output_function()
to see what the options are).
ymlthis writes and validates output YAML by parsing
calls to these functions. We can, for example, nest R
Markdown’s pdf_document()
inside
yml_output()
:
yml() %>%
yml_output(pdf_document())
---
author: Malcolm Barrett
date: '`r format(Sys.Date())`'
output: pdf_document
---
Passing arguments to the output functions will nest them correctly for YAML.
yml() %>%
yml_output(pdf_document(toc = TRUE))
---
author: Malcolm Barrett
date: '`r format(Sys.Date())`'
output:
pdf_document:
toc: true
---
And we can pass multiple output functions to facilitate rendering R Markdown files to multiple formats:
yml() %>%
yml_output(
pdf_document(toc = TRUE),
html_document()
)
---
author: Malcolm Barrett
date: '`r format(Sys.Date())`'
output:
pdf_document:
toc: true
html_document: default
---
YAML fields can come from a variety of places: R
Markdown itself, the output function, Pandoc (for example, as
options used in LaTeX), and custom templates. Many of these fields are
documented in yml_*()
functions.
yml() %>%
yml_author(
c("Yihui Xie", "Hadley Wickham"),
affiliation = "RStudio"
%>%
) yml_date("07/04/2019") %>%
yml_title("Reproducible Research in R") %>%
yml_category(c("r", "reprodicibility")) %>%
yml_output(
pdf_document(
keep_tex = TRUE,
includes = includes2(after_body = "footer.tex")
)%>%
) yml_latex_opts(biblio_style = "apalike")
---
author:
- name: Yihui Xie
affiliation: RStudio
- name: Hadley Wickham
affiliation: RStudio
date: 07/04/2019
title: Reproducible Research in R
category:
- r
- reprodicibility
output:
pdf_document:
keep_tex: true
includes:
after_body: footer.tex
biblio-style: apalike
---
You can also use yml_toplevel()
to append any YAML
fields not covered in ymlthis.
Parameterized
reports are a powerful feature of R Markdown that
lets you specify variables in the YAML metadata used in your report,
letting you re-use reports for a variety of settings. To set parameters,
you use the params
YAML field and access the parameter in
your report by calling params$variable_name
. Basic YAML for
parameters looks like this
params:
country: "Turkey"
Calling params$country
in the R
Markdown document will thus return "Turkey"
.
yml_params()
will write this for you:
yml() %>%
yml_params(country = "Turkey")
---
author: Malcolm Barrett
date: '`r format(Sys.Date())`'
params:
country: Turkey
---
You can also fill in parameters using a Shiny app
with the “Knit with Parameters” button in the RStudio IDE or by passing
"ask"
to the params
argument in
rmarkdown::render()
. While R Markdown will
try to guess the Shiny widget type by the value of the parameter, you
can specify them yourself with ymlthis functions that
start with shiny_*()
.
yml() %>%
yml_params(
data = shiny_file("Upload Data (.csv)"),
n = shiny_numeric("n to sample", 10),
date = shiny_date("Date"),
show_plot = shiny_checkbox("Plot the data?", TRUE)
)
---
author: Malcolm Barrett
date: '`r format(Sys.Date())`'
params:
data:
input: file
label: Upload Data (.csv)
'n':
input: numeric
label: n to sample
value: 10.0
date:
input: date
label: Date
show_plot:
input: checkbox
label: Plot the data?
value: true
---
R
Markdown has excellent support for citations. The simplest
way to use references in an R Markdown file is to add a
bibliography file using the bibliography
field.
yml() %>%
yml_citations(bibliography = "refs.bib")
---
author: Malcolm Barrett
date: '`r format(Sys.Date())`'
bibliography: refs.bib
---
However, if you only have a few references and want to keep your file
self-contained, you can also specify references directly in your YAML
using yml_reference()
and reference()
.
<- reference(
ref id = "fenner2012a",
title = "One-click science marketing",
author = list(
family = "Fenner",
given = "Martin"
),`container-title` = "Nature Materials",
volume = 11L,
URL = "https://doi.org/10.1038/nmat3283",
DOI = "10.1038/nmat3283",
issue = 4L,
publisher = "Nature Publishing Group",
page = "261-263",
type = "article-journal",
issued = list(
year = 2012,
month = 3
)
)
yml() %>%
yml_reference(ref)
---
author: Malcolm Barrett
date: '`r format(Sys.Date())`'
reference:
- id: fenner2012a
title: One-click science marketing
author:
family: Fenner
given: Martin
container-title: Nature Materials
volume: 11
URL: https://doi.org/10.1038/nmat3283
DOI: 10.1038/nmat3283
issue: 4
publisher: Nature Publishing Group
page: 261-263
type: article-journal
issued:
year: 2012.0
month: 3.0
---
yml_reference()
also supports package citation using the
.bibentry
argument and citation()
.
yml() %>%
yml_reference(.bibentry = citation("purrr"))
---
author: Malcolm Barrett
date: '`r format(Sys.Date())`'
---
If you have an existing .bib
file, but you want to
specify it in the YAML, instead, you can convert it with
bib2yml()
. For instance, if you wrote a .bib
file for the packages used in your document with
knitr::write_bib()
, bib2yml()
will translate
the file to YAML you can include directly in the metadata.
Packages that extend R Markdown, such as
bookdown and blogdown, also extend the
YAML used to make documents. One of the main ways that other packages
introduce YAML is through new output functions. xaringan,
for instance, doesn’t use custom YAML outside of its output function, so
ymlthis supports it out-of-box. Passing
xaringan::moon_reader()
to yml_output()
will
write the YAML for you.
yml() %>%
yml_title("Presentation Ninja") %>%
yml_subtitle("with xaringan") %>%
yml_output(
::moon_reader(
xaringanlib_dir = "libs",
nature = list(
highlightStyle = "github",
highlightLines = TRUE,
countIncrementalSlides = FALSE
)
) )
---
author: Malcolm Barrett
date: '`r format(Sys.Date())`'
title: Presentation Ninja
subtitle: with xaringan
output:
xaringan::moon_reader:
lib_dir: libs
nature:
highlightStyle: github
highlightLines: true
countIncrementalSlides: false
---
ymlthis can process any output function. Other
packages also add additional YAML; ymlthis supports six
R Markdown packages: bookdown,
blogdown, pkgdown,
pagedown, rticles, and
distill. ymlthis also supports YAML
for writing scheduled emails with RStudio Connect. You can find
functions supporting these packages with the patterns
yml_packagename_*()
and packagename_*()
(rsconnect
, in the case of RStudio Connect functions).
Functions that start with yml_packagename_*()
document YAML
fields and return yml
objects, while functions that start
with packagename_*()
are helper functions. There are also a
few template functions. pkgdown_template()
, for instance,
will assemble a full template for _pkgdown.yml
and return
it as a yml
object, and blogdown_template()
will return YAML templates matching your Hugo theme.
package | output function | top-level YAML |
---|---|---|
bookdown | ✓ | ✓ |
blogdown | ✓ | ✓ |
pkgdown | ✓ | ✓ |
pagedown | ✓ | ✓ |
rticles | ✓ | ✓ |
distill | ✓ | ✓ |
learnr | ✓ | ✗ |
xaringan | ✓ | ✗ |
revealjs | ✓ | ✗ |
flexdashboard | ✓ | ✗ |
ymlthis prints YAML cleanly to the console such that you could copy and paste it into an R Markdown document. However, ymlthis also provides a number of other workflows.
The easiest way is to use the Shiny add-in included with ymlthis; the add-in supports the most commonly used R Markdown options, citations, LaTeX options, and parameterized reports. You can then export the YAML to an R Markdown file, YAML file, or have it placed on your clipboard.
For more flexibility or to use R Markdown extension packages, you’ll have to write code, as we’ve been doing in this vignette. Your main options are to write the YAML to a file or to place it on your clipboard.
use_rmarkdown()
, use_yml_file()
, and
friends will take a yml
object and write to a file for you.
Passing yml
objects to use_rmarkdown()
is
often the simplest approach: it will translate the yml
object into YAML and open a new R Markdown file for you with the
metadata already written.
ymlthis also supports YAML files. For instance,
using pkgdown_template() %>% use_pkgdown_yml()
will
write the YAML for your pkgdown site to
_pkgdown.yml
based on your package directory.
ymlthis also has some helper functions for working with
Pandoc templates and highlighting themes.
As an example, let’s set up the navbar YAML for an R
Markdown website and then pass it to
use_navbar_yml()
.
<- yml_empty() %>%
navbar_yaml yml_site_opts(
name = "my-website",
output_dir = "_site",
include = "demo.R",
exclude = c("docs.txt", "*.csv")
%>%
) yml_navbar(
title = "My Website",
left = list(
navbar_page("Home", href = "index.html"),
navbar_page(navbar_separator(), href = "about.html")
)%>%
) yml_output(html_document(toc = TRUE, highlight = "textmate"))
# save to temporary directory since this is not interactive
<- tempfile()
path ::dir_create(path)
fs
use_navbar_yml(navbar_yaml, path = path)
#> ✔ Writing '/private/var/folders/w7/8yv1j00s0bb3pfhmqc_rvd980000gn/T/Rtmp6wBOjb/
#> file15d7f463a7d58/_navbar.yml'
In addition to writing to files, you can save YAML to your
.Rprofile
using
options(ymlthis.defaults = "{YAML}")
. yml()
will return the stored YAML by default. If you pass a yml
object to use_yml_defaults()
, the code to do this will be
placed on your clipboard, which you should paste into your
.Rprofile
. Open that file with
usethis::edit_r_profile()
. You can also set a default for
body text for use_rmarkdown()
by setting the
ymlthis.rmd_body()
option,
e.g. options(ymlthis.rmd_body = "{your text}")
(or take
advantage of use_rmd_defaults()
). Together with specifying
default YAML, use_rmarkdown()
also serves as an ad-hoc way
to make R Markdown templates.
<- options(
old ymlthis.default_yml = "author: Malcolm Barrett
date: '`r format(Sys.Date())`'
output: bookdown::pdf_document2",
ymlthis.rmd_body = c(
"",
::setup_chunk(),
ymlthis"",
::code_chunk(
ymlthislibrary(ymlthis)
)
)
)
# use temporary path set above
use_rmarkdown(path = file.path(path, "analysis.Rmd"))
#> ✔ Writing '/var/folders/w7/8yv1j00s0bb3pfhmqc_rvd980000gn/T/Rtmp6wBOjb/
#> file15d7f463a7d58/analysis.Rmd'
# reset previous option defaults
options(old)
function | action |
---|---|
use_yml_file() |
Write yml to a file |
use_bookdown_yml() |
Write yml to
_bookdown.yml |
use_navbar_yml() |
Write yml to
_navbar.yml |
use_output_yml() |
Write yml to
_output.yml |
use_pkgdown_yml() |
Write yml to
_pkgdown.yml |
use_site_yml() |
Write yml to _site.yml |
function | action |
---|---|
use_rmarkdown() |
Write yml to a .Rmd
file |
use_index_rmd() |
Write yml to Index.Rmd |
A final way to use ymlthis is to put YAML on your
clipboard to paste into a file or other setting. To place rendered YAML
on your clipboard, simply pass a yml
object to
use_yml()
.
function | action |
---|---|
use_yml() |
Place yml on your clipboard |
use_yml_defaults() |
Place code on your clipboard to save yml
to your default options |
use_pandoc_highlight_style() |
Write pandoc theme templates to a .theme
file |
use_pandoc_template() |
Write pandoc templates to a file |
Under the hood, yml
objects are lists of types that
match the corresponding YAML and are only converted to YAML when
printing or writing to files. Because yml
objects are just
lists, you can work with them as such. ymlthis also
includes several purrr-like functions for working with
yml
objects. Let’s define a yml
object that
has a fairly comprehensive set of options:
<-
x yml() %>%
yml_author(
c("Yihui Xie", "Hadley Wickham"),
affiliation = "RStudio"
%>%
) yml_date("07/04/2019") %>%
yml_title("Reproducible Research in R") %>%
yml_category(c("r", "reprodicibility")) %>%
yml_output(
pdf_document(
keep_tex = TRUE,
includes = includes2(after_body = "footer.tex")
),html_document()
%>%
) yml_latex_opts(biblio_style = "apalike")
The resulting YAML of x
is:
---
author:
- name: Yihui Xie
affiliation: RStudio
- name: Hadley Wickham
affiliation: RStudio
date: 07/04/2019
title: Reproducible Research in R
category:
- r
- reprodicibility
output:
pdf_document:
keep_tex: true
includes:
after_body: footer.tex
html_document: default
biblio-style: apalike
---
We can use yml_discard()
to remove the
category
option:
%>%
x yml_discard("category")
---
author:
- name: Yihui Xie
affiliation: RStudio
- name: Hadley Wickham
affiliation: RStudio
date: 07/04/2019
title: Reproducible Research in R
output:
pdf_document:
keep_tex: true
includes:
after_body: footer.tex
html_document: default
biblio-style: apalike
---
We can use purrr-style lambdas to express what to discard. How about any YAML fields with a length greater than one?
%>%
x yml_discard(~ length(.x) > 1)
---
date: 07/04/2019
title: Reproducible Research in R
biblio-style: apalike
---
The yml_pluck()
function is useful for selectively
acquiring a nested portion of the YAML:
%>%
x yml_pluck("output", "pdf_document")
---
keep_tex: true
includes:
after_body: footer.tex
---