---
title: Authoring HTML Articles with the markdown Package
author: Yihui Xie
date: "`r Sys.Date()`"
output:
  markdown::html_format:
    meta:
      js: ["@npm/@xiee/utils/js/sidenotes.min.js,appendix.min.js,heading-anchor.min.js,right-quote.min.js"]
      css: [default, "@npm/@xiee/utils/css/article.min.css,heading-anchor.min.css"]
    options:
      toc: true
      number_sections: true
---

```{=html}
<!--
%\VignetteEngine{knitr::knitr}
%\VignetteIndexEntry{Authoring HTML Articles with the markdown Package}
%\VignetteEncoding{UTF-8}
-->
```
```{r, include=FALSE}
options(width = 80)
knitr::opts_chunk$set(comment = '#>')
```

The R package [**markdown**](https://cran.r-project.org/package=markdown) can be
used to generate lightweight HTML documents with minimal default CSS styles. If
you are not familiar with this package, you may read [the
introduction](intro.html)[^1] first to learn the basics. The HTML format is
highly customizable if you know some CSS and JavaScript. This article
demonstrates an HTML article format by introducing external CSS and JavaScript
to the base format.

[^1]: The package vignette: `vignette("intro", package = "markdown")`

## Get started

To write an HTML article, you may use the following metadata variables (`css`
and `js`):[^2]

[^2]: If you are curious about what the leading `@` characters mean in the
    values, please read the section "YAML metadata" in the introduction vignette
    of this package.

``` yaml
output:
  markdown::html_format:
    meta:
      css: ["default", "@xiee/utils/css/article.min.css"]
      js: ["@xiee/utils/js/sidenotes.min.js,appendix.min.js"]
```

The `default` CSS is the default style provided by this package. Beyond that,
only the CSS file `article.css`[^3] is required.

[^3]: The actual file extension is `.min.css`, which means a *minified* version
    of the `.css`. The CSS is minified to make it load faster. If you do not
    care, you can definitely use the `.css` extension. The same thing applies to
    `.min.js` vs `.js`.

-   The JS file `sitenotes.js` is required only if you want to place certain
    elements on the left or right side, such as the table of contents (TOC),
    footnotes, and sidenotes.

-   The JS file `appendix.js` is required only if you have an appendix in the
    article.

Since we are going to demonstrate all elements, we have loaded both JS files for
this document.

## The overall style

The maximum width of the article body is 800px. For larger screens, this means
there will be extra space in the left/right margin, where we can place auxiliary
information, such as the TOC and footnotes. On smaller screens, the side content
will be collapsed into the body.

The article frontmatter, body, and optionally the appendix are placed in
separate boxes.

The default typeface is sans-serif, and you can customize it by supplying an
external CSS file (via the `css` meta variable) or just embedding CSS in the
document body, e.g.,

```{css}
body {
  font-family: Palatino, "Book Antiqua", Georgia, serif;
  font-size: 1em;
}
```

## Side elements

The TOC and footnotes are automatically placed in the margin if space permits.
You can also write arbitrary content in the margin via a fenced `Div`.

### The TOC

The TOC is sticky on the left side as you scroll down the article. If you do not
like this behavior, you may cancel it via CSS:

``` css
#TOC {
  top: unset;
}
```

### Footnotes

Footnotes are moved to the right side. When you move your cursor over a footnote
number in the body, the footnote will be moved next to your cursor. This can be
convenient when you have multiple footnotes on a line, since you do not need to
look for a specific footnote in the margin.

### Arbitrary sidenotes

You can write anything in the margin by using a fenced `Div` with the classes
`.side` and `.side-left` or `.side-right`.

::: {.side .side-left}
**Notice**

Here is a note on the left side. Anything permitted by law is permitted here.
Math? No problem!

$$e^{i\theta}=\sin{\theta}+i\cos{\theta}$$

When you have this sidenote "hammer", I'm sure you will hit a lot of nails into
the margin, even if you do not have to.
:::

::: {.side .side-right}
And here is a note on the right side. Seriously, we should let
[commonmark](https://commonmark.org)'s authors know that fenced `Div`s really
deserve first-class support! They can make Markdown infinitely customizable.
:::

``` markdown
::: {.side .side-left}
**Anything** on the left.
:::
```

``` markdown
::: {.side .side-right}
_Anything_ on the right.
:::
```

## Body elements

Inside the article body, you can write a few special elements.

### Full-width elements

When an element is wider than the article body, you can show it in its full
width by enclosing the element in a fenced `Div` with the class `.fullwidth`,
e.g.,

``` markdown
::: {.fullwidth}
![text](path/to/image)
:::
```

::: fullwidth
![Sunspots](https://prose.yihui.org/post/2020/11/10/r-markdown-demo/index_files/figure-html/sunspots-1.svg)
:::

If you use R Markdown, you can generate a wide plot or table from an R code
chunk, e.g.,

````{verbatim, lang='markdown'}
::: {.fullwidth}
```{r}
#| sunspots, echo=FALSE, fig.dim=c(14, 4),
#| fig.cap='Monthly mean relative sunspot numbers from 1749 to 1983.'
par(mar = c(4, 4, .1, .1), bg = 'lightgoldenrodyellow', fg = 'red', las = 1)
plot(sunspots, col = 'red', panel.first = grid())
```
:::
````

### Left/right quotes

::: quote-right
> Whenever you find that you are on the side of the majority, it is time to
> pause and reflect.
>
> ---[Mark Twain](http://www.quotationspage.com/quotes/Mark_Twain/81)
:::

Sometimes you may want to add a quote but do not want it to take the full width
in the body. You may use a fenced `Div` with the class `.quote-left` or
`.quote-right`.

Despite the class names, the content does not have to be a quote. If you do want
a quote, just use the blockquote syntax `>`, e.g.,

``` markdown
::: {.quote-right}
> This is a boring quote.
>
> ---Someone
:::
```

### Margin embedding

::: embed-right
```{r, echo=FALSE}
knitr::kable(head(mtcars, 4))
```
:::

You can embed elements on the left or right margin using a fenced `Div` with the
class `.embed-left` or `.embed-right`. These elements will float to the left or
right and exceed the margin by about 200px, which can save some space in the
article body. You can use the extra space to explain the embedded element with
text.

We have embedded a table of the first 4 rows of the `mtcars` data on the right
margin. The table was generated via `knitr::kable()`.

## Appendix {.appendix}

The appendix starts with a heading that has the attribute `.appendix`, e.g.,
`## Appendix {.appendix}`.

## Technical notes

It's quite simple to move an element into the margin using CSS. For example, the
`.side-right` class in this article is roughly defined as:

``` css
.side-right {
  width: 200px;
  float: right;
  margin-right: -200px
}
```

That basically means the width of the element is 200px and it floats to the
right. Now its right side will touch the right margin of its parent element (the
article body). What we need to do next is move it further to the right by 200px
(i.e., its width), which is done by the `-200px` right margin. Remember, a
positive right margin in CSS moves an element to the left, and a negative right
margin moves it to the right.
