001. Area of a circle (source: 001-minimal.Rmd) ⏵
---
title: Area of a circle
---
Define the radius as `x`:
```{r}
x = 1 + 1
```
When the radius is `{r} x`, the area will be `{r} pi * x^2`.
002. The attr.*
chunk options (source: 002-attr-options.Rmd) ⏵
---
title: The `attr.*` chunk options
---
1. Add an ID `#example-a` to the whole chunk.
2. Add line numbers to source blocks via the `.line-numbers` class.
3. Add the class `.round` to the first plot and set its width to 400px.
4. Add two classes `.dark` and `.img-center` to the second plot.
```{r}
#| example-a,
#| attr.chunk = '#example-a',
#| attr.source = '.line-numbers',
#| attr.plot = c('.round width="400"', '.dark .img-center'),
#| fig.alt = c('A scatterplot of rnorm(100) numbers.',
#| 'A sunflower plot of iris.')
plot(rnorm(100), rnorm(100))
i34 = iris[, 3:4]
smoothScatter(i34)
sunflowerplot(i34, add = TRUE)
```
Define CSS rules for the classes in the `#example-a` chunk:
```{css}
#example-a {
.round { border: solid 1px; border-radius: 50%; }
.dark { filter: invert(1); }
.img-center { display: block; margin: auto; }
}
```
003. Create a callout via the option attr.chunk
(source: 003-attr-callout.Rmd) ⏵
---
title: Create a callout via the option `attr.chunk`
output:
html:
meta:
css: ["@default", "@callout"]
js: ["@callout"]
---
If you use the class name `.callout-*` on a chunk, you can turn it into a callout, e.g.,
```{r}
#| attr.chunk = '.callout-example'
1 + 1
```
Remember to load the `callout` CSS/JS assets in YAML.
004. Caption position (source: 004-caption-position.Rmd) ⏵
---
title: Caption position
---
## Default caption positions
```{r, fig-bottom, fig.cap = 'Bottom figure caption.'}
plot(cars)
```
```{r, tab-top, tab.cap = 'Top table caption.'}
cars
```
## Change the positions
```{r, fig-top, fig.cap = 'Top figure caption.', cap.pos = 'top'}
plot(cars)
```
```{r, tab-bottom, tab.cap = 'Bottom table caption.', cap.pos = 'bottom'}
cars
```
005. The code
option (source: 005-option-code.Rmd) ⏵
---
title: The `code` option
---
Define a code template `tpl`:
```{r}
tpl = 'lm(mpg ~ %s, data = mtcars) |> summary() |> coef()'
x_vars = names(mtcars)[2:4]
```
We run regressions on three variables one by one:
<!-- ... -->
```{r, code = sprintf(tpl, x_vars)}
```
006. Collapse source code and text output (source: 006-option-collapse.Rmd) ⏵
---
title: Collapse source code and text output
---
By default, the source and output are in separate blocks:
```{r}
x = 1 + 1
x
x + 2
```
Set `collapse = TRUE` to collapse them:
```{r, collapse = TRUE}
x = 1 + 1
x
x + 100
```
007. The comment
option (source: 007-option-comment.Rmd) ⏵
---
title: The `comment` option
---
Use `#-> ` to comment out text output:
```{r, comment = '#-> ', print = NA}
matrix(1:12, 3)
```
Do not comment out text output:
```{r, comment = '', print = NA}
matrix(1:12, 3)
```
008. The graphics device (source: 008-option-device.Rmd) ⏵
---
title: The graphics device
---
The default (png) device with a higher resolution:
```{r}
#| chunk-a, dev.args = list(res = 96),
#| fig.alt = 'png with a resolution of 96 ppi'
plot(cars)
```
The `svg` device with a background color:
```{r}
#| chunk-b, dev = 'svg', dev.args = list(bg = 'lightyellow'),
#| fig.alt = 'svg with a lightyellow background'
plot(cars)
```
009. Decorating figures (source: 009-option-figure-decoration.Rmd) ⏵
---
title: Decorating figures
output:
html:
meta:
css: ["@default", "@article"]
js: ["@sidenotes"]
---
Place two plots side by side via the `width` attribute:
```{r}
#| chunk-a, attr.plot = 'width="45%"',
#| fig.alt = c('a histogram', 'a sunflower plot'),
#| fig.cap = 'Exploring the faithful dataset.',
hist(faithful$eruptions, main = '', border = 'white')
sunflowerplot(faithful)
```
A full-width figure (requires the `@article` CSS):
```{r}
#| chunk-b, fig.dim = c(14, 4), fig.env = '.figure .fullwidth',
#| fig.cap = 'Monthly mean relative sunspot numbers from 1749 to 1983.'
par(mar = c(4, 4, .1, .1), bg = 'lightyellow', fg = 'red', las = 1)
plot(sunspots, col = 'red')
grid()
```
Feel free to experiment with other class names provided by the `@article` CSS, such as `.side .side-right` or `.embed-right` in addition to `.fullwidth`.
010. Plot files (source: 010-option-plot-files.Rmd) ⏵
---
title: Plot files
---
The default extension for the `jpeg()` device is `jpeg`, and you can change it to `.jpg` if desired:
```{r, chunk-a, dev = 'jpeg', fig.ext = '.jpg'}
plot(cars)
```
Set the plot size via `fig.dim`:
```{r, chunk-b, fig.dim = c(5, 4)}
plot(cars)
```
Write plot files to a different folder:
```{r, chunk-c, fig.path = 'figures/'}
plot(cars)
```
011. Shared chunk labels (source: 011-option-label.Rmd) ⏵
---
title: Shared chunk labels
---
```{r, chunk-a}
message("This chunk's label is chunk-a")
```
Repeat `chunk-a` but suppress the message:
```{r, chunk-a, message=FALSE}
```
012. Custom execution order (source: 012-option-order.Rmd) ⏵
---
title: Custom execution order
abstract: "We analyzed `{r, order = N + 1} nrow(x)` `{r} n_cyl`-cylinder cars, with an average MPG of `{r} m`."
---
Subset the data:
```{r}
n_cyl = 8
x = subset(mtcars, cyl == n_cyl)
```
The average MPG `{r} m` is calculated from:
```{r, order = i - 1.5}
m = mean(x$mpg)
```
013. Print objects (source: 013-option-print.Rmd) ⏵
---
title: Print objects
---
Print objects with `base::print()`, and use different arguments for different objects.
```{r}
#| print = NA,
#| print.args = list(table = list(zero.print = '.'),
#| factor = list(quote = TRUE, max.levels = 3))
X = c('a', 'b', 'c', 'c', 'c', 'a')
Y = factor(c('A', 'B', 'C', 'C', 'D', 'E'))
Y # factor
table(X, Y) # table
```
014. 014-option-purl.html (source: 014-option-purl.Rmd) ⏵
This code chunk is not important for the `fiss()` output.
```{r, setup, purl = FALSE}
litedown::reactor(fig.height = 5)
```
This code chunk will be included in the script.
```{r}
if (TRUE) {
x = 1 + 1
}
```
015. Fill out references in code chunks (source: 015-fill-chunk.Rmd) ⏵
---
title: "Fill out references in code chunks"
---
Define `chunk-a` that includes a reference to `chunk-b`:
```{r, chunk-a, eval = FALSE, echo = FALSE}
x = runif(1); y = runif(1)
`<chunk-b>`
```
```{r, chunk-b, eval = FALSE, echo = FALSE}
if (x^2 + y^2 <= 1) {
n = n + 1
}
```
```{r, echo = FALSE}
N = 10000
```
<!-- ... -->
Embed `chunk-a` in a function body:
```{r}
f = function() {
n = 0
for (i in 1:`{N}`) {
`<chunk-a>`
}
n/`{N}` * 4
}
abs(f() - pi) <= 0.1 # is it close to pi?
```
We can generate code dynamically in any code chunk, not limited to R chunks, e.g.,
```{js, eval = FALSE, fill = xfun::tojson}
const data = `{ iris[1:5, 1:2] }`;
Object.keys(data); // column names
```
016. Text output (source: 016-option-results.Rmd) ⏵
---
title: Text output
---
Default verbatim output:
```{r, test-out}
cat('Hello _world_!\n')
```
Hide output:
```{r, test-out, results = FALSE}
```
Output as is:
```{r, test-out, results = 'asis'}
```
017. Blank lines in source code (source: 017-option-strip-white.Rmd) ⏵
---
title: Blank lines in source code
---
Keep blank lines at the beginning/end:
<!-- ... -->
```{r, strip.white = FALSE}
# a blank line above
1 + 1
# and a blank line below
```
018. A simple table (source: 018-option-table.Rmd) ⏵
---
title: A simple table
---
See @tab:simple.
<!-- ... -->
```{r}
#| simple, tab.cap = 'First 3 rows of the `cars` data.',
head(cars, 3)
```
019. Printing verbosity (source: 019-option-verbose.Rmd) ⏵
---
title: Printing verbosity
---
Default `verbose = 0`:
```{r, test}
1:5 # a visible value
x = 1 + 1 # invisible
for (i in 1:10) i^2 # for loop returns invisible NULL
y = x^2 # invisible
```
`verbose = 1` always prints the last value:
```{r, test, verbose = 1}
```
`verbose = 2` prints all invisible values (except for `NULL`):
```{r, test, verbose = 2}
```
020. Inline output (source: 020-inline.Rmd) ⏵
---
title: Inline output
---
We know that $\pi = `{r} pi`$, and the first 3 letters are `{r} LETTERS[1:3]`. The first 3 variables of `mtcars` are `{r} xfun::join_words(names(mtcars)[1:3])`. You will not see this value `{r, eval = FALSE} 2 * pi`.
Some numbers:
```{r}
x = 1.23456789 * 10^c(0, 5, 6, 9, -6) * c(1, 1, -1, 1, 1)
sprintf('%f', x)
```
| n = signif/p = power | n = 3, p = 6 | n = 5/2/4/1/7 | p = 0/4/Inf/9/5 |
|-----------|-----------:|---------------------:|----------------------:|
| x_1 | `{r} x[1]` | `{r, signif=5} x[1]` | `{r, power=0} x[1]` |
| x_2 10^5 | `{r} x[2]` | `{r, signif=2} x[2]` | `{r, power=4} x[2]` |
| x_3 10^6 | `{r} x[3]` | `{r, signif=4} x[3]` | `{r, power=Inf} x[3]` |
| x_4 10^9 | `{r} x[4]` | `{r, signif=1} x[4]` | `{r, power=9} x[4]` |
| x_5 10^-6 | `{r} x[5]` | `{r, signif=7} x[5]` | `{r, power=5} x[5]` |
An equation: $Y = 300 `{r, dollar = FALSE, signif = 1} x[3]`x$.
021. Simple DataTables (source: 021-simple-datatables.Rmd) ⏵
---
title: "Simple DataTables"
---
Add the CSS/JS assets from the [simple-datatables](https://github.com/fiduswriter/simple-datatables/) library:
```{r}
litedown::vest(css = '@npm/simple-datatables/dist/style', js = '@npm/simple-datatables')
```
There are two ways to render a table using the library. You can either pass the data as a JSON object:
```{js, type = 'module', fill = xfun::tojson}
new simpleDatatables.DataTable('#table-iris', {
data: {
headings: `{ names(iris) }`,
data: `{ unname(iris)[1:20, ] }`
},
perPage: 5
});
```
<table id="table-iris"></table>
or generate the data to an HTML table first:
::: {#mtcars}
```{r, echo = FALSE}
I(mtcars[1:10, 1:5])
```
:::
and then initialize a simple data table.
```{js, type = 'module'}
new simpleDatatables.DataTable('#mtcars > table', {
perPage: 1,
perPageSelect: [1, 2, 4, 8, ['All', 0]]
});
```
022. Dygraphs (source: 022-dygraphs.Rmd) ⏵
---
title: "Dygraphs"
---
Add the CSS/JS assets from the [dygraphs](https://github.com/danvk/dygraphs) library:
```{r}
litedown::vest(css = '@npm/dygraphs/dist/dygraph', js = '@npm/dygraphs/dist/dygraph')
```
Show the yearly sunspots data (with a range selector):
```{r}
sunspot = cbind(Year = time(sunspot.year), Sunspots = sunspot.year)
```
```{js, type = 'module', fill = xfun::tojson}
const g = new Dygraph(
document.getElementById('graph-sunspot'),
`{ unname(sunspot) }`,
{
labels: `{ colnames(sunspot) }`,
showRangeSelector: true
}
);
// annotate the maximum
g.ready(() => g.setAnnotations([
{
series: `{ colnames(sunspot)[2] }`,
x: `{ sunspot[which.max(sunspot[, 2]), 1] }`,
shortText: "M",
text: "Maximum number"
}
]));
```
::: {#graph-sunspot style="width: 100%;"}
:::
Show two time series:
```{r}
deaths = cbind(Time = round(time(mdeaths), 2), Male = mdeaths, Female = fdeaths)
```
```{js, type = 'module', fill = xfun::tojson}
new Dygraph(
document.getElementById('graph-deaths'),
`{ unname(deaths) }`,
{
labels: `{ colnames(deaths) }`
}
);
```
::: {#graph-deaths style="width: 100%;"}
:::
023. Leaflet (source: 023-leaflet.Rmd) ⏵
---
title: "Leaflet"
---
Add the CSS/JS assets from the [leaflet](https://leafletjs.com) library:
```{r}
litedown::vest(css = '@npm/leaflet/dist/leaflet', js = '@npm/leaflet')
```
```{r}
loc = c(41.2542491, -95.9728748)
theta = (1:12)/6 * pi
circles = data.frame(Lat = loc[1] + sin(theta)/1000, Lng = loc[2] + cos(theta)/1000)
```
Provide a fenced Div with the ID `unmc` as the map container, and create the map:
::: {#unmc style="height: 500px;"}
:::
```{js, type = 'module', fill = xfun::tojson}
const map = L.map('unmc').setView(`{ loc }`, 17);
// add a tile layer
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 21,
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
// add a marker and bind a popup to it
const marker = L.marker(`{ loc }`).addTo(map);
marker.bindPopup("<b>UNMC</b><p>You can play badminton here.</p>");
// draw a circle of circles (lat/long from the data frame `circles`)
`{ unname(circles) }`.forEach(row => L.circle(row, {
color: 'orangered', radius: 30,
fillColor: 'lightskyblue', fillOpacity: 0.5
}).addTo(map));
```
024. Chart.js (source: 024-chart-js.Rmd) ⏵
---
title: "Chart.js"
---
Import the [chart.js](https://www.chartjs.org) library:
```{r}
litedown::vest(js = '@npm/chart.js')
```
Draw the chart with the `uspop` dataset:
```{js, type = 'module', fill = xfun::tojson}
const ctx = document.getElementById('uspop-polar');
new Chart(ctx, {
type: 'polarArea',
data: {
labels: `{ time(uspop) }`,
datasets: [{
data: `{ uspop }`
}]
},
options: {
responsive: true,
scales: {
r: {
pointLabels: {
display: true,
centerPointLabels: true
}
}
},
plugins: {
legend: {
display: false
}
}
}
});
```
<canvas id="uspop-polar"></canvas>
Test inline expressions (source: test-inline.Rmd) ⏵
---
title: "Test inline expressions"
---
A normal inline expression: `{r} pi`.
The knitr-style inline expressions are ignored by default: `r pi`.
An expression that spans multiple lines: `{r} pi +
1 -
1`.
When a line has leading spaces that are not meaningful,
it should still work: `{r} pi`.
<!-- doesn't work when the next line has leading spaces, e.g., `{r} pi +
1` -->
- An item.
`{r} pi` (leading spaces are meaningful here)
hi `{r} pi > 1 & FALSE`
hi `{r} pi`
<!-- doesn't work: hi `{r} pi +
1` -->
hi `{r} pi` (four spaces: this is a plain code block)
test-options.html (source: test-options.Rmd) ⏵
## Test Markdown options
```{r, test-a}
library(litedown)
# toc example
mkd <- c('# Header 1', 'p1', '## Header 2', 'p2')
mark(mkd, options = '+number_sections')
mark(mkd, options = '+number_sections+toc')
# hard_wrap example
mark('foo\nbar\n')
mark('foo\nbar\n', options = '+hardbreaks')
# latex math example
mkd <- c(
'`$x$` is inline math $x$!', '', 'Display style:', '', '$$x + y$$', '',
'\\begin{align}
a^{2}+b^{2} & = c^{2}\\\\
\\sin^{2}(x)+\\cos^{2}(x) & = 1
\\end{align}'
)
mark(mkd)
mark(mkd, options = '-latex_math')
# table example
mark('
First Header | Second Header
------------- | -------------
Content Cell | Content Cell
Content Cell | Content Cell
')
# caption
mark('
| a | b |
|---|--:|
| A | 9 |
Table: A table _caption_.
')
# no table
mark('
First Header | Second Header
------------- | -------------
Content Cell | Content Cell
Content Cell | Content Cell
', options = '-table')
# autolink example
mark('https://www.r-project.org/')
mark('https://www.r-project.org/', options = '-autolink')
# links and spans
mark('[a b](#){.red}')
mark('[a\nb](){.red}')
# strikethrough example
mark('~~awesome~~')
mark('~~awesome~~', options = '-strikethrough')
# superscript and subscript examples
mark('2^10^')
mark('2^10^', options = '-superscript')
mark('H~2~O')
mark('H~2~O', options = '-subscript')
# code blocks
mark('```r\n1 + 1;\n```')
mark('```{.r}\n1 + 1;\n```')
mark('```{.r .js}\n1 + 1;\n```')
mark('```{.r .js #foo}\n1 + 1;\n```')
mark('```{.r .js #foo style="background:lime;"}\n1 + 1;\n```')
mark('````\nA _code chunk_:\n\n```{r, echo=TRUE}\n1 + 1;\n```\n````')
# raw blocks
mark('```{=html}\n<p>raw HTML</p>\n```')
mark('```{=latex}\n\\textbf{raw LaTeX}\n```')
# fenced Divs
mark('::: foo\nasdf\n:::')
mark('::: {.foo .bar #baz style="color: red;"}\nasdf\n:::')
# smartypants example
mark('1/2 (c)')
mark('1/2 (c)', options = '+smartypants')
mkd <- paste(names(litedown:::pants), collapse = ' ')
mark(mkd, options = '+smartypants')
# filter out HTML tags
mkd = '<style>a {}</style><script type="text/javascript">console.log("No!");</script>\n[Hello](#)'
mark(mkd)
# tagfiler doesn't work: https://github.com/r-lib/commonmark/issues/15
# mark(mkd, options = 'tagfilter')
```
## The HTML output of above examples
```{r, test-b, results = 'asis'}
`<test-a>`
```
test-results-hide.html (source: test-results-hide.Rmd) ⏵
`results = 'hide'` should try to collapse output, e.g., merge the source blocks below:
```{r, results = 'hide'}
nrow(iris)
ncol(iris)
iris
```
Other types of output (such as messages) will interrupt the collapsed block:
```{r, results = 'hide'}
nrow(iris)
message(ncol(iris))
iris
```