включение списков кода из внешнего файла в knitr / markdown


Я хотел бы включить списки кода, полученного из внешних файлов, в файл Rmarkdown. Мне бы хотелось, чтобы это было красиво (подсветка синтаксиса, авто-отступ и т. д.).

  • код не является R-кодом (в противном случае я мог бы использовать некоторые из существующих трюков дляpretty - print R-функций ) - в частности, этоошибки иStan код.
  • я не обязательно ориентируюсь на вывод LaTeX/PDF: в противном случае я мог бы использовать пакет listings.
  • я хотел бы иметь возможность инкорпорируйте файлы без громоздкой внешней системной команды cat firstpart.rmd codefile.rmd lastpart.rmd >wholefile.rmd и без предварительного этапа обработки: этот вопрос предполагает, что процессоры Markdown, такие как Multimarkdown и Marked 2, имеют синтаксис включения файлов, но я думаю, что застрял с pandoc.
  • в настоящее время я использую фрагменты кода, подобные этому
```{r jagsmodel, echo=FALSE, results="markup", comment=""}
cat(readLines("logist.bug"),sep="n")
```

Который работает нормально, но не дает мне подсветку синтаксиса ...

1 2

1 ответ:

Вот один из подходов. Вам нужно pygments установить (pip install pygments), и он должен быть в состоянии поставить (он должен сам по себе) "pygmentize где-то в вашей системе. Если у вас нет python или вы не можете установить этот модуль, то этот ответ, очевидно, не будет ответом для вас.

Следующие блоки knitr (все, кроме последнего, который является чистым R) вызывают pygmentize для создания разметки HTML для кода. Это должно быть возможно изменить https://github.com/hrbrmstr/knitrengines Чтобы сделать это больше "автоматически", но это не входит в мои краткосрочные задачи.

---
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) }"    
```

И производит это:

Введите описание изображения здесь

Я могу заставить его использовать разные стили для каждого блока кода, но у меня едва ли были циклы, чтобы провернуть это. Это не должно быть слишком много работы.