58

update: Brandon Bertelsen's answer:

Brandon's answer produces the following output. It doesn't produce nice tables or highlight code like Rstudio does, and it crashes on some html files with unicode, so I'm not using it to automate my email reports.

My current approach is to compile with Rstudio to html, open the html document in chrome, and then copy and paste the html document into gmail. This works pretty well, see this gist: https://gist.github.com/nelsonauner/a68b5a808c232ce7817e

enter image description here

Original question:

Is there an easy way to send an R markdown document as the body of an email, so that the body of the email looks similar to the results of using Rstudio's "Knit HTML" ?

Here's a basic reproducible example using knitr, rmarkdown, and mailR

example.Rmd

---
title: "Report for email"
output: 
  html_document: 
    self_contained: no
---

```{r}
summary(cars)  
```

You can also embed plots, for example:

```{r, echo=FALSE}
plot(cars)
```

I'm using self_contained: no since the default base64 encoding does not work with mailR (recommended by Yihui in this SO post)

knit_and_send.R

# compile using rmarkdown
library(rmarkdown)
rmarkdown::render("example.Rmd")

library(mailR)

send.mail(from = "me@gmail.com",
          to = "me@gmail.com",
          subject = "R Markdown Report - rmarkdown",
          html = T,
          inline = T,
          body = "example.html",
          smtp = list(host.name = "smtp.gmail.com", port = 465, user.name = "me", passwd = "password", ssl = T),
          authenticate = T,
          send = T)

#compile using knitr
library(knitr)
knit2html("example.Rmd",options="")

send.mail(from = "me@gmail.com",
          to = "me@gmail.com",
          subject = "R Markdown Report - knitr",
          html = T,
          inline = T,
          body = "example.html",
          smtp = list(host.name = "smtp.gmail.com", port = 465, user.name = "me", passwd = "password", ssl = T),
          authenticate = T,
          send = T)

Both emails send successfully.

The knitted email looks like this:


knitted and emailed report


and the rmarkdown email looks like this. (Notice that it also includes a bunch of javascript files--I think I'd have to write some scripts to remove them)


enter image description here


But neither of them look as nice as the report that is produced from Rstudio's "Knit as HTML", which looks like this:

enter image description here

Any suggestions?

I think a true fix might involve some postprocessing of the html file that incorporate the css styling in an email-friendly way while removing the javascript files.

For now, I'll use the knitr package.

Please let me know if something isn't clear and I'll improve the question.

Relevant SO posts:

In R is there any way to send an RMarkdown v2 html file as the body of an email

mailR: how to send rmarkdown documents as body in email?

Nelson Auner
  • 1,421
  • 1
  • 15
  • 21
  • Looks like we are all looking how to do this without success... did you manage ? – statquant Jan 09 '16 at 13:40
  • Nope! My current approach is to compile as markdown in Rstudio, open the output html file, crtl-C crtl-P into an email, and send :( Noam ross suggests a package here: https://twitter.com/noamross/status/676760045187694596 . Still hoping to get attention of http://stackoverflow.com/users/559676/yihui – Nelson Auner Jan 10 '16 at 12:42
  • OK, I posted another extension of your post for interactive graphs... where your copy paste would not even work. Thanks – statquant Jan 10 '16 at 12:44
  • @statquant can you share link to question? You couldn't email interactive graphs (since email is static) so the problem isn't just copy/paste – Nelson Auner Jan 10 '16 at 13:58
  • http://stackoverflow.com/questions/34694775/how-can-i-embeded-an-interactive-chart-in-an-email-body – statquant Jan 10 '16 at 14:08

2 Answers2

15

The main problem is that email readers strip your code and don't allow external imports. To get basic CSS support, the best strategy is to use inline styles to have a consistent view. We'll circle back to that in a minute.

First, you have to setup your Rmd document a little differently so it excludes all the extra javascript files. theme, highlight and mathjax should all be null. Notice, I've added a css attribute.

---
title: "Report for email"
output: 
  html_document: 
    self_contained: no
    theme: null
    highlight: null
    mathjax: null
    css: ink.css
---

```{r}
summary(cars)  
```

You can also embed plots, for example:

```{r, echo=FALSE}
plot(cars)
```

ink.css comes from http://foundation.zurb.com/emails. I recommend using this as your base theme.

There are a number of different scripts you can use to "inline" your css (that's a verb), I've included instructions here for using premailer a python package. Unfortunately, none of them will support very complicated CSS like bootstrap. So you'll just have to make do with your own style built up using ink or whatever as your foundation.

You may need to install some elements, for me on Ubuntu:

sudo apt-get install python-pip libxslt1-dev
sudo pip install premailer

Now, you can do something like this.

library(rmarkdown)
library(mailR)
rmarkdown::render("example.Rmd")
system("python -m premailer -f example.html -o output.html")


send.mail(
  from = "me@gmail.com",
  to = "me@gmail.com",
  subject = "R Markdown Report - rmarkdown",
  html = T,
  inline = T,
  body = "output.html",
  smtp = list(
     host.name = "smtp.gmail.com", 
     port = 465, 
     user.name = "me",    
     passwd = "password", 
     ssl = T),
  authenticate = T,
  send = T)

DISCLAIMER: Your mileage may vary wildly depending on which email reader is your target

Brandon Bertelsen
  • 43,807
  • 34
  • 160
  • 255
  • Thanks for the answer, Brandon. I find that opening the original html file in chrome, then Crtl-C Crtl-P to paste it into an email preserves more of the original syntax than premailer. Curious as to what program (gmail?) is inlining the CSS when I use copy-paste – Nelson Auner Jan 21 '16 at 19:06
  • That is definitely a strange one indeed. I'd be interested to see the source you get in gmail when you're able to see the formatting. If you click on the dropdown at the top-left of the message you can click "Show original", and it will show you the whole text of the multipart-message. Put it in a gist if you have a minute. But remember - that's only gmail, people aren't guaranteed to be looking at your work only in gmail! I recommended ink because it hits a broader base of email clients. – Brandon Bertelsen Jan 21 '16 at 22:57
  • Here's the source of the email, and the R/html code that created it: https://gist.github.com/nelsonauner/a68b5a808c232ce7817e. Good point about compatibility, but at work, we all use gmail, so I even a gmail-specific solution would save me a lot of hassle. – Nelson Auner Jan 21 '16 at 23:19
  • I'm going to upvote your answer, and leave the question unanswered in the hopes that someone will answer with a solution that works to preserve table formatting and doesn't crash on unicode. If no one answers after a week or two, I'll accept this one--does that sound OK? – Nelson Auner Jan 21 '16 at 23:21
  • @nelsonauner I don't need the upvotes, leave it open untill you have a satisfactory solution. – Brandon Bertelsen Jan 21 '16 at 23:25
  • 1
    I just wrote a package for inlining CSS styles in HTML code that may be useful here: https://github.com/noamross/juicer – Noam Ross Mar 07 '16 at 20:50
  • Love the name. I'll try implementing later and let you know my results. – Brandon Bertelsen Mar 07 '16 at 20:53
  • I can't understand where did you get that ink.css file? – Mislav Dec 10 '18 at 18:20
  • @Mislav it comes from foundation https://foundation.zurb.com/emails.html read this carefully and you will be provided the files. They used to call it ink now it looks like they've changed it. – Brandon Bertelsen Dec 10 '18 at 23:10
  • @NoamRoss did you see they have an inliner too now? https://foundation.zurb.com/emails/inliner-v2.html – Brandon Bertelsen Dec 10 '18 at 23:19
6

Updated Dec 2019

R Studio has released a email-specific package blastula. I find that this does a good job at inlining CSS for emails.

https://github.com/rich-iannone/blastula

Nelson Auner
  • 1,421
  • 1
  • 15
  • 21