rmarkdown: Alter Action Depending on Document
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
Can I see a show of hands for those who love rmarkdown? Yeah me too. One nifty feature is the ability to specify various document prettifications in the YAML of a .Rmd document and then use:
rmarkdown::render("foo.Rmd", "all")
The Problem
Have you ever said, “I wish I could do X for document type A and Y for document type B”? I have, as seen in this SO question from late August. But my plea went unanswered until today…
The Solution
Baptiste Auguie answered a similar question on SO. The key to Baptiste’s answer is this:
```{r, echo=FALSE} out_type <- knitr::opts_knit$get("rmarkdown.pandoc.to") ```
This basically says “Document. Figure out what type you are”. You can then feed this information to if () {} else {}
, switch()
, etc. and act differently, depending on the type of document being rendered. If Baptiste is correct the options and flexibility are endless.
I decided to put Baptiste’s answer to the test on more complex scenarios. Here it is as GitHub repo that you can fork and/or download and try at home.
Simple Example
To get a sense of how this is working let’s start with a simple example. I will assume some familiarity with rmarkdown and the YAML system. Here we will grab the info from knitr::opts_knit$get("rmarkdown.pandoc.to")
and feed it to a switch()
statement and act differently for a latex, docx, and html document.
--- title: "For Fun" date: "`r format(Sys.time(), '%d %B, %Y')`" output: html_document: toc: true theme: journal number_sections: true pdf_document: toc: true number_sections: true word_document: fig_width: 5 fig_height: 5 fig_caption: true --- ```{r, echo=FALSE} out_type <- knitr::opts_knit$get("rmarkdown.pandoc.to") ``` ## Out Type ```{r, echo=FALSE} print(out_type) ``` ## Good times ```{r, results='asis', echo=FALSE} switch(out_type, html = "I'm HTML", docx = "I'm MS Word", latex = "I'm LaTeX" ) ```
The result for each document type is using rmarkdown::render("simple.Rmd", "all")
:
Extended Example
That’s great but my boss ain’t gonna be impressed with printing different statements. Let’s put this to the test. I want to embed a video into the HTML and PDF (LaTeX) or just put a url for an MS Word (docx) document. By the way if someone has a way to programmaticly embed the video in the docx file please share.
For this setup we can use a standard iframe for HTML and the media9 package for the LaTeX version to add a YouTube video. Note that not all PDF viewers can render the video (Adobe worked for me PDF XChange Viewer did not). We also have to add a small tweak to include the media9 package in a .sty (quasi preamble) using this line in the YAML:
includes: in_header: preambleish.sty
And then create a separate .sty file that includes LaTeX package calls and other typical actions done in a preamble.
--- title: "For Fun" date: "`r format(Sys.time(), '%d %B, %Y')`" output: html_document: toc: true theme: journal number_sections: true pdf_document: toc: true number_sections: true includes: in_header: preambleish.sty word_document: fig_width: 5 fig_height: 5 fig_caption: true --- ```{r, echo=FALSE} out_type <- knitr::opts_knit$get("rmarkdown.pandoc.to") ``` ## Out Type ```{r, echo=FALSE} print(out_type) ``` ## Good times ```{r, results='asis', echo=FALSE} switch(out_type, html = {cat('<a href="https://www.youtube.com/embed/FnblmZdTbYs?feature=player_detailpage">https://www.youtube.com/embed/FnblmZdTbYs?feature=player_detailpage</a>')}, docx = cat("https://www.youtube.com/watch?v=ekBJgsfKnlw"), latex = cat("\begin{figure}[!ht] \centering \includemedia[ width=0.6\linewidth,height=0.45\linewidth, activate=pageopen, flashvars={ modestbranding=1 % no YT logo in control bar &autohide=1 % controlbar autohide &showinfo=0 % no title and other info before start } ]{}{https://www.youtube.com/v/ekBJgsfKnlw?rel=0} % Flash file \caption{Important Video.} \end{figure}" ) ) ```
The result for each document type is using rmarkdown::render("extended.Rmd", "all")
:
I hope this post extends flexibility and speeds up workflow for folks. Thanks to @Baptiste for a terrific solution.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.