Skip to main content

R Markdown: The Definitive Guide A PreTeXt Edition

Chapter 12 Books

We have introduced the basics of R Markdown in Chapter 3, which highlighted how HTML, PDF, and Word documents can be produced from an R workflow. However, larger projects can become difficult to manage in a single R Markdown file. The bookdown package [12] addresses this limitation, and offers several key improvements:
  • Books and reports can be built from multiple R Markdown files.
  • Additional formatting features are added, such as cross-referencing, and numbering of figures, equations, and tables.
  • Documents can easily be exported in a range of formats suitable for publishing, including PDF, e-books and HTML websites.
This book itself was created using bookdown, and acts as an example of what can be achieved. Despite the name containing the word “book”, bookdown is not only for books, and it can be used for long reports, dissertations, or even single R Markdown documents (see Subsection 12.4.4). It also works with other computing languages such as Python and C++ (see Section 2.7). If you want, you can even write documents irrelevant to computing, such as a novel.
In this chapter, we cover the basics of bookdown, and explain how to start a bookdown project. Much of the content is based on the work “bookdown: Authoring Books and Technical Documents with R Markdown” (https://bookdown.org/yihui/bookdown/) of [6], which provides more detailed explanations of the concepts highlighted.

Section 12.1 Get started

You can install either the CRAN version or the development version on GitHub (https://github.com/rstudio/bookdown):
# install from CRAN
install.packages('bookdown')

# or GitHub
devtools::install_github('rstudio/bookdown')
If you use RStudio, you can start a new bookdown project from the menu File -> New Project -> New Directory -> Book Project using bookdown. Alternatively, the command bookdown:::bookdown_skeleton(getwd()) will create a skeleton project in your current working directory. Open the R Markdown file index.Rmd, and click the button Build Book on the Build tab of RStudio. This will compile the book and display the HTML version within the RStudio Viewer, which looks like Figure 12.1.
Figure 12.1.
The HTML output of the bookdown template.
You may add or change the R Markdown files, and hit the Knit button again to preview the book. If you prefer not to use RStudio, you may also compile the book through the command line using bookdown::render_book().

Section 12.2 Project structure

Below shows the basic structure of a default bookdown project:
directory/
├──  index.Rmd
├──  01-intro.Rmd
├──  02-literature.Rmd
├──  03-method.Rmd
├──  04-application.Rmd
├──  05-summary.Rmd
├──  06-references.Rmd
├── _bookdown.yml
├── _output.yml
├──  book.bib
├──  preamble.tex
├──  README.md
└──  style.css
As a summary of these files:
  • index.Rmd: This is the only Rmd document to contain YAML frontmatter as described in Chapter 2, and is the first book chapter.
  • Rmd files: A typical bookdown book contains multiple chapters, and each chapter lives in one separate Rmd file.
  • _bookdown.yml: A configuration file for bookdown.
  • _output.yml: It specifies the formatting of the HTML, LaTeX/PDF, and e-books.
  • preamble.tex and style.css: They can be used to adjust the appearance and styles of the book output document(s). Knowledge of LaTeX and/or CSS is required.
These files are explained in greater detail in the following subsections.

Subsection 12.2.1 Index file

The index.Rmd file contains the first chapter and the YAML metadata, for example:
---
title: "A Minimal Book Example"
author: "Yihui Xie"
date: "`r Sys.Date()`"
site: bookdown::bookdown_site
documentclass: book
bibliography: [book.bib, packages.bib]
biblio-style: apalike
link-citations: yes
description: "This is a minimal example of using
  the bookdown package to write a book."
---

Subsection 12.2.2 Rmd files

By default, all Rmd files are merged with index.Rmd to render the book. The Rmd files must start immediately with the chapter title using the first-level heading, for example # Chapter Title. YAML metadata should not be included in these Rmd files, as it is inherited from index.Rmd.
01-intro.Rmd
# Introduction

This chapter is an overview of the methods that
we propose to solve an **important problem**.
02-literature.Rmd
# Literature

Here is a review of existing methods.
By default, bookdown merges all Rmd files by the order of filenames, for example 01-intro.Rmd will appear before 02-literature.Rmd. Filenames that start with an underscore _ are skipped.

Subsection 12.2.3 _bookdown.yml

The _bookdown.yml file allows you to specify optional settings to build the book. For example, you may want to override the order in which files are merged by including the field rmd_files:
rmd_files: ["index.Rmd", "02-literature.Rmd", "01-intro.Rmd"]

Subsection 12.2.4 _output.yml

The _output.yml file is used to specify the book output formats (see Section 12.4). Here is a brief example:
bookdown::gitbook:
  lib_dir: assets
  split_by: section
  config:
    toolbar:
      position: static
bookdown::pdf_book:
  keep_tex: yes
bookdown::html_book:
  css: toc.css

Section 12.3 Markdown extensions

The bookdown package expands upon the Markdown syntax outlined in Section 2.5, and provides additional features that assist longer documents and academic writing.

Subsection 12.3.1 Number and reference equations

Subsection 2.5.3 highlighted how equations can be created using LaTeX syntax within Markdown. To number equations, put them in the equation environment, and assign labels using the syntax (#eq:label). Equation labels must start with the prefix eq: in bookdown. For example:
\begin{equation}
  E=mc^2
  (#eq:emc)
\end{equation}
It renders the equation below
\begin{equation*} E=mc^2 \end{equation*}

Subsection 12.3.2 Theorems and proofs

Theorems and proofs provide environments that are commonly used within articles and books in mathematics. To write a theorem, you can use syntax like:
```{theorem, label, name="Theorem name"}
Here is my theorem.
```
For example:
Theorems can be numbered and cross-referenced, as you can see from Theorem 12.2. The proof environment behaves similarly to theorem environments but is unnumbered.
Variants of the theorem environments include: lemma, corollary, proposition, conjecture, definition, example, exercise, and hypothesis. The abbreviations for references (e.g., \@ref(lem:mylemma)) are respectively lem, cor, prp, cnj, def, exm, exr, and hyp. Variants of the proof environments include remark and solution. The syntax for these environments is similar to the theorem environment, e.g., ```{lemma}.

Subsection 12.3.3 Special headers

There are two special types of first-level headers that can be used in bookdown:
  • A part can be created using # (PART) Part Title {-} before the chapters that belong to this part.
  • Appendices can be started with # (APPENDIX) Appendix {-}. All chapters after this header will be treated as appendices and numbered A, B, C, and so on.

Subsection 12.3.4 Text references

A text reference is a paragraph with a label. The syntax is (ref:label) text, where label is a unique identifier, and text is a Markdown paragraph. For example:
(ref:foo) Define a text reference **here**.
Then you can use (ref:foo) to refer to the full text. Text references can be used anywhere in the document, and are particularly useful when assigning a long caption to a figure or including Markdown formatting in a caption. For example:
    Some text.

    (ref:cool-plot) A boxplot of the data `iris` in **base** R.

```{r cool-plot, fig.cap='(ref:cool-plot)'}
    boxplot(Sepal.Length ~ Species, data = iris)
```

Subsection 12.3.5 Cross referencing

The bookdown package extends cross-referencing in R Markdown documents and allows section headers, tables, figures, equations, and theorems to be cross-referenced automatically. This only works for numbered environments. Cross-references are made in the format \@ref(type:label), where label is the chunk label and type is the environment being referenced. As examples:
As examples:
  • Headers:
    # Introduction {#intro}
    
    This is Chapter \@ref(intro)
    
  • Figures:
            See Figure \@ref(fig:cars-plot)
    
    ```{r cars-plot, fig.cap="A plot caption"}
            plot(cars)  # a scatterplot
    ```
    
  • Tables:
            See Table \@ref(tab:mtcars)
    
    ```{r mtcars}
            knitr::kable(mtcars[1:5, 1:5], caption = "A caption")
    ```
    
  • Theorems:
            See Theorem \@ref(thm:boring)
    
    ```{theorem, boring}
            Here is my theorem.
    ```
    
  • Equations:
    See equation \@ref(eq:linear)
    
    \begin{equation}
    a + bx = c  (\#eq:linear)
    \end{equation}
    
Only alphanumeric characters (a-z, A-Z, 0-9), -, /, and : are allowed in these labels.

Section 12.4 Output Formats

The bookdown package includes the following output formats:
  • HTML: gitbook, html_book, tufte_html_book
  • PDF: pdf_book
  • e-book: epub_book
  • Single documents: html_document2, tufte_html2, pdf_document2, tufte_handout2, tufte_book2, word_document2

Subsection 12.4.1 HTML

Although multiple formats are available for HTML books in bookdown, we will focus on the Gitbook style, which appears to be the most popular format. It provides a clean style, with a table of contents on the left. The design is fully responsive to make the content suitable for both mobile and desktop devices.
The output format bookdown::gitbook is built upon rmarkdown::html_document, which was explained in Section 3.1. The main difference between rendering in R Markdown and bookdown is that a book will generate multiple HTML pages by default. To change the way the HTML pages are split, the split_by argument can be specified. This defaults to split_by: chapter, but readers may prefer to use split_by: section if there are many sections within chapters, in which case a chapter page may be too long.

Subsection 12.4.2 LaTeX/PDF

There are limited differences between the output of pdf_book() in bookdown compared to pdf_document() in rmarkdown. The primary purpose of the new format is to resolve labels and cross-references in the syntax described in Subsection 12.3.5.
Pandoc supports LaTeX commands in Markdown. Therefore if the only output format that you want for a book is LaTeX/PDF, you may use the syntax specific to LaTeX, such as \newpage to force a page break. A major disadvantage of this approach is that LaTeX syntax is not portable to other output formats, meaning that these changes will not be transferred to the HTML or e-book outputs.

Subsection 12.4.3 E-books

The e-book formats can be read on devices like smartphones, tablets, or e-readers such as Kindle. You can create an EPUB e-book with bookdown::epub_book.

Subsection 12.4.4 A single document

We highlighted in Section 12.3 that bookdown extends the syntax provided by R Markdown, allowing automatic numbering of figures, tables, and equations, and cross-referencing them. You may use bookdown within single-file R Markdown documents to benefit from these features. The functions html_document2(), tufte_html2(), pdf_document2(), word_document2(), tufte_handout2(), and tufte_book2() are designed for this purpose. To use this in a traditional R Markdown document, you can replace the output YAML option as follows:
---
title: "Document Title"
output: bookdown::pdf_document2
---

Section 12.5 Editing

In this section, we explain how to edit, build, preview, and serve the book locally.

Subsection 12.5.1 Build the book

To build all Rmd files into a book, you can call the function bookdown::render_book(). It uses the settings specified in the _output.yml (if it exists). If multiple output formats are specified in it, all formats will be built. If you are using RStudio, this can be done through the Build tab. Open the drop down menu Build Book if you only want to build one format.
Figure 12.3.
The Build tab within RStudio highlighting bookdown output formats.

Subsection 12.5.2 Preview a chapter

Building the whole book can be slow when the size of the book is big or your book contains large amounts of computation. We can use the preview_chapter() function in bookdown to only build a single chapter at a time. Equivalently, you can click the Knit button in RStudio.

Subsection 12.5.3 Serve the book

Instead of running render_book() or preview_chapter() each time you want to view the changes, you can use the function bookdown::serve_book() to start a live preview of the book. Any time a Rmd file is saved, the book will be recompiled automatically, and the preview will be updated to reflect the changes.

Subsection 12.5.4 RStudio addins

The bookdown package comes with two addins for RStudio which assist the editing of books:
  • “Preview Book”: this calls bookdown::serve_book() to compile and serve the book.
  • “Input LaTeX Math”: provides a text box which allows you to write LaTeX equations, to avoid common errors when typing the raw LaTeX math expressions.

Section 12.6 Publishing

You can generate books for both physical and electronic distribution. This section outlines some of the main options.

Subsection 12.6.1 RStudio Connect

An easy way to publish books online is through https://bookdown.org, which is a website provided by RStudio to host books for free. Books can be pushed to this website by using bookdown::publish_book(). You will need to sign up for an account at https://bookdown.org/connect/, and your login details will be used to authorize bookdown the first time you call the publish_book() function.

Subsection 12.6.2 Other services

You can host your book online with many other web services, such as Netlify or GitHub (via GitHub Pages). Because output from bookdown::render_book() is a collection of static files, you can host them using the same methods of hosting normal web pages.

Subsection 12.6.3 Publishers

You can consider publishing physical copies of your book with a publisher or using self-publishing. Many publishers provide LaTeX style classes that can be used to set the overall appearance of the book, and these can be used by setting the documentclass option in the YAML metadata of index.Rmd. Further customization of PDF appearance can be achieved by altering the LaTeX preamble via the includes: in_header option of bookdown::pdf_book.