Does rmarkdown allow captions and references for code chunks?

…衆ロ難τιáo~ 提交于 2021-02-18 11:09:40

问题


Is there a trick for captioning and referencing a chuck of code in rmarkdown (not the result of running the code)? For example, how do I reference this block of code:

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

I know that I can use \@ref(fig:theFig) or \@ref(tab:theTable) to get at fig.cap or caption (with kable) but I don't see a way to caption and reference the code itself.


回答1:


This would be a great feature. And I think it is not integrated yet. Here is an approach that works for PDF documents and allows you to generate captions as well as labels for cross-referencing:

  1. Include a header.tex with the following content

\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

Since the environment used for chunks is not a floating type we declare a new one, named chunk. The option name is left blank since we already redefine \thechunk in the next line by prepending the word Chunk (play with the name option and see what happens).

The chunks should be enumerated by section and so we tell tex to reset the counter each time a new section begins.

If you do not use section numbering (by setting the YAML option), then replace the line

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

by

\renewcommand{\thechunk}{Chunk~\arabic{chunk}}
  1. Modify the knitr source hook in your rmarkdown document

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

Here we make use of two new chunk options ref and codecap. If either one is not NULL, a corresponding label or caption is generated using the the commands \label or \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}

Here is the output (of both pages):

Adding the caption below the code chunk

If you'd prefer to add the caption below the code chunk, instead of above, this can be achieved by altering the above knitr hook to read:

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

Comments:

You could improve the code by checking what output type is desired so that the new source hook is only used for pdf output (skipped since it is lunch time).



来源:https://stackoverflow.com/questions/50702942/does-rmarkdown-allow-captions-and-references-for-code-chunks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!