Rendering both PDF and HTML is only possible interactively, not via script

This is a crosspost of my GitHub issue on the kableExtra repository, where I have yet to receive any feedback, so I thought I'd try here.

I have some Rmd documents (weekly assignments) I want to render both as PDF (for turning them in) and HTML (for sharing them with classmates), and to make it easier, I use a simple build script that calls rmarkdown:render() for both formats:

#!/usr/bin/env Rscript

rmarkdown::render(input = "testing.Rmd", output_format = "html_document")
rmarkdown::render(input = "testing.Rmd", output_format = "pdf_document")

(I am assuming that output_format = "all" would be the neater option, but due to this issue here I went with the more debugging-friendly version)

However, when used in a script, the commands yield an error when building the PDF:

Error: Functions that produce HTML output found in document targeting latex output.
Please change the output type of this document to HTML. Alternatively, you can allow
HTML output in non-HTML formats by adding this option to the YAML front-matter of
your rmarkdown file:

  always_allow_html: yes

Note however that the HTML output will not be visible in non-HTML formats.

Since it is possible to render both PDF and HTML interactively in RStudio through the "knit" button, I am confused as to what exactly I'm doing wrong. Also, the kableExtra author previously mentioned on Stackoverflow that kabelExtra functions are "smart" enough to decide for themselves which output format is required.
It appears this issue may call that into question, or I'm just doing something wrong.

To Reproduce

I have prepared a demo project here: https://github.com/jemus42/Rmd-pdf-html-debug
You can clone the project, interactively render the testing.Rmd to PDF and HTML, and then execute the lines in the build.R script which should yield the described error.

I would like to know if this is some bug somewhere or if my understanding of the knitr/RMarkdown/kableExtra internals is merely insufficient.

Tested this on macOS Mojave and Ubuntu 16.04, each with current R 3.5.1 and up to date packages (CRAN)

I can't tell if nobody is able to reproduce my issue or if I didn't make clear what the issue is :pensive:

We want kable to generate html for the table when the document output format is html and latex for the table when the document output format is PDF. We can determine the output format from within the rmarkdown document using the knitr functions is_html_output() and is_latex_output(). Below is a complete rmarkdown document using the example you provided. I've added a test for the output document type in the code chunk where the table is generated. Then, within the kable function, we use the format argument to set the table output to "html" or "latex", depending on the type of document we're generating.

When I tried to render the document to PDF, I got a latex error: ! LaTeX Error: Unknown float option 'H'.. I've seen this before and thought it had been fixed in more recent versions of kableExtra, so I'm not sure why it's happening here. In any case, if you get the same error, it can be addressed by explicitly loading a bunch of latex packages by adding the following code to the YAML:

header-includes:
  - \usepackage{booktabs}
  - \usepackage{longtable}
  - \usepackage{array}
  - \usepackage{multirow}
  - \usepackage[table]{xcolor}
  - \usepackage{wrapfig}
  - \usepackage{float}
  - \usepackage{colortbl}
  - \usepackage{pdflscape}
  - \usepackage{tabu}
  - \usepackage{threeparttable}
  - \usepackage[normalem]{ulem}

Here's the full rmarkdown document.

---
title: "Testing Document"
author: Lukas
date: "`r Sys.time()`"
output: 
  pdf_document:
    latex_engine: pdflatex
  html_document:
    toc: true
    toc_float: true
    code_folding: show
fontfamily: palatino
editor_options: 
  chunk_output_type: console
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(echo = FALSE, warning = FALSE, 
                      message = FALSE, fig.align = "center",
                      fig.height = 2.5, fig.width = 8)

library(tibble)
library(knitr)
library(dplyr)
library(kableExtra)
```

# a small table

```{r}
a5 <- tibble(
  x = c(-1, 1, 2),
  f = c(0.2, 0.1, 0.7),
  Fx = cumsum(f)
) 

# Get output document type and use as the format argument in kable function
table_format = if(is_html_output()) {
  "html"
} else if(is_latex_output()) {
  "latex"
}

a5 %>%
  setNames(c("x", "f(x)", "F(x)")) %>%
  t() %>%
  kable(format = table_format, booktabs=TRUE) %>%
    kable_styling(latex_options = c("striped"))
```
2 Likes

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.