rmarkdown: Alter Action Depending on Document

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('<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
  }
]{}{http://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.

Advertisements

About tylerrinker

I am Literacy PhD student with a bent for the quantitative and a passion for R.
This entry was posted in knitr, r, reports, Uncategorized, work flow and tagged , , . Bookmark the permalink.

6 Responses to rmarkdown: Alter Action Depending on Document

  1. Great solution for xtable dilemmas.

  2. Pingback: The R-Podcast Episode 14: Tips and Tricks for using R-Markdown » The R-Podcast

  3. Pingback: The R-Podcast Episode 14: Tips and Tricks for using R-Markdown | Mubashir Qasim

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s