How to change the figure caption format in bookdown

When using bookdown (single document), figures are numbered automatically as:

Figure 1 Text of figure caption.

In chemistry, the convention is to label main Figures as:

Figure 1. Text of figure caption.

and for the supporting information document:

Figure S1. Text of figure caption.

Also in the figure reference in the text we need:

...as can be seen in Figure 1, ...

so the reference text should not be bold.

Question

How can i make bookdown (or rmarkdown) produce figure and table captions like so: "Figure S1. Some text." and "Table S1. Some text." ?

I need this to be in MS Word format.

Example/ Attempted Solution

So far i tried to modify the _bookdown.yml document as follows:

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

This gives: Figure S1 Some text... and the inline reference when using:

Figure S\@ref(fig:Xray)

is Figure S1 which is ok.

Here is a minimal example:

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

The code above produces Figure S1 in the figure caption but NOT Figure S1. (Note it is all bold and a full stop in the end).


While there is no method to style figure caption prefixes via bookdown, it is possible to do this by applying a custom Lua filter (which requires pandoc 2.0 or later).

Lua-Filters

Assuming that you are starting from

Figure 1 Text of figure caption.

the following filter should do what you want (see https://pandoc.org/lua-filters.html#inline for additional formatting options):

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

(Assuming that img.caption[2] is the white space between Figure)

As another example, if instead you are starting from

Figure 1 Text of figure caption.

the following filter should do what you want (see https://pandoc.org/lua-filters.html#inline for additional formatting options):

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

(Assuming that img.caption[2] is the white space between Figure and the number and img.caption[4] is the white space between the number and the caption)

Applying a Lua-filter

Assuming you place this filter in a file called figure_caption_patch.lua in the directory of your rmarkdown document you can apply it by adding a pandoc argument in the YAML front matter:

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

This should yield the desired caption style.

Figure 1. Text of figure caption.


To my knowledge, you cannot control figure/table captions to do what you want with rmarkdown/bookdown. You can use the package captioner to achieve it, with a catch: it works fine with rmarkdown outputs, but you'll need to do post-processing with bookdown outputs. Here is the Rmd file that produces your desired caption style:

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

However, if you switch to use bookdown::word_document2 output, the figure caption becomes "Figure 1: Figure S1. ...". I haven't found a way to suppress "Figure 1:" and have to do post-processing in my output to search and replace all "Figure ?:" with "".


Following this guide to set Word (.docx) style, you could make fig. and tab. captions boldface, though the whole caption line can be bold... I mean we have a way to create a caption in .docx via RMarkdown like this automatically:

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

However, still it seems difficult to make one like this:

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

I imagine that you do want to boldface only "Figure/Table S1" section, not the whole caption line. Nevertheless, if you are interested in formatting .docx file with Rmarkdown, you can check the link I added above and see the following description.

1. Knit the .Rmd file @LmW. provided us to get the first .docx output.

If you have some problem with captioner package, you can also use the following one.

---
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. Set Image Caption and Table Caption as boldface.

In the first .docx file,

  1. Select an image caption or a table caption;
  2. Make it bold (Ctrl + B or Command + B);
  3. Click the lower right corner of Styles setting in Home tab. Or press Alt + Ctrl + Shift + S;
  4. Find Image Caption or Table Caption;
  5. Click its drop-down menu and click Update Title to match selection.

If you have done the steps above in both Image and Table Caption, be sure to save the .docx file as word-styles-reference-01.docx in your working directory.

Selecting an image caption to make it bold

3. Knit the .Rmd file adding the reference_docx line to get your final .docx output.

Add reference_docx: word-styles-reference-01.docx under word_document: line. See Line 7 in the following example.

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

It's been a while since the question was posted, but to change the numbering of figures from 'Figure 1' to 'Figure S1', you can use the following:

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