Creating Pretty Documents from R Markdown
Author: Yixuan Qiu
Date: 2016-08-31

> Have you ever tried to find a lightweight yet nice theme for the R Markdown documents, just like this page?

## Themes for R Markdown

With the powerful `rmarkdown` package, we could easily create nice HTML document by adding some meta information in the header, for example

    ---
    title: Nineteen Years Later
    author: Harry Potter
    date: July 31, 2016
    output:
      rmarkdown::html_document:
        theme: lumen
    ---

The `html_document` engine uses the Bootswatch theme library to support different styles of the document. This is a quick and easy way to tune the appearance of your document, yet with the price of a large file size (> 700KB) since the whole Bootstrap library needs to be packed in.

For package vignettes, we can use the `html_vignette` engine to generate a more lightweight HTML file that is meant to minimize the package size, but the output HTML is less stylish than the `html_document` ones.

So can we do BOTH, a lightweight yet nice-looking theme for R Markdown?

## The prettydoc Engine

The answer is YES! (At least towards that direction)

The `prettydoc` package provides an alternative engine, `html_pretty`, to knit your R Markdown document into pretty HTML pages. Its usage is extremely easy: simply replace the `rmarkdown::html_document` or `rmarkdown::html_vignette` output engine by `prettydoc::html_pretty` in your R Markdown header, and use one of the built-in themes and syntax highlighters. For example

    ---
    title: Nineteen Years Later
    author: Harry Potter
    date: July 31, 2016
    output:
      prettydoc::html_pretty:
        theme: cayman
        highlight: github
    ---

## Options and Themes

The options for the `html_pretty` engine are mostly compatible with the default `html_document` (see the documentation) with a few exceptions:

1. Currently the `theme` option can take the following values. More themes will be added in the future.
   - `cayman`: Modified from the Cayman theme.
   - `tactile`: Modified from the Tactile theme.
   - `architect`: Modified from the Architect theme.
   - `leonids`: Modified from the Leonids theme.
   - `hpstr`: Modified from the HPSTR theme.
2. The `highlight` option takes value from `github` and `vignette`.
3. Options `code_folding`, `code_download` and `toc_float` are not applicable.

## Elements

We demonstrate some commonly used HTML elements here to show the apprearance of themes.

### Headers

#### Level 4

##### Level 5

### Tables

| Df | Sum Sq | Mean Sq | F value | Pr(>F) |
--- | --- | --- | --- | --- | --- | ---
Block | 5 | 343.3 | 68.66 | 4.447 | 0.01594 | *
N | 1 | 189.3 | 189.28 | 12.259 | 0.00437 | **
P | 1 | 8.4 | 8.40 | 0.544 | 0.47490 |
K | 1 | 95.2 | 95.20 | 6.166 | 0.02880 | *
N:P | 1 | 21.3 | 21.28 | 1.378 | 0.26317 |
N:K | 1 | 33.1 | 33.14 | 2.146 | 0.16865 |
P:K | 1 | 0.5 | 0.48 | 0.031 | 0.86275 |
Residuals | 12 | 185.3 | 15.44 |  |  |

### Lists

There are three kinds of lies:

1. Lies
2. Damned lies
3. Statistics
   - Frequentists
   - Bayesian
   - …

Supported highlighters in `prettydoc`:

- `github`: Style similar to Github
- `vignette`: Style used by `rmarkdown::html_vignette`

### Markups

Bold, italic, don’t say this.

### Code

Familiar `knitr` R code and plots:

    set.seed(123)
    n <- 1000
    x1  <- matrix(rnorm(n), ncol = 2)
    x2  <- matrix(rnorm(n, mean = 3, sd = 1.5), ncol = 2)
    x   <- rbind(x1, x2)
    smoothScatter(x, xlab = "x1", ylab = "x2")

    head(x)

    ##             [,1]        [,2]
    ## [1,] -0.56047565 -0.60189285
    ## [2,] -0.23017749 -0.99369859
    ## [3,]  1.55870831  1.02678506
    ## [4,]  0.07050839  0.75106130
    ## [5,]  0.12928774 -1.50916654
    ## [6,]  1.71506499 -0.09514745

Also try some other languages, for example C++.

    // [[Rcpp::depends(RcppEigen)]]
    // [[Rcpp::depends(RcppNumerical)]]

    #include <RcppNumerical.h>

    using namespace Numer;

    // f = 100 * (x2 - x1^2)^2 + (1 - x1)^2
    // True minimum: x1 = x2 = 1
    class Rosenbrock: public MFuncGrad
    {
    public:
        double f_grad(Constvec& x, Refvec grad)
        {
            double t1 = x[1] - x[0] * x[0];
            double t2 = 1 - x[0];
            grad[0] = -400 * x[0] * t1 - 2 * t2;
            grad[1] = 200 * t1;
            return 100 * t1 * t1 + t2 * t2;
        }
    };

    // [[Rcpp::export]]
    Rcpp::List optim_test()
    {
        Eigen::VectorXd x(2);
        x[0] = -1.2;
        x[1] = 1;
        double fopt;
        Rosenbrock f;
        int res = optim_lbfgs(f, x, fopt);
        return Rcpp::List::create(
            Rcpp::Named("xopt") = x,
            Rcpp::Named("fopt") = fopt,
            Rcpp::Named("status") = res
        );
    }