Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change the figure caption format in bookdown

Tags:

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

like image 457
Outlander Avatar asked Aug 21 '18 08:08

Outlander


2 Answers

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.

like image 132
crsh Avatar answered Oct 06 '22 22:10

crsh


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 "".

like image 30
LmW. Avatar answered Oct 06 '22 22:10

LmW.