rmarkdown: Alter Action Depending on Document

November 18, 2014
By

(This article was first published on TRinker's R Blog » R, and kindly contributed to R-bloggers)

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")

rmarkdown


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.

github_flurry_ios_style_icon_by_flakshack-d5ariic


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"):

 

simple_html

HTML Document

 

simple_latex

LaTeX Document

 

simple_docx

docx Document

 


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('https://www.youtube.com/embed/FnblmZdTbYs?feature=player_detailpage')},
    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"):

extended_html

HTML Document

 

extended_latex

LaTeX Document

 

extended_docx

docx Document

 

I hope this post extends flexibility and speeds up workflow for folks. Thanks to @Baptiste for a terrific solution.

To leave a comment for the author, please follow the link and comment on their blog: TRinker's R Blog » R.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: Data science, Big Data, R jobs, visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...



If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Comments are closed.

Search R-bloggers


Sponsors

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)