Разрешает ли rmarkdown заголовки и ссылки для фрагментов кода? - PullRequest
0 голосов
/ 05 июня 2018

Есть ли хитрость для подписи и ссылки на фрагмент кода в rmarkdown (не в результате выполнения кода)?Например, как мне ссылаться на этот блок кода:

```{r blah}
blah <- "blah"
```

Я знаю, что могу использовать \ @ref (рис .: theFig) или \ @ref (tab: theTable), чтобы попасть на fig.capили заголовок (с kable), но я не вижу способа подписи и ссылки на сам код.

1 Ответ

0 голосов
/ 06 июня 2018

Это было бы отличной возможностью.И я думаю, что это еще не интегрировано.Вот подход, который работает для документов PDF и позволяет создавать подписи, а также метки для перекрестных ссылок:

1.Включите header.tex со следующим содержимым

\usepackage{caption}
\usepackage{floatrow}

\DeclareNewFloatType{chunk}{placement=H, fileext=chk, name=}
\captionsetup{options=chunk}
\renewcommand{\thechunk}{Chunk~\thesection.\arabic{chunk}}
\makeatletter
\@addtoreset{chunk}{section}
\makeatother

Поскольку среда, используемая для чанков, не является плавающим типом, мы объявляем новый тип с именем chunk.Параметр name оставлен пустым, поскольку мы уже переопределяем \thechunk в следующей строке, добавляя слово Chunk (поиграйте с опцией name и посмотрите, что произойдет).

Chunksдолжен перечисляться по разделам, и поэтому мы говорим tex для сброса счетчика каждый раз, когда начинается новый раздел.

Если вы не используете нумерацию разделов (установив опцию YAML), то замените строку

\renewcommand{\thechunk}{Chunk~\thesection.\arabic{chunk}}

\renewcommand{\thechunk}{Chunk~\arabic{chunk}}

2.Измените хук источника knitr в документе rmarkdown

library(knitr)
oldSource <- knit_hooks$get("source")
knit_hooks$set(source = function(x, options) {
  x <- oldSource(x, options)
  x <- ifelse(!is.null(options$ref), paste0("\\label{", options$ref,"}", x), x)
  ifelse(!is.null(options$codecap), paste0("\\captionof{chunk}{", options$codecap,"}", x), x)
})

Здесь мы используем две новые опции чанков ref и codecap.Если один из них не является NULL, соответствующая метка или заголовок генерируется с помощью команд \label или \captionof.

MWE:

---
title: "Cross-referencing Code Chunks"
output: 
  pdf_document: 
    includes:
      in_header: header.tex
    number_sections: true
---

```{r, echo=FALSE}
library(knitr)
oldSource <- knit_hooks$get("source")
knit_hooks$set(source = function(x, options) {
  x <- oldSource(x, options)
  x <- ifelse(!is.null(options$ref), paste0("\\label{", options$ref,"}", x), x)
  ifelse(!is.null(options$codecap), paste0("\\captionof{chunk}{", options$codecap,"}", x), x)
})
```

# Foo

Jump to \ref{TheBarChunk}

```{r Foo, ref = "TheFooChunk", codecap = "My Chunk"}
print("Foo!")
```

\newpage

# Bar

```{r Bar, ref = "TheBarChunk", codecap = "My second chunk"}
print("Bar!")
```

Head back to \ref{TheFooChunk}

Вот вывод (на обеих страницах):

enter image description here

enter image description here

Комментарии:

Вы можете улучшить код, проверив, какой тип вывода требуется, чтобы новый обработчик исходного кода использовался только для вывода PDF (пропускается, так как это обеденное время).

...