-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
Copy path04-customization.Rmd
261 lines (193 loc) · 13.2 KB
/
04-customization.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# Customization
As we mentioned in the very beginning of this book, you are expected to have some basic knowledge about R Markdown, and we have been focusing on introducing the **bookdown** features instead of **rmarkdown**. In fact, R Markdown is highly customizable, and there are many options that you can use to customize the output document. 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.
## YAML options {#yaml-options}
\index{YAML}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 `r knitr::combine_words(rmarkdown:::highlighters(), before = '\x60')`. For example, you can choose the `tango` style for the `gitbook` format:
```yaml
---
output:
bookdown::gitbook:
highlight: tango
---
```
For HTML\index{HTML} output formats, you are most likely to use the `css` option to provide your own CSS\index{CSS} stylesheets to customize the appearance of HTML elements. 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
<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\index{LaTeX} source document has a similar structure:
```latex
\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\index{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:
```html
<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.,
```yaml
---
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 \@ref(collaboration) 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:
```latex
\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:
```yaml
---
output:
bookdown::pdf_book:
includes:
in_header: preamble.tex
---
```
## 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.
As mentioned in Section \@ref(bootstrap-style), the default style for `html_book()` is the Bootstrap style. The Bootstrap style actually has several built-in themes that you can use, including `r knitr::combine_words(rmarkdown:::themes(), before='\x60')`. You can set the theme via the `theme` option, e.g.,
```yaml
---
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.
For `pdf_book()`, besides the `in_header` option mentioned in the previous section, another possibility is to change the document class. 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:
```yaml
---
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.,
```yaml
documentclass: krantz
output:
bookdown::pdf_book:
pandoc_args: --top-level-division=chapter
```
## Templates
When Pandoc converts Markdown to another output format, it uses a template\index{Pandoc 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
<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:
```markdown
---
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
<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.
Note that for HTML output, **bookdown** requires some additional comment tokens in the template, and we have explained them in Section \@ref(bootstrap-style).
## Configuration
We have mentioned `rmd_files` in Section \@ref(usage), and there are more (optional) settings you can configure for a book in `_bookdown.yml`\index{\_bookdown.yml}^[For the [`bs4_book()`](#bs4-book) format, the `edit`, `history`, and `view` fields have no effect and similar configuration can be specified with the [repo](#specifying-the-repository) argument of the output function.]:
- `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 use `rm(list = ls(all = TRUE))` in the R script.
- `after_chapter_script`: similar to `before_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 to `edit`, a link to the edit/commit history of the current page.
- `view`: similar to `edit`, 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.
- `include_md`: include `.md` files in search for book source (by default only `.Rmd` files are included).
- `output_dir`: the output directory of the book (`_book` by default); this setting is read and used by `render_book()`.
- `clean`: a vector of files and directories to be cleaned by the `clean_book()` function.
Here is a sample `_bookdown.yml`:
```yaml
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"]
```
## 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:
```{r echo=FALSE, comment='', results='asis'}
cat('```yaml\n')
cat(yaml::as.yaml(list(language = list(
label = c(bookdown:::label_names, bookdown:::label_names_math2),
ui = bookdown:::ui_names
))
))
cat('```')
```
For example, if you want `FIGURE x.x` instead of `Figure x.x`, you can change `fig` to `"FIGURE "`:
```yaml
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 \@ref(configuration)). 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:
```yaml
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, where `identifier` is an identifier of your choice.