Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving html to pdf in chrome

I am using rmarkdown to generate an HTML report. I am on a restricted machine, can't install tex. So, I was trying to generate an HTML document and then convert/print it to a pdf. The example markdown document is:

---
title: "trials"
author: "Foo Bar"
date: "15 December 2016"
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

```{r cars, echo=FALSE, cache=FALSE, message=FALSE}

library(dplyr, quietly = TRUE)
library(abind, quietly = TRUE)
virginica <- iris %>% filter(Species == "virginica") %>% head() %>% select(-Species)
setosa <- iris %>% filter(Species == "setosa") %>% head() %>% select(-Species)

diff_mat <- virginica - setosa


diff_mat[diff_mat<0] <- '<font color="green">&dArr; </font>'
diff_mat[diff_mat>0] <- '<font color="red">&uArr; </font>'
diff_mat[diff_mat == 0] <- '<font color="blue">&hArr; </font>'

datArray <- abind::abind(virginica, diff_mat, along=3)

fin_dat <- apply(datArray,1:2, function(x)paste(x[1],x[2], sep = " "))

knitr::kable(fin_dat, format = "html",
      escape = FALSE, table.attr = "border=1",
      caption = "Changes across species")

```

I can't knit to word either as the formatting is lost as discussed in HTML formatted tables in rmarkdown word document. The HTML produced is exactly what I wanted. HTML to word using save as in word works mostly fine with some issues and I can print pdf but it is not as good as directly printed from pdf. enter image description here

when I try to save it as pdf in chrome the colour is lost.

enter image description here

There is no issues in print options enter image description here

Other pages such as this question in our beloved site Replace NA's using data from Multiple Columns prints fine

enter image description here

Do you have any pointers where I am missing a point or where the issue is.

like image 523
discipulus Avatar asked Jan 12 '17 03:01

discipulus


1 Answers

Add this right after the YAML header:

<style>
@media print {

  font[color="green"] {
    color: #00ff00!important;
    -webkit-print-color-adjust:exact;
  }

  font[color="red"] {
    color: #ff0000!important;
    -webkit-print-color-adjust:exact;
  }

}
</style>

The problem is that RStudio's default R markdown templates use Bootstrap and their version of bootstrap.min.css has:

@media print {
  *,
  *:before,
  *:after {
    color: #000 !important;
    text-shadow: none !important;
    background: transparent !important;
    -webkit-box-shadow: none !important;
            box-shadow: none !important;
  }

in it. That's a pretty "destructive" media query as the *'s cause those settings to be applied to all tags and color: #000 !important; means "no color for YOU!" when you print a document. I grok the sentiment behind that (saving the planet + toner/ink costs) but if you're printing to PDF it makes no sense whatsoever.

Unfortunately, there are no hyper-targeted media queries for printing to PDF, so the generic "print" ones get applied when you print web pages to PDFs and these mindless, catch-all media queries take over.

The problem for you is that you'll need to be very specific in targeting any other tags to override these settings. Which means adding your own CSS classes to anything you generate in Rmds or getting cozy with "Inspect Element" until you catch'em all.

However, if you're feeling adventurous you can modify the YAML header to be:

output:
  html_document:
    self_contained: false

When you render to HTML it'll create a directory with subdirectories for the various components vs base64-encode them into one big document.

I named my document forso.Rmd which means it made a directory called forso_files and put subdirs under it.

Open up the main HTML file and scroll down until you see something like:

<script src="forso_files/jquery-1.11.3/jquery.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="forso_files/bootstrap-3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="forso_files/bootstrap-3.3.5/js/bootstrap.min.js"></script>
<script src="forso_files/bootstrap-3.3.5/shim/html5shiv.min.js"></script>
<script src="forso_files/bootstrap-3.3.5/shim/respond.min.js"></script>
<script src="forso_files/navigation-1.1/tabsets.js"></script>

Change this:

<link href="forso_files/bootstrap-3.3.5/css/bootstrap.min.css" rel="stylesheet" />

to:

<link href="forso_files/bootstrap-3.3.5/css/bootstrap.css" rel="stylesheet" />

Edit bootstrap.css, remove the color: #000 !important; line and add the -webkit-print-color-adjust:exact; line. SAVE A COPY OF bootstrap.css ELSEWHERE as it'll get squashed on future renders (i.e. you'll need to copy it back on every render).

You can't just link to a separate CSS file with a less brain dead print media query since the color: #000 !important; impacts all tags thanks to the * target and you can't just reset it to initial or inherit` because that will just turn them black as well.

Your final (and probably best) option is to make your own R Markdown template (see https://github.com/hrbrmstr/markdowntemplates for more info) and avoid placing over-arching print media queries in it.

like image 60
hrbrmstr Avatar answered Sep 18 '22 02:09

hrbrmstr