楼主: janyiyi
1767 1

Using the LaTeX listings package to style R PDF reports with knitr and pandoc [推广有奖]

  • 3关注
  • 17粉丝

讲师

27%

还不是VIP/贵宾

-

威望
0
论坛币
3206 个
通用积分
5056.6800
学术水平
539 点
热心指数
537 点
信用等级
538 点
经验
10157 点
帖子
300
精华
2
在线时间
90 小时
注册时间
2010-10-3
最后登录
2024-4-6

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
This article was first published on Tyler Smith » r, and kindly contributed to R-bloggers)

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:

  1. ```{r, include = FALSE}
  2. ## setup knitr and display options
  3. library(knitr)
  4. opts_chunk$set(comment=NA)
  5. ```

  6. Test document
  7. ==

  8. Code with Output
  9. --

  10. Here's a bit of R code:

  11. ```{r code-output}
  12. summary(lm(Petal.Length ~ Species, data = iris))
  13. ```
复制代码

By default, the R code and the output it produces are included in thedocument.

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 html’ button.

Getting to pdf requires one more step. knit2html("example.Rmd")created 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 knit("example.Rmd")instead of knit2html)

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 pandocdefault doesn’t quite cut it here.

Leaving R for the command line, we can try the pandoc highlight-style options. I like tango:

  1. pandoc example.md -o example.pdf --highlight-style=tango
复制代码

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 --listingsoption on our example.md file:

  1. pandoc example.md -o example.tex --listings
复制代码

The resulting latex is marked up like this:

  1. \begin{lstlisting}[language=R]
  2. summary(lm(Petal.Length ~ Species, data = iris))
  3. \end{lstlisting}

  4. \begin{lstlisting}

  5. Call:
  6. lm(formula = Petal.Length ~ Species, data = iris)
复制代码

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:

  1. pandoc example.md -o example.tex -s --listings

  2. # add lstlisting style options
  3. sed -i 's/{lstlisting}\[language=R\]/{lstlisting}[language=R,style=Rcode]/g' \
  4. example.tex
复制代码

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 command pandoc -D latex. So I created a new template:

pandoc -D latex > ~/.pandoc/templates/ty.latex

Now I can place the listings style info directly into ty.latex:

  1. \documentclass[$if(fontsize)$fontsize$,$endif$if(lang)$lang$,$endif$if(papersize)$papersize$,$endif$for(classoption)$classoption$sep$,$endfor$]{$documentclass$}
  2. \usepackage[T1]{fontenc}
  3. \usepackage{tgschola}
  4. \usepackage{DejaVuSansMono}                  % monospace font for code
  5. \usepackage{amssymb,amsmath}
  6. \usepackage{fixltx2e} % provides \textsubscript

  7. \usepackage[margin=1in]{geometry} % document size
  8. \usepackage{natbib}               % reference style
  9. \bibpunct{(} {)} {;} {a} {} {,}   % citation formatting

  10. $if(listings)$
  11. \usepackage{listings}
  12. \usepackage[dvipsnames]{xcolor}
  13. \lstset{frame=single,commentstyle=\color{BrickRed},columns=fixed,basicstyle=\ttfamily,
  14. stringstyle=\color{Red},keepspaces=true,showstringspaces=false,
  15. numbers=none}
  16. \lstdefinestyle{Rcode}{backgroundcolor=\color[gray]{0.95}}
  17. $endif$
复制代码

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:

  1. Rscript -e 'args <- commandArgs(trailingOnly = TRUE) ; library(knitr) ; knit(args[1])' $fullname
  2. # md -> tex
  3. pandoc $filename.md -o $filename.tex --template=ty --listings
  4. # add lstlisting style options
  5. sed -i 's/{lstlisting}\[language=R\]/{lstlisting}[language=R,style=Rcode]/g' \
  6. $filename.tex
  7. # tex -> pdf
  8. texi2pdf $filename.tex
复制代码

The first line just bundles up the knitr call, using Rscript to run a self-contained R session for the processing. Next, we use pandoc to generate the LaTeX file. I use sed to add the style options, and finally call texi2pdf to generate the final document.

And here’s the result:

rmd2pdf.sh example.Rmd

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.


二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:package Reports listing Report ports package reports style

已有 1 人评分经验 论坛币 学术水平 热心指数 信用等级 收起 理由
oliyiyi + 40 + 40 + 5 + 5 + 5 精彩帖子

总评分: 经验 + 40  论坛币 + 40  学术水平 + 5  热心指数 + 5  信用等级 + 5   查看全部评分

沙发
tianwk 发表于 2019-7-26 00:08:39 |只看作者 |坛友微信交流群
thanks for sharing
已有 1 人评分论坛币 收起 理由
oliyiyi + 10 精彩帖子

总评分: 论坛币 + 10   查看全部评分

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注jltj
拉您入交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-19 23:55