在使用knitr和latex的Rmarkdown中如何设置代码块字体大小

61
在 knitr 中,.Rnw 文件中的 size 选项可以正常工作,以下代码生成:
\documentclass{article}

\begin{document}

<<chunk1, size="huge">>=
summary(mtcars)
@


\end{document}

rnw

然而,在Rmarkdown中我无法让它起作用。以下代码不会改变字体大小,就像在.rnw文件中一样。当尝试使用opts_chunk$set(size="huge")设置选项时,情况也是一样的。

这是预期的行为吗?如何更改块代码的字体大小?(我的意思是使用knitr选项,而不是在代码前添加\huge

---
title: "Untitled"
output: pdf_document
---

```{r, size="huge"}
summary(mtcars)
```

这里输入图片描述

我正在使用RStudio版本0.98.987、knitr 1.6和rmarkdown 0.2.68。


2
很遗憾,“size”选项只适用于Rnw。对于R Markdown(v2),我认为唯一的方法是重新定义Pandoc/LaTeX的代码环境(请参见http://rmarkdown.rstudio.com/pdf_document_format.html中的“包含”部分)。 - Yihui Xie
6
个人而言,我更愿意在LaTeX中重新定义环境,而不是使用钩子,因为后一种方法可能不够通用。例如,你可能会使用一个块钩子来添加\begin{huge}\end{huge}以围绕一个块,但这样做会使你陷入LaTeX中,除非你不需要其他文档格式,比如HTML、Word等。另外,调整样式就像这只小猫咪缠着你一样:http://i.imgur.com/17B4U.gif。当你工作时,很容易被这种行为所诱惑,但这会分散你的注意力并且是一项无休止的工作 :) - Yihui Xie
5个回答

42

我们可以采用更改knitr钩子的想法来进行操作:

def.chunk.hook  <- knitr::knit_hooks$get("chunk")
knitr::knit_hooks$set(chunk = function(x, options) {
  x <- def.chunk.hook(x, options)
  ifelse(options$size != "normalsize", paste0("\n \\", options$size,"\n\n", x, "\n\n \\normalsize"), x)
})

这段代码片段修改了默认的块钩子。它只是检查块选项大小是否不等于其默认值(normalsize),如果是,则将 options$size 的值前置到代码块的输出中(包括源代码!),并追加 \\normalsize 以进行切换。

因此,如果你在一个代码块中添加了 size="tiny",那么该代码块生成的所有输出都将以此方式打印。

你只需要在文档开头包含这个代码段即可。


2
这是一个很棒的答案! - jay.sf
2
据我所知,您的答案仅适用于LaTex输出。您是否知道任何既适用于HTML又适用于LaTex的便捷解决方案? - mavericks
确实是个好答案。在我的本地机器上它完美地运行了,但在服务器上失败了。根据 YihuI 在这里的描述,在服务器上的解决方案是添加额外的\n。我已经编辑了答案以包含这个解决方案。 - Ege Rubak
如果您想要在LaTeX文件中使用大量的\small\normalsize切换,并且希望每个块都具有相同的大小,那么这确实是一个很好的答案。我正在使用Bookdown的示例环境,但我不想让它们变成\small。是否有一种方法可以按块类型进行设置? - El Andi
我认为重新定义环境的方式更适合LaTeX,可以参考这个答案;而使用CSS指定字体大小则更适合html输出,可以参考这个答案 - El Andi
这通常效果很好,但我发现这样做会导致代码块无法包含在递增列表中(https://stackoverflow.com/questions/63538154/uncover-code-chunk-in-rmarkdown-and-beamer)。 - S. Robinson

27
\tiny

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

按照降序排列,可用的字号选项如下:
Huge > huge > LARGE > Large > large > normalsize > small > footnotesize > scriptsize > tiny


这让我无法使用图表引用。 - usεr11852

18

根据这个代码片段,你需要使用CSS定义字体大小:

<style type="text/css">
body, td {
   font-size: 14px;
}
code.r{
  font-size: 20px;
}
pre {
  font-size: 20px
}
</style>

code.r将控制从代码块中回显的R代码的字体大小,而pre将应用于从代码输出的任何R结果。

完整的工作.Rmd文件可能如下所示:

---
title: "FontTest"
author: "Thomas Hopper"
date: "January 13,2016"
output: html_document
---

<style type="text/css">

body, td {
   font-size: 14px;
}
code.r{
  font-size: 20px;
}
pre {
  font-size: 20px
}
</style>

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

## R Markdown

This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see <http://rmarkdown.rstudio.com>.

When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

```{r cars}
summary(cars)
```

生成的html呈现为:

显示20pt R代码和20pt R输出的截图


15
原帖作者想要改变 PDF 输出的字体大小,而你的示例更改了 HTML 输出的字体大小。 - jarauh
2
然而,当我试图在HTML输出中搜索更改字体大小的解决方案时,我最终来到了这里。因此,这个答案是有用的 - 尽管它不是针对OP的。 - Pere
@Tom:非常有用,但是当我尝试时,发现'per'适用于代码和R输出,而'code.r'无响应。此外,是否有一种方法可以针对特定的代码块进行操作? - user2955884

9
您可以通过从您的包my_package导出以下函数来基于其定义自己的文档格式:
my_report <- function(...) {

  fmt <- rmarkdown::pdf_document(...)

  fmt$knitr$knit_hooks$size = function(before, options, envir) {
    if (before) return(paste0("\n \\", options$size, "\n\n"))
    else return("\n\n \\normalsize \n")
  }

  return(fmt)
}

这将定义一个knitr代码块钩子size,它会在代码块之前放置适当的latex命令,并在代码块之后放置\normalsize
无论如何,使用以下R markdown可以检查它是否起作用:
---
output: my_package::my_report
---

Test text for comparison

```{r}
print(1)
```
The next code chunk has `size = 'tiny'` in the chunk options.

```{r, size = 'tiny'}
print(1)
```

我从`markdown::render()`获得以下结果:

enter image description here

请参阅我在github上开的问题:

https://github.com/yihui/knitr/issues/1296


1

在@Martin Schmelzer的输出基础上,如果您想要更改代码并输出默认字体大小整个文档,但不更改文本大小,则可以采用以下解决方案。

def.chunk.hook  <- knitr::knit_hooks$get("chunk")
knitr::knit_hooks$set(chunk = function(x, options) {
  x <- def.chunk.hook(x, options)
  paste0("\n \\", "size_of_the_code_and_output","\n\n", x, "\n\n \\size_of_the_text")
})

例如,
---
output: pdf_document
---

```{r setup, include=FALSE}
def.chunk.hook  <- knitr::knit_hooks$get("chunk")
knitr::knit_hooks$set(chunk = function(x, options) {
  x <- def.chunk.hook(x, options)
  paste0("\n \\", "footnotesize","\n\n", x, "\n\n \\Huge")
})
```

# Section 1
```{r}
summary(cars)
```
Text.

# Section 2
```{r}
print(1)
```
This works for every chunks.

这是例子的输出结果: Example

1
正是医生开的药方!谢谢。 - PatrickT

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接