在 knitr/markdown 中合并来自外部文件的代码清单

incorporate code listings from an external file in knitr/markdown

我想将从外部文件中提取的代码列表合并到 Rmarkdown 文件中。我希望它漂亮(语法高亮、自动缩进等)。

```{r jagsmodel, echo=FALSE, results="markup", comment=""}
cat(readLines("logist.bug"),sep="\n")
```

它工作正常但没有让我语法突出显示...

这是一种方法。您需要安装 pygments (pip install pygments) 并且它必须能够放置(它应该是自己的)“pygmentize 在您系统的某处。如果您没有 python 或者不能安装那个模块,那么这个答案显然不会成为你的答案。

以下 knitr 块(除最后一个纯 R 之外的所有块)调用 pygmentize 为代码创建 HTML 标记。应该可以修改 https://github.com/hrbrmstr/knitrengines 以使其更多 "automagical" 但这不在我的短期 TODO 中。

---
title: "lexers"
output: 
  html_document:
    css: code.css
    keep_md: true
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

### Bugs

```{r bugs1, echo=FALSE, results="asis"}
tf <- tempfile(fileext=".html")
system(sprintf("/usr/local/bin/pygmentize -o %s incl.bug", tf))
cat(readLines(tf), sep="\n")
unlink(tf)
```

### Elixir

```{r elixir1, echo=FALSE, results="asis"}
tf <- tempfile(fileext=".html")
system(sprintf("/usr/local/bin/pygmentize -o %s incl.ex", tf))
cat(readLines(tf), sep="\n")
unlink(tf)
```

### Python

```{r py1, echo=FALSE, results="asis"}
tf <- tempfile(fileext=".html")
system(sprintf("/usr/local/bin/pygmentize -o %s incl.py", tf))
cat(readLines(tf), sep="\n")
unlink(tf)
```

### Plain ol' R

```{r}
summary(mtcars)
```

这使得:

您可以使用您喜欢的任何 pygments CSS 文件来实现不同的方案,这就是 code.css:

中的内容
<style>
.gl .hll { background-color: #ffffcc }
.highlight  { background: #f8f8f8; }
.highlight .c { color: #408080; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #FF0000 } /* Error */
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
.highlight .o { color: #666666 } /* Operator */
.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #BC7A00 } /* Comment.Preproc */
.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #FF0000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #00A000 } /* Generic.Inserted */
.highlight .go { color: #808080 } /* Generic.Output */
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #0040D0 } /* Generic.Traceback */
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #B00040 } /* Keyword.Type */
.highlight .m { color: #666666 } /* Literal.Number */
.highlight .s { color: #BA2121 } /* Literal.String */
.highlight .na { color: #7D9029 } /* Name.Attribute */
.highlight .nb { color: #008000 } /* Name.Builtin */
.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */
.highlight .no { color: #880000 } /* Name.Constant */
.highlight .nd { color: #AA22FF } /* Name.Decorator */
.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #0000FF } /* Name.Function */
.highlight .nl { color: #A0A000 } /* Name.Label */
.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #19177C } /* Name.Variable */
.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #666666 } /* Literal.Number.Float */
.highlight .mh { color: #666666 } /* Literal.Number.Hex */
.highlight .mi { color: #666666 } /* Literal.Number.Integer */
.highlight .mo { color: #666666 } /* Literal.Number.Oct */
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
.highlight .sx { color: #008000 } /* Literal.String.Other */
.highlight .sr { color: #BB6688 } /* Literal.String.Regex */
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #19177C } /* Name.Variable.Class */
.highlight .vg { color: #19177C } /* Name.Variable.Global */
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */
</style>
#

更新

如果您愿意将代码(不会执行但会格式化)内联,我刚刚对上述 knitrengines 包进行了更新,让您可以这样做:

---
title: "pygtest"
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(knitrengines)
```

```{pygments test, pyg.ext="py", pyg.sty="github"}
import something.please

print("Hello, world!")
```

```{pygments test2, pyg.ext="go", pyg.sty="github"}
package main

import "fmt"

func main() {

    s := make([]string, 3)
    fmt.Println("emp:", s)

    s[0] = "a"
    s[1] = "b"
    s[2] = "c"
    twoD := make([][]int, 3)
    for i := 0; i < 3; i++ {
        innerLen := i + 1
        twoD[i] = make([]int, innerLen)
        for j := 0; j < innerLen; j++ {
            twoD[i][j] = i + j
        }
    }
    fmt.Println("2d: ", twoD)
}
```

```{pygments test3, pyg.ext="ex", pyg.sty="github"}
defmodule Math do
  def sum(a, b) do
    a + b
  end
end

IO.puts "The answer is #{ Math.sum(4,3) }"    
```

并产生这个:

我可以让它在每个代码块中使用不同的样式,但我几乎没有时间来完成它。不过应该不会太麻烦。