This is a follow-on question to this. I'm aware that the canonical method for cross-referencing figures and tables in a PDF produced by knitr is to use bookdown::pdf_document2
(details here).
This is awesome! But suppose that I want to send my Rmd to a user who doesn't have bookdown already installed? How can I ensure that the document will render if knitted in an environment in which bookdown is not already installed? I want to have everything self-contained in a single Rmd file. The consumer of the document might be someone with little or no prior experience of R, and has just installed R and RStudio but no packages. How can I ensure that if they click knit that they will get the PDF with cross-references? Alternatively, what if Binder or similar provide the means to execute (or, better still, knit to PDF) Rmd files in much the same way as is done with Jupyter Notebooks -- I'd like to be able to bundle everything that is needed for rendering the PDF in an automated way in the Rmd file itself.
An example document looks like this:
---
title: "Cross-refs test"
author: "Me"
date: "13 December 2017"
output:
bookdown::pdf_document2:
citation_package: natbib
fig_caption: yes
keep_tex: yes
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## Title
\begin{equation}
f\left(k\right)=\binom{n}{k}p^k\left(1-p\right)^{n-k} \label{eq:binom}
\end{equation}
You may refer to it using `\@ref(eq:binom)`, e.g., see Equation \@ref(eq:binom).
So if this Rmd file is downloaded and knit by a brain-dead zombie, or by Binder, how can I make sure that this doesn't happen:
Error in loadNamespace(name) : there is no package called 'bookdown'
Calls: <Anonymous> ... tryCatch -> tryCatchList -> tryCatchOne -> <Anonymous>
Execution halted
I can't assume that a consumer of my Rmd will know what to do in this situation, nor any automated process that I don't control that renders a PDF from the Rmd that it grabs from a repo somewhere (like what Binder does).
If there are no cross-references, I can specify pdf_document
as the output format and RStudio will read the YAML and if knitr and rmarkdown are not installed, installation of these will be triggered automatically (the user/brain-dead zombie just has to click on "OK" to accept installation) and the PDF will be rendered. So if these two packages are missing: no problem, at least when using RStudio. User gets Rmd, installs R and Rstudio, knits the Rmd, and the PDF appears. The same is not true if using bookdown to get cross-referencing.
It seems the YAML is interpreted before R code is executed, so the same kind of logic as this that is used to print the current time in a document (date: "`r Sys.time()`"
) doesn't work. Otherwise, I'd r install.packages("bookdown")
here.
So, is there a method to do cross-referencing without bookdown, but as simply and as elegantly as with bookdown, or is there someway of triggering knitr to install bookdown such that rendering won't crash when encountering bookdown::pdf_document2
?
Basically, what I want is cross-references in a knitted PDF with minimal user intervention to make it happen -- 'cos my user might be a brain-dead zombie or robot.
I want to avoid hard-coding cross-refs. And I'd rather not use LaTeX. Just pure R Markdown and some knitr magic, if possible.
source("https://github.com/.../myfile.R")
. Then, he can knit. – Sébastien Rochette