[BOOKDOWN third] Customization
1. YAML options
Depending on how much you want to customize the output, you may use some simple options in the YAML metadata, or just replace the entire Pandoc template.
For most types of output formats, you can customize the syntax highlighting styles using the highlight
option of the specific format. Currently, the possible styles are default
, tango
, pygments
, kate
, monochrome
, espresso
, zenburn
, haddock
, and breezedark
. For example, you can choose the tango
style for the gitbook
format:
---
output:
bookdown::gitbook:
highlight: tango
---
There is an option includes
that applies to more formats, including HTML and LaTeX. The includes
option allows you to insert arbitrary custom content before and/or after the body of the output. It has three sub-options: in_header
, before_body
, and after_body
. You need to know the basic structure of an HTML or LaTeX document to understand these options. The source of an HTML document looks like this:
<html>
<head>
<!-- head content here, e.g. CSS and JS -->
</head>
<body>
<!-- body content here -->
</body>
</html>
The in_header
option takes a file path and inserts it into the <head>
tag. The before_body
file will be inserted right below the opening <body>
tag, and after_body
is inserted before the closing tag </body>
.
A LaTeX source document has a similar structure:
\documentclass{book}
% LaTeX preamble
% insert in_header here
\begin{document}
% insert before_body here
% body content here
% insert after_body here
\end{document}
The includes
option is very useful and flexible. For HTML output, it means you can insert arbitrary HTML code into the output. For example, when you have LaTeX math expressions rendered via the MathJax library in the HTML output, and want the equation numbers to be displayed on the left (default is on the right), you can create a text file that contains the following code:
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
TeX: { TagSide: "left" }
});
</script>
Let’s assume the file is named mathjax-number.html
, and it is in the root directory of your book (the directory that contains all your Rmd files). You can insert this file into the HTML head via the in_header
option, e.g.,
---
output:
bookdown::gitbook:
includes:
in_header: mathjax-number.html
---
Another example is to enable comments or discussions on your HTML pages. There are several possibilities, such as Disqus (https://disqus.com) or Hypothesis (https://hypothes.is). These services can be easily embedded in your HTML book via the includes
option (see Section 5.5 for details).
Similarly, if you are familiar with LaTeX, you can add arbitrary LaTeX code to the preamble. That means you can use any LaTeX packages and set up any package options for your book. For example, this book used the in_header
option to use a few more LaTeX packages like booktabs (for better-looking tables) and longtable (for tables that span across multiple pages), and applied a fix to an XeLaTeX problem that links on graphics do not work:
\usepackage{booktabs}
\usepackage{longtable}
\ifxetex
\usepackage{letltxmacro}
\setlength{\XeTeXLinkMargin}{1pt}
\LetLtxMacro\SavedIncludeGraphics\includegraphics
\def\includegraphics#1#{% #1 catches optional stuff (star/opt. arg.)
\IncludeGraphicsAux{#1}%
}%
\newcommand*{\IncludeGraphicsAux}[2]{%
\XeTeXLinkBox{%
\SavedIncludeGraphics#1{#2}%
}%
}%
\fi
The above LaTeX code is saved in a file preamble.tex
, and the YAML metadata looks like this:
---
output:
bookdown::pdf_book:
includes:
in_header: preamble.tex
---
2. Theming
Sometimes you may want to change the overall theme of the output, and usually this can be done through the in_header option described in the previous section, or the css option if the output is HTML. Some output formats have their unique themes, such as gitbook, tufte_html_book, and tufte_book2, and you may not want to customize these themes too much. By comparison, the output formats html_book() and pdf_book() are not tied to particular themes and more customizable.
the default style for html_book()
is the Bootstrap style. The Bootstrap style actually has several built-in themes that you can use, including default
, bootstrap
, cerulean
, cosmo
, darkly
, flatly
, journal
, lumen
, paper
, readable
, sandstone
, simplex
, spacelab
, united
, and yeti
. You can set the theme via the theme
option, e.g.,
---
output:
bookdown::html_book:
theme: united
---
If you do not like any of these Bootstrap styles, you can set theme
to null
, and apply your own CSS through the css
or includes
option.
There are many possible LaTeX classes for books, such as memoir (https://www.ctan.org/pkg/memoir), amsbook (https://www.ctan.org/pkg/amsbook), KOMA-Script (https://www.ctan.org/pkg/koma-script) and so on. Here is a brief sample of the YAML metadata specifying the scrbook
class from the KOMA-Script package:
---
documentclass: scrbook
output:
bookdown::pdf_book:
template: null
---
Some publishers (e.g., Springer and Chapman & Hall/CRC) have their own LaTeX style or class files. You may try to change the documentclass
option to use their document classes, although typically it is not as simple as that. You may end up using in_header
, or even design a custom Pandoc LaTeX template to accommodate these document classes.
Note that when you change documentclass
, you are likely to specify an additional Pandoc argument --top-level-division=chapter
so that Pandoc knows the first-level headers should be treated as chapters instead of sections (this is the default when documentclass
is book
), e.g.,
documentclass: krantz
output:
bookdown::pdf_book:
pandoc_args: --top-level-division=chapter
3. Templates
When Pandoc converts Markdown to another output format, it uses a template under the hood. The template is a plain-text file that contains some variables of the form $variable$
. These variables will be replaced by their values generated by Pandoc. Below is a very brief template for HTML output:
<html>
<head>
<title>$title$</title>
</head>
<body>
$body$
</body>
</html>
It has two variables title
and body
. The value of title
comes from the title
field of the YAML metadata, and body
is the HTML code generated from the body of the Markdown input document. For example, suppose we have a Markdown document:
---
title: A Nice Book
---
# Introduction
This is a **nice** book!
If we use the above template to generate an HTML document, its source code will be like this:
<html>
<head>
<title>A Nice Book</title>
</head>
<body>
<h1>Introduction</h1>
<p>This is a <strong>nice</strong> book!</p>
</body>
</html>
The actual HTML, LaTeX, and EPUB templates are more complicated, but the idea is the same. You need to know what variables are available: some variables are built-in Pandoc variables, and some can be either defined by users in the YAML metadata, or passed from the command-line option -V
or --variable
. Some variables only make sense in specific output formats, e.g., the documentclass
variable is only used in LaTeX output. Please see the documentation of Pandoc to learn more about these variables, and you can find all default Pandoc templates in the GitHub repository https://github.com/jgm/pandoc-templates.
4. Configuration
We have mentioned rmd_files
in Section [1.3], and there are more (optional) settings you can configure for a book in _bookdown.yml
[11]:
-
book_filename
: the filename of the main Rmd file, i.e., the Rmd file that is merged from all chapters; by default, it is named_main.Rmd
. -
delete_merged_file
: whether to delete the main Rmd file after the book is successfully rendered. -
before_chapter_script
: one or multiple R scripts to be executed before each chapter, e.g., you may want to clear the workspace before compiling each chapter, in which case you can userm(list = ls(all = TRUE))
in the R script. -
after_chapter_script
: similar tobefore_chapter_script
, and the R script is executed after each chapter. -
edit
: a link that collaborators can click to edit the Rmd source document of the current page; this was designed primarily for GitHub repositories, since it is easy to edit arbitrary plain-text files on GitHub even in other people’s repositories (if you do not have write access to the repository, GitHub will automatically fork it and let you submit a pull request after you finish editing the file). This link should have%s
in it, which will be substituted by the actual Rmd filename for each page. -
history
: similar toedit
, a link to the edit/commit history of the current page. -
view
: similar toedit
, a link to source code of the current page. -
rmd_subdir
: whether to search for book source Rmd files in subdirectories (by default, only the root directory is searched). This may be either a boolean (e.g.true
will search for book source Rmd files in the project directory and all subdirectories) or list of paths if you want to search for book source Rmd files in a subset of subdirectories. -
output_dir
: the output directory of the book (_book
by default); this setting is read and used byrender_book()
. -
clean
: a vector of files and directories to be cleaned by theclean_book()
function.
Here is a sample _bookdown.yml
:
book_filename: "my-book.Rmd"
delete_merged_file: true
before_chapter_script: ["script1.R", "script2.R"]
after_chapter_script: "script3.R"
view: https://github.com/rstudio/bookdown-demo/blob/master/%s
edit: https://github.com/rstudio/bookdown-demo/edit/master/%s
output_dir: "book-output"
clean: ["my-book.bbl", "R-packages.bib"]
5. Internationalization
If the language of your book is not English, you will need to translate certain English words and phrases into your language, such as the words “Figure” and “Table” when figures/tables are automatically numbered in the HTML output. Internationalization may not be an issue for LaTeX output, since some LaTeX packages can automatically translate these terms into the local language, such as the ctexcap package for Chinese.
For non-LaTeX output, you can set the language
field in the configuration file _bookdown.yml
. Currently the default settings are:
language:
label:
fig: 'Figure '
tab: 'Table '
eq: 'Equation '
thm: 'Theorem '
lem: 'Lemma '
cor: 'Corollary '
prp: 'Proposition '
cnj: 'Conjecture '
def: 'Definition '
exm: 'Example '
exr: 'Exercise '
hyp: 'Hypothesis '
proof: 'Proof. '
remark: 'Remark. '
solution: 'Solution. '
ui:
edit: Edit
chapter_name: ''
appendix_name: ''
For example, if you want FIGURE x.x
instead of Figure x.x
, you can change fig
to "FIGURE "
:
language:
label:
fig: "FIGURE "
The fields under ui
are used to specify some terms in the user interface. The edit
field specifies the text associated with the edit
link in _bookdown.yml
(Section 4.4). The fields chapter_name
, appendix_name
, fig
, tab
and eq
can be either a character string to be prepended to chapter (e.g., 'CHAPTER '
) or reference number (e.g., 'FIGURE '
), or an R function that takes a number (chapter or reference number) as the input and returns a string. (e.g., !expr function(i) paste('Chapter', i)
). Here is an example for Hungarian:
language:
label:
fig: !expr function(i) paste(i, 'ábra')
ui:
chapter_name: !expr function(i) paste0(i, '. fejezet')
For chapter_name
and appendix_name
only, if it is a character vector of length 2, the chapter title prefix will be paste0(chapter_name[1], i, chapter_name[2])
, where i
is the chapter number.
There is one caveat when you write in a language that uses multibyte characters, such as Chinese, Japanese, and Korean (CJK): Pandoc cannot generate identifiers from section headings that are pure CJK characters, so you will not be able to cross-reference sections (they do not have labels), unless you manually assign identifiers to them by appending
{#identifier}
to the section heading, whereidentifier
is an identifier of your choice.