---
layout: post
title: "A Tufte-style Jekyll blog powered by servr and knitr"
categories: [jekyll, rstats]
tags: [knitr, servr, httpuv, websocket]
---
This post demonstrates [my fork](http://github.com/cpsievert/knitr-jekyll) of Yihui's [knitr-jekyll](https://github.com/yihui/knitr-jekyll) which tweaks the default layout to resemble [tufte-jekyll](https://github.com/clayh53/tufte-jekyll). As Yihui mentions in his [knitr-jekyll blog post](http://yihui.name/knitr-jekyll/2014/09/jekyll-with-knitr.html) (which I _highly_ recommend reading), GitHub Pages does not support arbitrary Jekyll plugins, but I've managed to remove tufte-jekyll's dependency on custom plugins via custom [knitr output hooks](http://yihui.name/knitr/hooks/). Not only does this allow GitHub Pages to build and host this template automagically, but it also fixes [tufte-jekyll's problem with figure paths](https://github.com/clayh53/tufte-jekyll#which-brings-me-to-sorrow-and-shame).
The rest of this post shows you how to use these custom hooks and some other useful things specific to this template (at some point, you might also want the [source for this post](https://raw.githubusercontent.com/cpsievert/knitr-jekyll/gh-pages/_source/2015-04-20-jekyll-tufte-servr.Rmd))
```{r setup, echo = FALSE, message = FALSE}
knitr::opts_chunk$set(message = FALSE, cache = TRUE, fig.height = 4)
```
### Figures
By default, the `fig.width` [chunk option](http://yihui.name/knitr/options/) is equal to 7 inches. Assuming the zoom of your browser window is at 100%, that translates to about 3/4 of the textwidth.
```{r skinny, fig.cap = "Figure 1: A nice plot that is not quite wide enough. Note that this figure caption was created using the `fig.cap` chunk option"}
library(ggplot2)
p <- ggplot(diamonds, aes(carat))
p + geom_histogram()
```
If we increase `fig.width` to a ridiculous number, say 20 inches, it will still be constrained to the text width, even by changing `fig.width` to 20 inches.
```{r wide, fig.width = 20, fig.cap = "Figure 2: The `fig.height` for this chunk is same as Figure 1, but the `fig.width` is now 20. Since the width is constrained by the text width, the figure is shrunken quite a bit."}
p + geom_histogram(aes(y = ..density..))
```
By constraining the figure width, it will ensure that figure captions (set via `fig.cap`) appear correctly in the side margin. If you don't want to restrict the final figure width, set the `fig.fullwidth` chunk option equal to `TRUE`. In this case, the figure caption is placed in the side margin below the figure.
```{r full, fig.width = 20, fig.fullwidth = TRUE, fig.cap = "Figure 3: Full width plot"}
p + geom_point(aes(y = price), alpha = 0.2) +
facet_wrap(~cut, nrow = 1, scales = "free_x") +
geom_smooth(aes(y = price, fill = cut))
```
To place figures in the margin, set the `fig.margin` chunk option equal to `TRUE`.
```{r margin, fig.margin = TRUE, fig.cap = "Figure 4: useR logo"}
tmp <- tempfile()
user <- "http://user2014.stat.ucla.edu/images/useR-large.png"
download.file(user, tmp)
img <- png::readPNG(tmp)
plot(0:1, type = 'n', xlab = "", ylab = "")
lim <- par()
rasterImage(img, lim$usr[1], lim$usr[3], lim$usr[2], lim$usr[4])
unlink(tmp)
```
## Sizing terminal output
The default `R` terminal output width is 80, which is a bit too big for the styling of this blog, but a width of 55 works pretty well:
```{r}
options(width = 55, digits = 3)
(x <- rnorm(40))
```
## Mathjax
If you want inline math rendering, put `$$ math $$` inline. For example, $$ \Gamma(\alpha) = (\alpha - 1)!$$. If you want it on it's own line, do something like:
{% highlight latex %}
$$
x = {-b \pm \sqrt{b^2-4ac} \over 2a}.
$$
{% endhighlight %}
which results in
$$
x = {-b \pm \sqrt{b^2-4ac} \over 2a}.
$$
## Margin notes
Much margin. So excite.
Put stuff in the side margin using the `` HTML tag with a class of 'marginnote':
{% highlight html %}
Anything here will appear in side margin
{% endhighlight %}
Another (less cute) example of margin notes is to add a table caption. In fact, the figure captions above are just margin notes.
Table 1: Output from a simple linear regression in tabular form.
```{r echo = FALSE}
m <- lm(vs ~ wt, mtcars)
knitr::kable(broom::tidy(m), format = "markdown")
```
## Sidenotes
Similar to a 'marginnote' is a 'sidenote' 1 which works like this
1
Sidenotes are kind of like footnotes that appear in the side margin.
{% highlight html %}
1
1
Sidenotes are kind of like footnotes that appear in the side margin.
{% endhighlight %}
Unfortunately, this is a lot of HTML markup, but of course[^2], you can also do footnotes, so that might be a better option.
[^2]: I hate it when people say "of course" as though this is obvious everyone.
## Contact me
If you find any issues or want to help improve the implementation, [please let me know](https://github.com/cpsievert/knitr-jekyll/issues/new)!
## Session Information
```{r, echo = FALSE}
sessionInfo()
```