When talking about PDF and printing, we often think of tools like LaTeX and Microsoft Word. When talking about HTML and CSS, we may have never imagined their possible off-screen use such as printing to PDF.
Can we print a book with HTML and CSS? W3C published the first working draft on "Paged Media Properties for CSS(3)", which was last updated in 2013. Although the working draft has been there for nearly two decades, it is still not common to see authors write or print books with HTML and CSS. The main reason is that the W3C specs are still in the draft mode, so most web browsers have not really implemented them.
HTML and CSS still cannot beat other dominating tools like Word or LaTeX when it comes to typesetting content under the constraint of "pages". You may be disappointed by a lot of typesetting details on a paged HTML page. However, HTML and CSS can be extremely powerful and flexible in other aspects, especially when combined with the power of JavaScript. By the way, HTML works almost anywhere because it only requires a web browser.
Although most web browsers have not implemented the W3C specs for Paged Media, a JavaScript polyfill library named "paged.js" is currently being developed to fill the gap. This library is still experimental and has many rough edges, but looks promising enough to us, so we created an R package pagedown [@R-pagedown] based on this JavaScript library to paginate the HTML output of R Markdown documents. You can install the package from Github:
remotes::install_github('rstudio/pagedown')
To learn more about paged.js and CSS for Paged Media, you may check out the documentation of paged.js.
The pagedown package contains output formats for paged HTML documents, letters, resumes, posters, business cards, and so on. Usually there is an R Markdown template for each output format, which you can access from RStudio's menu File -> New File -> R Markdown -> From Template
.
To create a paged HTML document, you can use the output format pagedown::html_paged
, e.g.,
output: pagedown::html_paged: toc: true number_sections: false
This format is based on paged.js. Some other formats in this package are extensions of html_paged
, such as html_letter
and html_resume
. Please note that you need a web server to view the output pages of these formats, because paged.js requires a web server. The web server could be either a local server or a remote one. When you compile an R Markdown document to HTML in RStudio, RStudio will display the HTML page through a local web server, so paged.js will work in RStudio Viewer. However, when you view such pages in a real web browser, you will need a separate web server. The easiest way to preview these HTML pages in a web browser may be through the RStudio addin "Infinite Moon Reader", which requires the xaringan package [@R-xaringan]. Or equivalently, you can call the function xaringan::inf_mr()
. This will launch a local web server via the servr package [@R-servr].
Please note that the layout of the pages is very sensitive to the zoom level in your browser. Elements on a page are often not zoomed strictly linearly, e.g., as you zoom out, certainly elements may start to collapse into each other. The 100% zoom level usually gives the best result (press Ctrl + 0
or Command + 0
). You are strongly recommended to use this level when printing the page to PDF.
We have provided a few default CSS stylesheets in this output format:
output: pagedown::html_paged: css: - default-fonts - default-page - default
To find the actual CSS files behind these names, use pagedown:::list_css()
. For example, default-fonts
means the file resources/css/default-fonts.css
in the installation directory of pagedown. The stylesheet default-fonts
defines the typefaces of the document, default-page
defines some page properties (such as the page size, running headers and footers, and rules for page breaks), and default
defines the style of various elements (such as the table of contents).
If you do not like any of these default stylesheets, you can use a subset of them, or override certain CSS rules. For example, if you do not like the default typeface, you may create a CSS file my-fonts.css
(assuming it is under the same directory of your Rmd file):
body { font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif; }
Then include this CSS file via the css
option:
output: pagedown::html_paged: css: - my-fonts.css - default-page - default
Note that it is possible to use Sass, by installing the Sass package (install.packages("sass")
) and including a file with the .sass
or .scss
extension in the css
option. Moreover, this overriding mechanism also works for other output formats in pagedown.
There are three ways to print to PDF:
with Google Chrome, Microsoft Edge or Chromium using the menu "Print" or by pressing Ctrl + P
(or Command + P
on macOS). Remember to allow background graphics to be printed.
using the function chrome_print()
. Its first argument (input
) accepts a path to a local Rmd or HTML file or an URL. Google Chrome, Microsoft Edge or Chromium must be installed on your system.
in RStudio, adding the following line in the YAML header of your Rmd file:
yaml
knit: pagedown::chrome_print
With this metadata parameter, the behavior of the "Knit" button of RStudio is modified: it produces both the HTML document and the PDF with Chrome. This functionality is suitable for any R Markdown HTML output format and is mainly convenient for small documents like presentations or notes.
If chrome_print()
cannot find Chrome, Edge or Chromium automatically, set the PAGEDOWN_CHROME
environment variable to the path to Chrome, Edge or Chromium executable.
If you want to use chrome_print()
on a server (an RStudio server, for instance), Chromium or Chrome has to be present on this server and available from the PATH
or PAGEDOWN_CHROME
environment variables.
Be sure that the local IP address 127.0.0.1
is referenced in the no_proxy
environment variable. Otherwise the R session won't be able to connect to Chrome.
It is possible to produce a PDF with Chrome using a continuous integration service.
With Travis, activate the Chrome addon by adding theses lines in .travis.yml
file:
addons: chrome: stable
With GitLab CI, you have to use a Docker image with R, Pandoc, pagedown and Chromium or Chrome.^[see an example below] Depending on the base image, you may have to install some extra fonts.
Travis and GitLab CI are container-based environments running as root. As explained in the Travis documentation, you have to pass the --no-sandbox
argument to chrome_print()
(this is required for both Travis and GitLab CI):
chrome_print( ..., extra_args = c("--disable-gpu", "--no-sandbox") )
Since the --no-sandbox
option can lead to major security threats, do not use these CI/CD services to print untrusted web pages.
Here is a minimal Dockerfile using a popular image from the Rocker project which uses RStudio:
FROM rocker/verse RUN curl -LO https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb && \ apt-get update -qq && \ apt-get -y install \ ./google-chrome-stable_current_amd64.deb && \ rm google-chrome-stable_current_amd64.deb RUN install2.r pagedown
If you save this Dockerfile in your current directory, you can build the image with:
docker build myimages/pagedown .
If you intend to use pagedown::chrome_print()
in a container running this image, do not launch the container as usual.
You have to use Jessie Frazelle's seccomp file for Chrome in Docker^[download here https://raw.githubusercontent.com/jessfraz/dotfiles/master/etc/docker/seccomp/chrome.json] as follows:
docker run -e PASSWORD=yourpassword --rm -p 8787:8787 --security-opt seccomp="$(pwd)/chrome.json" myimages/pagedown
With this seccomp file, you do not have to use the "--no-sandbox"
option: this is much more secure!
In rare circumstances and if your document contains a lot of images, chrome_print()
may fail to generate your PDF.
On Linux environments with minimal resources (like a container), you may get this error message:
Chrome crashed. This may be caused by insufficient resources. Please, try to add "--disable-dev-shm-usage" to the `extra_args` argument.
Here, you just have to follow the advice.
If you use an old version of Chrome, you may obtain the following error message:
[error] consume error: websocketpp.processor.4 (A message was too large)
In that case, you must install a more recent version of Chrome.
Currently pagedown has one resume format: pagedown::html_resume
. See https://pagedown.rbind.io/html-resume/ for an example.
knitr::include_graphics('https://user-images.githubusercontent.com/163582/49983676-c940a880-ff29-11e8-9487-3b4c94614fcc.png')
The R Markdown source document should contain two parts titled "Aside" (for the sidebar) and "Main" (for the main body), respectively. Each part can contain any numbers of sections (e.g., education background and working experience). Each section can contain any numbers of subsections, and you can write more content in a subsection.^[In case you are not very familiar with the Markdown syntax for section headings, a series of =
under a heading is equivalent to #
before a heading, and a series of -
is equivalent to ##
. See Pandoc's manual for details: https://pandoc.org/MANUAL.html#headers.] Below is a quick example:
--- title: "Someone's resume" author: Your Name output: pagedown::html_resume --- Aside ==================================== Picture, etc. Contact info ------------------------------------ Email, phone number, ... Skills ------------------------------------ - One - Two - Three Disclaimer ------------------------------------ A footer in the sidebar. Main ==================================== Your Name {#title} ------------------------------------ Arbitrary content. Education {data-icon=graduation-cap} ------------------------------------ ### University One Title Location Year Arbitrary content ### University Two ...
The "Aside" part will be displayed in the right sidebar. This part can contain arbitrary content (not necessarily structured). For example, you can include a picture in the beginning. The "Disclaimer" section will be placed at the bottom of the first page. All icons for this resume template are from Font Awesome. For example, <i class="fa fa-envelope"></i>
will generate an envelope icon. You can look up all icon names on the Font Awesome website if you want to use other icons.
For the "Main" part, all sections must follow a specific structure except the first section. The first section usually shows your name and information that you want to highlight. For the rest of sections, they should contain a title and a number of subsections. You can specify an icon for a section title via the attribute data-icon
, e.g., {data-icon=graduation-cap}
means an icon of a graduation cap (which can be used as a symbol for education). For each subsection, it should contain a title, followed by at least three paragraphs:
The first paragraph is a brief description of the subsection.
The second paragraph is the location.
The third paragraph is the time period. If this subsection has both a starting and ending time, separate them by a dash, e.g., 2014 - 2015
or 2014/07/27 - 2015/07/23
.
The description, location, and time period can each be N/A
if the relevant information is not available.
You can write arbitrary content after the third paragraph (e.g., more paragraphs, bullet lists, and so on). If you want to write content in two columns, you may use a "concise" block, e.g.,
::: concise - Taught R language to beginners. - Wrote Shiny app demos. - Converted statistical tutorials from SPSS to R language. :::
If you want to write a side note, use an "aside" block, e.g.,
Section --------------- ### Subsection Title Location Year More info ::: aside Some notes in the sidebar. :::
knitr::include_graphics('https://user-images.githubusercontent.com/163582/50015125-654ecc00-ff8b-11e8-95be-fc6af8e4a66e.png')
There is a caveat about page breaks. By default, we allow page breaks within a subsection. Sometimes this may lead to odd output like the example in Figure \@ref(fig:break-yes). The first bullet should not be split into two columns, and the rest of bullets should have a larger left margin.
knitr::include_graphics('https://user-images.githubusercontent.com/163582/49983264-520a1500-ff27-11e8-8537-66a642f617c3.png')
If you want to avoid layout problems like this, you may disallow page breaks via CSS:
.blocks { break-inside: avoid; }
However, this may lead to a new issue demonstrated in Figure \@ref(fig:break-no): there may be a large bottom margin on the previous page. At this point, you may start to miss your old friends, Word and LaTeX.
knitr::include_graphics('https://user-images.githubusercontent.com/163582/49983263-520a1500-ff27-11e8-8e71-cbc69ccfbc6e.png')
You can create a poster with the output format pagedown::poster_relaxed
or pagedown::poster_jacobs
. See https://pagedown.rbind.io/poster-relaxed/ and https://pagedown.rbind.io/poster-jacobs/ for examples.
We do not have time to document the poster formats yet, but here is a caveat: the layout of poster sections is hardcoded in CSS styleseets, which means you cannot add/delete sections unless you know CSS (in particular, CSS Grid Layout). If you are interested in learning CSS Grid Layout, you may take a look at the CSS of poster_jacobs
.
To create a simple business card, you can use the pagedown::business_card
format. See https://pagedown.rbind.io/business-card/ for an example.
A single business card can be created with the following R Markdown file (this file contains only a YAML header).
--- name: Jane Doe title: Miss Nobody phone: "+1 123-456-7890" email: "jane.doe@example.com" url: www.example.com address: | 2020 South Street Sunshine, CA 90000 logo: "logo.png" output: pagedown::business_card ---
You can repeat the card on multiple pages using the repeat
variable. The following example produces as many pages as cards (12).
--- name: Jane Doe title: Miss Nobody phone: "+1 123-456-7890" email: "jane.doe@example.com" url: www.example.com address: | 2020 South Street Sunshine, CA 90000 logo: "logo.png" repeat: 12 output: pagedown::business_card ---
In order to print the cards, you may prefer a layout with several cards on the same page: you can adjust the paper size with the paperwidth
and paperheight
variables and define a grid layout with the cols
and rows
variables (you may test some combinations of these parameters to find the most appropriate one).
--- name: Jane Doe title: Miss Nobody phone: "+1 123-456-7890" email: "jane.doe@example.com" url: www.example.com address: | 2020 South Street Sunshine, CA 90000 logo: "logo.png" repeat: 12 paperwidth: 8.5in paperheight: 11in cols: 4 rows: 3 output: pagedown::business_card ---
You also can use markdown to define a card. Be aware to use the slot
attributes as follows.
--- logo: "logo.png" paperwidth: 8.5in paperheight: 11in cols: 4 rows: 3 output: pagedown::business_card --- ::::: {.wrapper data-repeat="12"} [Jane Doe]{slot="name"} [Miss Nobody]{slot="title"} [+1 123-456-7890]{slot="phone"} [jane.doe@example.com]{slot="email"} [www.example.com]{slot="url"} ::: {.address slot="address"} 2020 South Street Sunshine, CA 90000 ::: :::::
You can produce business cards for members of an organization sharing some informations (address, website...).
Common informations are declared as top level variables in the YAML header. Custom cards are defined using the person
variable: each key: value
pair of a person
block overrides the corresponding top level pair.
--- phone: "+1 123-456-7890" url: www.example.com address: | 2020 South Street Sunshine, CA 90000 logo: "logo.png" person: - name: Jane Doe title: Miss Nobody email: "jane.doe@example.com" repeat: 6 - name: John Doe title: Mister Nobody phone: "+1 777-777-7777" # overrides the default phone email: "john.doe@example.com" repeat: 6 paperwidth: 8.5in paperheight: 11in cols: 4 rows: 3 output: pagedown::business_card ---
If you prefer, you can use markdown to create a card as follows.
--- name: Jane Doe title: Miss Nobody phone: "+1 123-456-7890" email: "jane.doe@example.com" url: www.example.com address: | 2020 South Street Sunshine, CA 90000 logo: "logo.png" repeat: 6 paperwidth: 8.5in paperheight: 11in cols: 4 rows: 3 output: pagedown::business_card --- ::: {.wrapper data-repeat="6"} [John Doe]{slot="name"} [Mister Nobody]{slot="title"} [+1 777-777-7777]{slot="phone"} [john.doe@example.com]{slot="email"} [my.domain.com]{slot="url"} :::
You can change the text font with the mainfont
and/or googlefonts
top level YAML variables:
mainfont
will use the local font installed on your computer, e.g.
```yamlname: Jane Doe title: Miss Nobody phone: "+1 123-456-7890" email: "jane.doe@example.com" url: www.example.com address: | 2020 South Street Sunshine, CA 90000 logo: "logo.png" mainfont: Arial output: pagedown::business_card
```
googlefonts
to use fonts from https://fonts.google.com, e.g.
```yamlname: Jane Doe title: Miss Nobody phone: "+1 123-456-7890" email: "jane.doe@example.com" url: www.example.com address: | 2020 South Street Sunshine, CA 90000 logo: "logo.png" googlefonts: ["Roboto Condensed", "Raleway"] output: pagedown::business_card
```
You can modify the card size with the cardwidth
and cardheight
variables. You can get a landscape card with:
--- name: Jane Doe title: Miss Nobody phone: "+1 123-456-7890" email: "jane.doe@example.com" url: www.example.com address: | 2020 South Street Sunshine, CA 90000 logo: "logo.png" cardwidth: 3.5in cardheight: 2in output: pagedown::business_card ---
If you render this card, you will see that the default style does not suit well with a landscape card. Read the next section to find an example of a landscape card with a better style.
Finally, you can modify the style of the card using CSS rules.
The markup of a card can be represented as follows^[This is technically incorrect since the card template use a shadow DOM.]:
<div class="wrapper" data-repeat="1"> <img class="logo" src="logo.png" alt="Logo" /> <div class="me"> <div class="name"><span>Jane Doe</span></div> <div class="title"><span>Miss Nobody</span></div> <div class="coordinates"> <p class="phone"><span>+1 123-456-7890</span></p> <p class="contact-email"><span>jane.doe@example.com</span></p> <p class="website"><span>www.example.com</span></p> <div class="address">2020 South Street Sunshine, CA 90000</div> </div> </div> </div>
You can use these built-in classes to style your card with CSS.
A landscape card could be styled like this:
--- name: Jane Doe title: Miss Nobody phone: "+1 123-456-7890" email: "jane.doe@example.com" url: www.example.com address: | 2020 South Street Sunshine, CA 90000 logo: "logo.png" cardwidth: 3.5in cardheight: 2in output: pagedown::business_card --- `r ''````{css} .logo { display: block; height: 20%; margin-right: .3in; padding: .3in 0 0; float: right; } .name { margin-top: .1in; } ```
You can write a letter with the pagedown::html_letter
format. See https://pagedown.rbind.io/html-letter/ for an example.
You can write a thesis with the pagedown::thesis_paged
format created by Brent
Thorne. See https://pagedown.rbind.io/thesis-paged/ for an example.
You can write an article for the Journal of Statistical Sofware. See https://pagedown.rbind.io/jss-paged/ for an example.
Lists of tables and/or figures can be inserted in the document using the lot
and lof
variables in the YAML metadata. You also can customize their titles with the lot-title
and lof-title
variables. By default, theses lists are referenced in the table of contents, if any. You can use the lot-unlisted
and lof-unlisted
options to remove them. For instance:
--- title: "A document with lists of tables and figures" output: pagedown::html_paged toc-title: Contents lot: true # default: "List of Tables" lot-title: "Tables" # uncomment to remove from the TOC: #lot-unlisted: true lof: true # default: "List of Figures" lof-title: "Figures" # uncomment to remove from the TOC: #lof-unlisted: true ---
A list of abbreviations is automatically built if the document contains at least one HTML abbr
element.
For instance, if the R Markdown document contains <abbr title="Cascading Style Sheets">CSS</abbr>
, a list of abbreviations is built with the CSS definition.
:::{#loa-example style="background-color:#f9f9f9;"}
List of abbreviations example
CSS : Cascading Style Sheets :::
The title of this list of abbreviations can be customized using the loa-title
field in the YAML header.
By default, the front matter is composed of the cover, the table of contents and the lists of figures, tables and abbreviations if any. The only difference between the front matter pages and the main content pages is the style of the page numbers.
You can add extra sections to the front matter using the front-matter
class. For instance, if you want to add a preface to the front matter, you need to write:
# Preface {.front-matter .unnumbered}
The word "Chapter " can be prepended to chapter numbers in chapter titles using the chapter
class :
# A prefixed chapter {.chapter}
The chapter title prefix can be customized using the chapter_name
field in the YAML header or in _bookdown.yml
file^[see https://bookdown.org/yihui/bookdown/internationalization.html]
When defined in the YAML header the chapter_name
field is parsed by Pandoc. Therefore, special characters like spaces have to be escaped^[see https://pandoc.org/MANUAL#backslash-escapes]. For instance, if you want to use 'CHAPTER '
as a chapter title prefix, you have to write:
--- title: "Custom chapter title prefix" output: pagedown::html_paged chapter_name: "CHAPTER\\ " --- # A chapter with a custom prefix {.chapter}
A suffix string can be added after the chapter number. For instance, to add a dot (.
) after the chapter number, use the following value for the chapter_name
field:
--- title: "Custom chapter title prefix" output: pagedown::html_paged chapter_name: ["CHAPTER\\ ", "."] --- # A chapter with a custom prefix {.chapter}
If defined in _bookdown.yml
file, the chapter_name
field will override a chapter_name
field declared in the YAML header.\
Note that contrary to the bookdown HTML formats, a custom function is not allowed as a value for the chapter_name
field.
In Markdown, the usual ways to insert links are automatic and inline links.
Automatic links are created using pointy brackets, e.g., <https://bookdown.org>
. The full URL is then inserted in the final document https://bookdown.org. This is convenient for a short and meaningful URL.
Inline links are useful when you do not want to show the full URL but an alternative text (because URLs are usually long and ugly). In Markdown, the link text is inserted in square brackets and the URL in parentheses, e.g. [bookdown website](https://bookdown.org)
. On a website, the URL is hidden and replaced by the link text: bookdown website. The user can interactively access the URL by clicking on the link.
When printing a document, we lose interactivity. So we need to show the hidden URLs. By default, the html_paged
format adds the URLs after the link text in parentheses, for instance [bookdown website](https://bookdown.org)
is rendered as bookdown website.
You also can use the links-to-footnotes
top-level YAML parameter: it transforms all the URLs to footnotes. You will get the same result as bookdown website^[https://bookdown.org]
. To activate the links-to-footnotes
option, insert links-to-footnotes: true
in the YAML header. For instance:
--- title: "A paged HTML document" output: pagedown::html_paged links-to-footnotes: true ---
The default behavior of pagedown is to render notes as endnotes because Paged.js does not natively support footnotes for now. However, we introduced an experimental support for footnotes. You can test it by including paged-footnotes: true
in the YAML header of your document. Please, note that the paged-footnotes
option only supports inline content^[see https://github.com/rstudio/pagedown/issues/156]. If you get any trouble with this experimental feature, please open an issue in the pagedown repository on GitHub.
If you need to override the default footnotes style, you should use an important
rule on elements of class footnote
. For example,
.footnote { font-size: 20px !important; color: red !important; }
Sometimes a section title may be too long to fit the header or footer area. In this case, you can specify a shorter title for the running headers/footers via the attribute data-short-title
after a title, e.g.,
## The actual long long long title {data-short-title="An alternative title"}
Covers images can be added using the front_cover
and back_cover
parameters of pagedown::html_paged()
. You can pass any path to a file or an url.
--- output: pagedown::html_paged: front_cover: !expr system.file("img", "Rlogo.png", package="png") back_cover: https://www.r-project.org/Rlogo.png --- # Content
Several paths or links can be passed to the front_cover
and back_cover
parameters. For each image declared in the front_cover
or back_cover
parameter, a CSS variable is created: --front-cover
, --back-cover
, --front-cover-2
, --back-cover-2
, etc.
They can be used as value for the background-image
CSS property:
@page chapter:first { background-image: var(--front-cover-2); }
You also can add textual content on the front and back covers using two special divs of classes front-cover
and back-cover
:
--- output: pagedown::html_paged: front_cover: !expr system.file("img", "Rlogo.png", package="png") back_cover: https://www.r-project.org/Rlogo.png --- :::front-cover # My great book about ::: :::back-cover ### Written with ::: # Content
If the background properties of the default template does not suit your needs, here is a small hack to modify them.
The following lines are used to position the pagedown hex logo on the front page of the current document:
/* position the hex logo on the first page */ .pagedjs_page.pagedjs_first_page { background-size: 40%; background-position: center 80%; }
Internal links will be followed by page numbers by default. For example, you can refer to another section using either [Section Title]
or [Link Text](#section-id)
(where section-id
is the ID of the section header).
Do you still remember Paged.js that we mentioned earlier?
For templates built on top of html_paged
, line numbering can be added using the top-level YAML parameter number-lines
. For example:
--- output: pagedown::thesis_paged number-lines: true ---
The line numbers can be reset on each page using the reset-page
option:
--- output: pagedown::thesis_paged number-lines: reset-page: true ---
You also can select the HTML elements by passing a CSS selector to the selector
parameter. To number the lines of all the paragraphs and headers, you need to write:
--- output: pagedown::thesis_paged number-lines: selector: "p, h1, h2, h3, h4, h5, h6" ---
The default CSS selector is ".level1:not(.front-matter) h1, .level1 h2, .level1 h3, .level1 p"
. Line numbering is deactivated for display math environments.
Be aware that the value "normal"
of the CSS line-height
property is not supported: elements with a normal line height are not numbered. Since "normal"
is the default value for the line-height
property, the CSS stylesheets must define a different value. If your template relies on custom CSS files, you can add for example:
html { line-height: 1.3; }
You can modify the horizontal positioning and the font size of the lines numbers using two CSS variables: --line-numbers-padding-right
(default value 10px
) and --line-numbers-font-size
(default value 8pt
). For further customisation, you can modify the style of the elements of class maintextlinenumbers
. Here is an example:
.maintextlinenumbers { --line-numbers-padding-right: 25px; --line-numbers-font-size: 10pt; font-weight: bold; font-family: monospace; }
Please note that this feature is sensitive to elements which break the vertical rythm of the text like inline maths.
There are two ways to force a page break:
with the \newpage
$\LaTeX$ command (\pagebreak
also works)
using one of these two CSS classes: page-break-before
or page-break-after
\
For example, to force a page break before a given section, use:
markdown
### New section {.page-break-before}
The following test comes from http://www.cs.toronto.edu/~yujiali/test/mathjax.html.
Some RBM stuff:
$$ E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j $$
Multiline equations:
$$ \begin{align} p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \ p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right) \end{align} $$
Here is an example of an inline expression: $p(x|y) = \frac{p(y|x)p(x)}{p(y)}$.
Table \@ref(tab:test-table):
knitr::kable(head(iris[, -5]), caption = 'An example table.')
knitr::write_bib(c(.packages(), 'pagedown', 'xaringan', 'servr'), 'index.bib')
{js, echo=FALSE}
// insert a soft break to avoid an infinite loop with FF
// this is because FF handles lists differently
document.querySelector('#TOC h1').insertAdjacentHTML('afterend', '<wbr>');
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.