如何在bookdown中更改图表标题的格式

26

当使用bookdown(单一文档)时,图像会自动编号为:

图1 图例文字。

在化学中,惯例是将主要的图像标记为:

图1. 图例文字。

对于支持信息文档,我们需要:

图S1. 图例文字。

另外,在文本中引用图像时,我们需要:

...如图1所示,...

因此引用文本不应该加粗。

问题

我该如何让bookdown(或rmarkdown)生成这样的图表题注:“图S1. 一些文字。”和“表格S1. 一些文字。”?

我需要这些在MS Word格式下可用。

示例/尝试的解决方案

到目前为止,我已经尝试修改_bookdown.yml文档如下:

language:
  label:
    fig: "**Figure S**"
    tab: "**Table S**"

这将给出:图S1 一些文字...以及在使用时的内联引用:

Figure S\@ref(fig:Xray)

图S1看起来没问题。

这里是一个最简示例:

---
title: Supporting Information
subtitle: "Iron(I) etc"
author: "Some people here"
abstract: "Added the addresses here since there is no abstract in the SI"
output:
  bookdown::word_document2:
    fig_caption: yes
    toc: yes
    toc_depth: 1
---

## Reaction of etc.
Some text  (Figure S\@ref(fig:Xray)). Some text followed by a figure:

```{r Xray, fig.cap="Single-crystal X-ray structure of some text", echo=FALSE}
plot(cars)
```
Some text etc. followed by a table:

```{r DipUVvis, echo=FALSE, tab.cap="Table caption"}
df<-data.frame(Entry=c('AMM 51$3^a$','AMM 52^*a*^'),
               Precat=c('[FeBr~2~(dpbz)~2~] (4.00)','[FeBr~2~(dpbz)~2~] 
(2.00)'))

kable(head(df), format = "markdown")
```

上面的代码生成的是标题中的图S1,而不是图S1。(注意它全部都是粗体,并以句号结尾。)


请至少提供一个YAML头示例,以便我们生成一个接近您配置的文档。 - Martin Schmelzer
@MartinSchmelzer 你好,大家好。根据你们的评论,我尝试修改了问题,如果还需要其他信息,请告诉我。我正在努力学习,请多多包涵,感谢你们的帮助! - Outlander
1
@AMM 我稍微修改了一下问题,以便其他人更容易提供帮助。很遗憾目前我没有时间去寻找解决方案。我还删除了关于创建模式的方面。这使得问题过于复杂,SO帖子应该只提出一个问题。我建议您在第二个问题上单独发布帖子。希望能有所帮助! - Michael Harper
1
@MikeyHarper 这非常有帮助,非常感谢!我会确保在未来的问题中整合您的反馈! - Outlander
6个回答

10

虽然没有一种方法可以通过 bookdown 样式化图题前缀,但是可以通过应用自定义 Lua 过滤器(需要 pandoc 2.0 或更高版本)来实现此功能。

Lua 过滤器

假设你从以下内容开始:

Figure 1 Text of figure caption.

以下过滤器应该可以达到你想要的效果(有关其他格式设置选项,请参见https://pandoc.org/lua-filters.html#inline):

function Image (img)
  img.caption[1] = pandoc.Strong(img.caption[1])
  img.caption[3] = pandoc.Strong(pandoc.Str(string.gsub(img.caption[3].text, ":", ".")))
  return img
end

(假设 img.caption[2]Figure之间的空白)

另一个例子,如果你从以下文本开始:

图1 图题文字。

下面的过滤器应该可以满足您的要求(有关其他格式选项,请参见https://pandoc.org/lua-filters.html#inline):

function Image (img)
  img.caption[1] = pandoc.Strong(img.caption[1])
  img.caption[3] = pandoc.Strong(img.caption[3])
  img.caption[4] = pandoc.Strong(".  ")
  return img
end

(假设img.caption[2]Figure和编号之间的空白,img.caption[4]是编号和标题之间的空白)

应用Lua过滤器

假设您将此过滤器放置在名为figure_caption_patch.lua的文件中,并将其放置在rmarkdown文档目录中,您可以通过在YAML头信息中添加一个pandoc参数来应用它:

output:
  bookdown::word_document2:
    pandoc_args: ["--lua-filter", "figure_caption_patch.lua"]

这将产生所需的标题样式。

图1。 图片说明文字。


2
看起来rmarkdown发生了变化,现在默认添加冒号,所以你的解决方案不再适用。请参见https://community.rstudio.com/t/how-to-change-the-figure-table-caption-style-in-bookdown/110397。但是,您可以使用`img.caption[3] = pandoc.Strong(pandoc.Str(string.gsub(img.caption[3].text, ":", "."))):替换为.`。请参见https://dev59.com/UcHqa4cB1Zd3GeqP1oc3#68508668。 - stefan
1
谢谢@stefan,我更新了我的答案并采纳了你的建议修复。 - crsh
对于 PDF 输出,最好通过 LaTeX 来完成。请参阅 https://tex.stackexchange.com/questions/276795/how-to-change-figure-1-to-bold-fig-1-in-latex - crsh
1
非常感谢您的回答,对我帮助很大!我想提一下,默认情况下 RMarkdownBookdown 在我的图片标题开头添加了一个 <span></span> 标签,并且过滤器起初似乎不起作用。因此,我不得不从 img.caption[2] 开始计数,像这样 img.caption[2] = pandoc.Strong(img.caption[2]),这也使得过滤器在我的情况下做得很好。 - NicolasBourbaki
1
非常感谢您的回答,对我帮助很大!我想提一下,默认情况下,RMarkdownBookdown会在我的图题前面添加一个<span></span>标签,而过滤器最初似乎无法起作用。因此,我不得不从2开始计数,比如img.caption[2] = pandoc.Strong(img.caption[2]),这样过滤器在我的情况下也能很好地工作。 - undefined
显示剩余2条评论

8
据我所知,您无法通过rmarkdown/bookdown控制图表标题以达到您想要的效果。您可以使用 captioner 包来实现它,但有一个问题:它在rmarkdown输出中可以正常工作,但是对于bookdown输出,您需要进行后处理。这里是产生所需标题样式的Rmd文件:
---
title: Supporting Information
subtitle: "Iron(I) etc"
author: "Some people here"
abstract: "Added the addresses here since there is no abstract in the SI"
output:
  word_document:
    fig_caption: yes
---

```{r, include=F}
library(captioner)
tables <- captioner(prefix = "Table S", suffix = ". ", style="b", style_prefix=TRUE, auto_space = FALSE)
figures <- captioner(prefix = "Figure S", suffix = ". ", style="b", style_prefix=TRUE, auto_space = FALSE)

figures("Xray1", "Single-crystal X-ray structure of some text (1)", display=FALSE)
figures("Xray2", "Single-crystal X-ray structure of some text (2)", display=FALSE)
figures("Xray3", "Single-crystal X-ray structure of some text (3)", display=FALSE)
```

## Reaction of etc.
Some text. Some text followed by `r figures("Xray1", display="cite")`, which is the same figure as  `r figures("Xray3", display="cite")` but comes after `r figures("Xray2", display="cite")`.

```{r Xray, fig.cap=figures("Xray1"), echo=FALSE}
plot(cars)
```

```{r Xray2, fig.cap=figures("Xray2"), echo=FALSE}
plot(cars)
```

```{r Xray3, fig.cap=figures("Xray3"), echo=FALSE}
plot(cars)
```

Some text etc. followed by `r tables("tab-DipUVvis", display="cite")`:

```{r DipUVvis, echo=FALSE}
df<-data.frame(Entry=c('AMM 51$3^a$','AMM 52^*a*^'),
               Precat=c('[FeBr~2~(dpbz)~2~] (4.00)','[FeBr~2~(dpbz)~2~] 
(2.00)'))

knitr::kable(head(df), caption=tables("tab-DipUVvis", "Table Caption"))
```

然而,如果你改用bookdown::word_document2输出文档,图表标题会变成"Figure 1: Figure S1. ..."。目前还没有找到一种方法来抑制"Figure 1:",我只能在输出后进行后处理,搜索并替换所有的"Figure ?:"为""。


你尝试过在bookdown YAML中指定语言:label: fig: ""来消除重复的“Figure 1:”吗?...不过我猜你仍然会得到“1:”... :-/ @AMM:你还提到了通过captioner解决的方案-你是怎么做到的? - mschilli
@AMM:您还计划将您的解决方案编写为答案吗?否则,如果您认为LmW的解决方案足够好(无论如何都应该得到赞),我建议您接受它。 - mschilli
1
据我所知,@yihui并没有花太多时间来支持Word输出,因为他更喜欢HTML,并且很难在Word中支持每一个功能。话虽如此,我相信在github上的pull-request会受到欢迎。;-) - mschilli
2
@AMM,我认为你所描述的captioner的“问题”是因为它在第一次将唯一值传递给“name”参数时分配了图表编号,而不管“display”参数的值如何。更好的解决方案是使用“display=FALSE”定义您想要的顺序中的图像,然后在任何地方引用或显示它们。我修改了我的示例代码以包括这样一个示例。 - LmW.
@mschilli,既然您仍然需要删除“1:”,即使使用label: fig: "",我发现在MS Word中使用通配符“Figure [0-9] @:”进行搜索和替换更容易,因为文本中可能还有其他出现的“1:”。 - LmW.
显示剩余5条评论

7

按照此指南设置Word (.docx)样式,您可以将fig.和tab.字幕设置为加粗,尽管整个字幕行都可以加粗……我的意思是我们有一种自动创建.docx中的字幕的方法,类似于RMarkdown中的这个:

Figure S1: Single-crystal X-ray structure of some text (1)

但是,仍然似乎很难像这样创建一个:

Figure S1: Single-crystal X-ray structure of some text (1)

我想您只想使"Figure/Table S1"部分加粗,而不是整个字幕行。然而,如果您有兴趣使用Rmarkdown格式化.docx文件,则可以查看我添加的链接并查看以下说明。

1. 使用@LmW提供的.Rmd文件进行编织以获得第一个.docx输出。

如果您在captioner软件包方面遇到问题,也可以使用以下软件包。

---
title: Supporting Information
subtitle: "Iron(I) etc"
author: "Some people here"
abstract: "Added the addresses here since there is no abstract in the SI"
output:
  word_document:
     fig_caption: yes
---

```{r, include=F}
library(captioner)
#`captioner` package (Ver. 2.2.3) in my envionment returns the following error messages:
#Error in captioner(prefix = "Table S", suffix = ". ", style = "b", style_prefix = TRUE,  : 
#  unused arguments (suffix = ". ", style = "b", style_prefix = TRUE)

#Error in captioner(prefix = "Figure S", suffix = ". ", style = "b", style_prefix =     TRUE,  : 
#  unused arguments (suffix = ". ", style = "b", style_prefix = TRUE)

#tables <- captioner(prefix = "Table S", suffix = ". ", style="b", style_prefix=TRUE, auto_space = FALSE)
#figures <- captioner(prefix = "Figure S", suffix = ". ", style="b", style_prefix=TRUE, auto_space = FALSE)

tables <- captioner(prefix = "Table S",  auto_space = FALSE)
figures <- captioner(prefix = "Figure S", auto_space = FALSE)

figures("Xray1", "Single-crystal X-ray structure of some text (1)", display=FALSE)
figures("Xray2", "Single-crystal X-ray structure of some text (2)", display=FALSE)
figures("Xray3", "Single-crystal X-ray structure of some text (3)", display=FALSE)
```

## Reaction of etc.
Some text. Some text followed by `r figures("Xray1", display="cite")`, which is the same figure as  `r figures("Xray3", display="cite")` but comes after `r figures("Xray2", display="cite")`.

```{r Xray, fig.cap=figures("Xray1"), echo=FALSE}
plot(cars)
```

```{r Xray2, fig.cap=figures("Xray2"), echo=FALSE}
plot(cars)
```

```{r Xray3, fig.cap=figures("Xray3"), echo=FALSE}
plot(cars)
```

Some text etc. followed by `r tables("tab-DipUVvis", display="cite")`:

```{r DipUVvis, echo=FALSE}
df<-data.frame(Entry=c('AMM 51$3^a$','AMM 52^*a*^'),
               Precat=c('[FeBr~2~(dpbz)~2~] (4.00)','[FeBr~2~(dpbz)~2~] 
               (2.00)'))

knitr::kable(head(df), caption=tables("tab-DipUVvis", "Table Caption"))
```

2. 将 Image CaptionTable Caption 设为加粗。

在第一个 .docx 文件中:

  1. 选择一张图片标题或表格标题;
  2. 将其设为加粗(Ctrl + BCommand + B);
  3. 点击主页选项卡中样式设置的右下角或按下 Alt + Ctrl + Shift + S;
  4. 找到 Image CaptionTable Caption
  5. 点击它的下拉菜单并点击更新所选内容以匹配标题

如果你已经在 Image Caption 和 Table Caption 中完成了上述步骤,请确保将 .docx 文件保存为 word-styles-reference-01.docx,并放在你的工作目录中。

Selecting an image caption to make it bold

3. 通过添加 reference_docx 行来编织 .Rmd 文件,从而获得最终的 .docx 输出文件。

word_document: 行下添加 reference_docx: word-styles-reference-01.docx。请参见以下示例中的第 7 行。

---
title: Supporting Information
subtitle: "Iron(I) etc"
author: "Some people here"
abstract: "Added the addresses here since there is no abstract in the SI"
output:
  word_document:
    reference_docx: word-styles-reference-01.docx
    fig_caption: yes
---

```{r, include=F}
library(captioner)
#`captioner` package (Ver. 2.2.3) in my envionment returns the following error messages:
#Error in captioner(prefix = "Table S", suffix = ". ", style = "b", style_prefix = TRUE,  : 
#  unused arguments (suffix = ". ", style = "b", style_prefix = TRUE)

#Error in captioner(prefix = "Figure S", suffix = ". ", style = "b", style_prefix =     TRUE,  : 
#  unused arguments (suffix = ". ", style = "b", style_prefix = TRUE)

#tables <- captioner(prefix = "Table S", suffix = ". ", style="b", style_prefix=TRUE, auto_space = FALSE)
#figures <- captioner(prefix = "Figure S", suffix = ". ", style="b", style_prefix=TRUE, auto_space = FALSE)

tables <- captioner(prefix = "Table S",  auto_space = FALSE)
figures <- captioner(prefix = "Figure S", auto_space = FALSE)

figures("Xray1", "Single-crystal X-ray structure of some text (1)", display=FALSE)
figures("Xray2", "Single-crystal X-ray structure of some text (2)", display=FALSE)
figures("Xray3", "Single-crystal X-ray structure of some text (3)", display=FALSE)
```

## Reaction of etc.
Some text. Some text followed by `r figures("Xray1", display="cite")`, which is the same figure as  `r figures("Xray3", display="cite")` but comes after `r figures("Xray2", display="cite")`.

```{r Xray, fig.cap=figures("Xray1"), echo=FALSE}
plot(cars)
```

```{r Xray2, fig.cap=figures("Xray2"), echo=FALSE}
plot(cars)
```

```{r Xray3, fig.cap=figures("Xray3"), echo=FALSE}
plot(cars)
```

Some text etc. followed by `r tables("tab-DipUVvis", display="cite")`:

```{r DipUVvis, echo=FALSE}
df<-data.frame(Entry=c('AMM 51$3^a$','AMM 52^*a*^'),
               Precat=c('[FeBr~2~(dpbz)~2~] (4.00)','[FeBr~2~(dpbz)~2~] 
               (2.00)'))

knitr::kable(head(df), caption=tables("tab-DipUVvis", "Table Caption"))
```

这个方法也适用于免费的办公软件替代品吗?还是说我必须购买Windows/MacOS + MS Word才能调整模板? - mschilli
1
@mschilli 虽然我没有使用免费的办公软件来完成这个任务,但我认为你可以使用其他类似于“Word”的软件来完成我在帖子中提到的第二步。例如,如果你使用LibreOffice的Writer,你会发现样式设置,并且可以更新你想要修改的样式。 - Carlos Luis Rivera
如果您想获取MS Office,建议先检查您所属的机构是否与Microsoft拥有正式(全组织范围内)许可证以免费下载Office,例如牛津大学提供的 - Carlos Luis Rivera
谢谢你的指导,但我并不想为了更改报告的格式而安装操作系统和办公套件。;-) - mschilli
感谢您的贡献,您所描述的是我尝试过的第一件事情之一,正如您发现的那样,它会导致整个标题都变成粗体,这不是期望的结果。期刊有严格的格式指南,因此像这样的细节非常重要。因此,我认为目前使用captioner包是最好的方法。 - Outlander

2

这是一种最简单的解决方法,最初由@canovasjm在此处发表答案:

要在整个文档中将Figure X描述更改为Figure SX,并将其导出为pdf文件,只需在YAML部分的header-includes:下使用LaTex命令即可:

---
title: "Untitled"
output: pdf_document
header-includes:
  - \renewcommand{\figurename}{Figure S}
  - \makeatletter
  - \def\fnum@figure{\figurename\thefigure}
  - \makeatother
---

```{r, fig.cap="This is my figure description", fig.height=3}
plot(pressure)
```

```{r, fig.cap="Another figure description", fig.height=3}
plot(iris$Sepal.Length, iris$Petal.Width)
```

enter image description here


2

虽然这个问题已经发布一段时间了,但是如果要将图表编号从“Figure 1”更改为“Figure S1”,可以使用以下方法:

- \usepackage{caption}                            
- \DeclareCaptionLabelFormat{Sformat}{#1 S#2}     
- \captionsetup[table]{labelformat=Sformat}  
- \captionsetup[figure]{labelformat=Sformat} 

1
看起来对于 PDF 文件很好用,但我不认为这适用于 OP 要求的 MS Word 格式。 - Martin Smith

0

根据其他地方发布的建议,您可以在与MyFile.Rmd相同的目录中的文件_bookdown.yml中使用表达式:

language:
  label:
    fig: !expr function(x) sprintf("**Figure S%s.** ", x)
    tab: !expr function(x) sprintf("**Table S%s.** ", x)

此功能的完整文档可在此处获得。


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