A note from the authors: Some of the information and instructions in this book are now out of date because of changes to Hugo and the blogdown package. If you have suggestions for improving this book, please file an issue in our GitHub repository. Thanks for your patience while we work to update the book, and please stay tuned for the revised version!

In the meantime, you can find an introduction to the changes and new features in the v1.0 release blog post and this "Up & running with blogdown in 2021" blog post.

— Yihui, Amber, & Alison

1.6 R Markdown vs. Markdown

If you are not familiar with R Markdown, please see Appendix A for a quick tutorial. When you create a new post, you have to decide whether you want to use R Markdown or plain Markdown, as you can see from Figure 1.7.

Table 1.3 summarizes the main differences among the three file extensions. Note that .Rmarkdown is always rendered to Markdown (.markdown), yet .Rmd may be rendered to HTML or Markdown, depending on the global option blogdown.method = "html" or "markdown".

TABLE 1.3: Differences among the three document formats.
Feature .Rmd .Rmarkdown .md/.markdown
Run R code yes yes no
Bibliography yes yes no
Cross references yes yes no
LaTeX math yes maybe maybe
HTML widgets yes yes no

Basically, you cannot execute any R code in a plain Markdown document (.md or .markdown), whereas in an R Markdown document (.Rmd or .Rmarkdown), you can embed R code chunks (```{r}). However, you can still embed R code in plain Markdown using the syntax for fenced code blocks ```r (note there are no curly braces {}). Such code blocks will not be executed and may be suitable for pure demonstration purposes. Below is an example of an R code chunk in R Markdown:

```{r cool-plot, fig.cap='A cool plot.'}
plot(cars, pch = 20)  # not really cool

And here is an example of an R code block in plain Markdown:

1 + 1  # not executed

A plain Markdown post is directly rendered to HTML through Goldmark (a Markdown renderer written in the Go language and adopted by Hugo). An R Markdown post is first compiled to Markdown through the R packages rmarkdown and bookdown, which means you can use most features of bookdown’s Markdown extensions in blogdown. Then the Markdown post can be rendered to HTML by either Goldmark or Pandoc. For the latter case, you can also use richer features in Pandoc’s Markdown (see Section 1.6.2 for more information).

1.6.1 Basic features of R Markdown

If you use R Markdown (Allaire et al. 2023) with blogdown, we recommend that you read the documentation of Pandoc and bookdown at least once to know all the possible features. We will not repeat the details in this book, but list the features briefly below, which are also demonstrated on the example website https://blogdown-demo.rbind.io.

  • Inline formatting: _italic_ / **bold** text and `inline code`.

  • Inline elements: subscripts (e.g., H~2~0) and superscripts (e.g., R^2^); links ([text](url)) and images ![title](url).

  • Footnotes: text[^1]; [^1]: your footnote content. Note that the inline footnote text^[footnote] is no longer supported by Hugo. As Hugo switched the default Markdown renderer to Goldmark since v0.60.0, which does not support inline footnotes.

  • Block-level elements: paragraphs; numbered and unnumbered section headers; ordered and unordered lists; block quotations; fenced code blocks; tables; horizontal rules.

  • Math expressions and equations.

  • Theorems and proofs.

  • R code blocks that can be used to produce text output (including tables) and graphics. Note that equations, theorems, tables, and figures can be numbered and cross-referenced.

  • Citations and bibliography.

  • HTML widgets, and Shiny apps embedded via <iframe>.

If you do not need the extra features in Table 1.3, you can just write a plain Markdown post (.md), otherwise you need to use R Markdown. As we mentioned before, there are two possible formats of R Markdown: one with the file extension .Rmd, and one with .Rmarkdown. The latter is always rendered to Markdown, which will be processed by Hugo’s Markdown renderer (Goldmark). The former can be rendered to either HTML or Markdown, which we will explain in the next section.

1.6.2 Render R Markdown to Markdown or HTML?

If you use the file extension .Rmd for a post, you need to make a decision on whether to render it to .html or .md. Essentially, that means whether you want to use Pandoc or Goldmark to render the post. To render to .html via Pandoc, you need to set the global option options(blogdown.method = "html"). To render to .md, you can set options(blogdown.method = "markdown").

In general, Pandoc’s Markdown features are richer than Goldmark’s. For example, Goldmark does not support LaTeX math and Pandoc does. We have added the MathJax support to the default theme (hugo-lithium) in blogdown to render LaTeX math on HTML pages, but there is a caveat for plain Markdown posts: you have to include inline math expressions in a pair of backticks `$math$`, e.g., `$S_n = \sum_{i=1}^n X_i$`. Similarly, math expressions of the display style have to be written in `$$math$$`. For .Rmd posts to be rendered to .html, you can use $math$ for inline math expressions, and $$math$$ for display-style expressions.11

The main disadvantages of rendering .Rmd to .html are:

  1. You may sacrifice some speed in rendering the website, but this may not be noticeable due to a caching mechanism in blogdown (more on this in Section D.3). Hugo is very fast when processing plain Markdown files, and typically it should take less than one second to render a few hundred posts.

  2. You will have some intermediate HTML files in the source directory of your website, because blogdown has to call rmarkdown to pre-render *.Rmd files into *.html. You will also have intermediate folders for figures (*_files/) and cache (*_cache/) if you have plot output in R code chunks or have enabled knitr’s caching. Unless you care a lot about the “cleanness” of the source repository of your website (especially when you use a version control tool like GIT), these intermediate files should not matter.

There are two major limitations of rendering .Rmd to .md (or .Rmarkdown to .markdown):

  • You cannot use Markdown features only supported by Pandoc, such as fenced Divs.

  • Math expressions only work if you apply the JavaScript solution mentioned in Section B.3.

The main advantage of rendering posts to Markdown instead of HTML is that the output files are cleaner because they are Markdown files (by comparison, HTML files often contain a lot of HTML tags, which are hard for humans to read). It can be easier for you to read the output of your posts without looking at the actual web pages rendered. This can be particularly helpful when reviewing GitHub pull requests. Note that numbered tables, figures, equations, and theorems are also supported. You cannot directly use Markdown syntax in table or figure captions, but you can use text references as a workaround (see bookdown’s documentation).

1.6.3 Customize the R Markdown output format

For any R Markdown documents (not specific to blogdown), you have to specify an output format. There are many possible output formats in the rmarkdown package (such as html_document and pdf_document) and other extension packages (such as tufte::tufte_html and bookdown::gitbook). Of course, the output format for websites should be HTML. We have provided an output format function blogdown::html_page in blogdown, and all R Markdown files are rendered using this format. It is based on the output format bookdown::html_document2, which means it has inherited a lot of features from bookdown in addition to features in Pandoc. For example, you can number and cross-reference math equations, figures, tables, and theorems, etc. See Chapter 2 of the bookdown book (Xie 2016) for more details on the syntax.

Note that the output format bookdown::html_document2 in turn inherits from rmarkdown::html_document, so you need to see the help page ?rmarkdown::html_document for all possible options for the format blogdown::html_page. If you want to change the default values of the options of this output format, you can add an output field to your YAML metadata. For example, we can add a table of contents to a page, set the figure width to be 6 inches, and use the svg device for plots by setting these options in YAML:

title: "My Awesome Post"
author: "John Doe"
date: "2017-02-14"
    toc: true
    fig_width: 6
    dev: "svg"

To set options for blogdown::html_page() globally (i.e., apply certain options to all Rmd files), you can create a _output.yml file under the root directory of your website. This YAML file should contain the output format directly (do not put the output format under the output option), e.g.,

  toc: true
  fig_width: 6
  dev: "svg"

At the moment, not all features of rmarkdown::html_document are supported in blogdown, such as df_print, code_folding, code_download, and so on.

If your code chunk has graphics output, we recommend that you avoid special characters like spaces in the chunk label. Ideally, you should only use alphanumeric characters and dashes, e.g., ```{r, my-label} instead of ```{r, my label}.

It is not recommended to change the knitr chunk options fig.path or cache.path in R Markdown. The default values of these options work best with blogdown. Please read Section D.5 to know the technical reasons if you prefer.

If you are working on an R Markdown post, but do not want blogdown to compile it, you can temporarily change its filename extension from .Rmd to another unknown extension such as .Rmkd.


Allaire, JJ, Yihui Xie, Jonathan McPherson, Javier Luraschi, Kevin Ushey, Aron Atkins, Hadley Wickham, Joe Cheng, Winston Chang, and Richard Iannone. 2023. Rmarkdown: Dynamic Documents for r. https://CRAN.R-project.org/package=rmarkdown.
Xie, Yihui. 2016. Bookdown: Authoring Books and Technical Documents with R Markdown. Boca Raton, Florida: Chapman; Hall/CRC. https://github.com/rstudio/bookdown.

  1. The reason that we need the backticks for plain Markdown documents is that we have to prevent the LaTeX code from being interpreted as Markdown by Blackfriday. Backticks will make sure the inner content is not translated as Markdown to HTML, e.g., `$$x *y* z$$` will be converted to <code>$$x *y* z$$</code>. Without the backticks, it will be converted to $$x <em>y</em> z$$, which is not a valid LaTeX math expression for MathJax. Similar issues can arise when you have other special characters like underscores in your math expressions.↩︎