knitr is a an R package that allows you to include R code in markdown or LaTeX source files, and have the code and/or its output included in the resulting html or pdf files. RStudio provides good support for this, so if you want to try it out that’s a good place to start. This post assumes you’ve got everything installed and working, and want to customize the pdf output via LaTeX.
I’ve been working with this for a week or two, and the one hitch that I’ve run into is generating a nice pdf directly from the source Rmd file. For example, working from this source file, in the Rmd or R-markdown format:
Generating html is easy. From within R, just call
knit2html("example.Rmd"). This produces a self-contained, nicely
highlighted html file. Even easier from Rstudio, just click the ‘knit to
Getting to pdf requires one more step.
two new files, one in markdown:
example.md, and the target html:
example.html. The markdown file can be converted to pdf with
pandoc("example.md", format = "latex").
(if you don’t need html output, you can use
This calls pandoc behind the scenes to do the conversion. You can now view your output in a pdf viewer. The R source code and output has a different font and a bit of highlighting, but are not otherwise set off from the surrounding code.
I’m preparing R tutorials, and want to visually distinguish my
instructions, the R code, and the associated output. The
doesn’t quite cut it here.
Leaving R for the command line, we can try the
options. I like
This shades the R source code, but the output is unchanged. Not quite what I’m after:
It seems like the highlight-styles ought to be customizable, but I haven’t figure that out yet.
Pandoc provides one further option, using the LaTeX Listings package. Listings provides lots of different options for customizing the presentation and highlighting of code blocks in latex output. With listings I’ll be able to add boxes and shading to the code chunks with a custom template for the file.
However, before I can do that, I need to fix one small shortcoming of the
Pandoc LaTeX output. When Pandoc uses the
--listings option on our
The resulting latex is marked up like this:
Note that the R source code has the language option set to R, but the output has no options set at all. There’s no way to style these two environments differently in LaTeX. To do that, we need to apply a style to one or the other of these listings. I haven’t found any way to accomplish this using knitr or pandoc, so I now pipe the pandoc output through sed to get this done:
Almost there. Now the listings styles are applied, but the style needs to
be defined in the document template. Pandoc templates are stored in
~/.pandoc/templates. The default latex template is available with the
pandoc -D latex. So I created a new template:
Now I can place the listings style info directly into
Check the documentation for listings to see all the options. The code here sets the default options for the R blocks (source and output), including boxing and colouring strings and comments. In addition, R source code blocks will be shaded gray; the background of the output remains white.
This is just the head of the file; the rest of it is unchanged from the default. I don’t understand all the options, so I’ll leave them alone for now. I did change the fonts to tgschola for the body, DejaVuSansMono for the code chunks, and added my standard geometry and natbib options. I haven’t used this template with references yet, so that may need tweaking.
With the template in place, I can now generate a pdf with my preferred formatting directly from the source Rmd, using the following script:
The first line just bundles up the
knitr call, using
Rscript to run a
self-contained R session for the processing. Next, we use
generate the LaTeX file. I use
sed to add the style options, and finally
texi2pdf to generate the final document.
And here’s the result:
That’s a fairly long and winding path to travel! Now that it’s done, I can use all the features of listings, and only need remember the simple R Markdown formatting for my day-to-day writing.