Skip to content

Instantly share code, notes, and snippets.

@dmenne
Last active December 14, 2022 09:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dmenne/ab32c6ef0d8d927927337f80d6904c6e to your computer and use it in GitHub Desktop.
Save dmenne/ab32c6ef0d8d927927337f80d6904c6e to your computer and use it in GitHub Desktop.
Markdown to Word: Cross-references and captions for tables and figures
---
title: "Markdown to Word: Cross-references and captions for tables and figures"
output:
bookdown::word_document2
---
```{css, echo=FALSE}
blockquote {
font-size: 16px;
}
```
# The first chapter {#firstchap}
See this [gist](https://gist.github.com/dmenne/f8eb291c9e71a5de44764d442e8bdefd) for a HTML version, which has more working options.
This is the first chapter with id `{#firstchap}.`
In RStudio, there is a button labelled 'A' in the top right corner of the editor window to switch to the Visual Markdown Editor. Use Insert/Cross Reference to insert a cross reference. Look like this button has disappeared in RStudio Desktop 2021.09.1.
## A subchapter {#subchapter}
- Anchors have curly braces.
- This is a subchapter with id `{#subchapter}`.
- You can also link to [arbitrary text]{#atext}. Anchor looks like this: `[arbitrary text]{#atext}`. The hash is required.
## Another one {#another-one}
This chapter **without label** only exists to demonstrate implicit anchors. You should prefer the above explicit ones, these are more robust to changes in the title text. See the [Pandoc documentation](https://pandoc.org/MANUAL.html#extension-auto_identifiers "Rules for automatic identifiers") for rules of automatic identifiers.
```{r, echo = FALSE, warning=FALSE}
library(knitr)
library(ggplot2)
mcaption = function(tag, caption){
# Do not use underscores in tag!
stopifnot(length(grep("_", tag)) == 0)
cat("<caption>(#tab:", tag, ")", caption, "</caption>", sep="")
}
```
### `kable` Table
Too bad, caption is always at the top, but otherwise, `kable` does everything right. Being able to position at the bottom has been promised long time ago.
```{r iris}
# Chunk iris, not tab:iris!. Gives Table 1.1
kable(head(iris), caption = "Iris with kable")
```
As a __unique feature__, knitr::kable with bookdown supports [Word templates](https://bookdown.org/yihui/rmarkdown-cookbook/word-template.html). See also [this blog post](https://rmarkdown.rstudio.com/articles_docx.html).
### `kableExtra` Table
`kableExtra` does not like Word.
### `pander` Table
`pander` gives tabular output on Word. It does not support table numbering.
```{r panderiris, results='asis', echo = FALSE}
# Must use echo = FALSE (or globally).
library(pander)
pandoc.table(head(iris), caption = "This is a pander caption")
```
### `DT` Table
It would be too much to expect that grandmaster `datatable` works with Word - it is too much rooted in the HTML world.
### `flextable`
The Winner.
[Great documentation](https://ardata-fr.github.io/flextable-book/), works in HTML, Word, PowerPoint and PDF.
Setting caption in the chunk works and gives table numbering. For functioning \[cross-references to work (<https://github.com/davidgohel/flextable/issues/301>) (March 2021), you might have to use the version on github:
`devtools::install_github("davidgohel/flextable)"`
Thanks to David Gohel for fixing this missing link (sic!) in a weekender.
```{r flexiris, tab.cap="Iris with flextable, caption in chunk label", echo=FALSE, label="flexiris"}
library(flextable)
flextable( head( iris ) )
```
Word templates, such as used in knitr::kable, do not work with `flextable`; [it is agnostic to pdf/word/HTML/PowerPoint](https://github.com/davidgohel/flextable/issues/372) that will contain them.
### `huxtable`
From the documentation:
- Within knitr, huxtable labels will default to the same as the knitr chunk label. To turn off this behaviour, set options(huxtable.autolabel = FALSE).
- If you use bookdown, and set a label on your table, the table caption() will automatically be prefixed with `(#label)`. You can then refer to the table using `\@ref(label)` (The backslash is not required, only for knitting, DM). `label` needs to start with `"tab:"`; if it doesn't, the `"tab:"` prefix will be added automatically. To turn off this behaviour, set `options(huxtable.bookdown = FALSE)`.
This package uses `flextable` internally, so with the latest github version of flextable internal references work too.
```{r huxiris, echo=FALSE}
suppressPackageStartupMessages(library(huxtable))
hx = hux( head( iris ) )
hx = add_colnames(hx)
hx = huxtable::set_caption(hx, "Iris with huxtable")
# The old and still working way: setting it explicit
#hx = huxtable::set_label(hx, "tab:huxirisexplicit")
hx
```
### A figure
```{r irisf, fig.height=2.4, fig.width= 2.5, fig.cap="Figures work nicely", echo = FALSE}
ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width) ) + geom_point()
```
```{=tex}
\begin{equation}
\bar{X} = \frac{\sum_{i=1}^n X_i}{n} (\#eq:mean)
\end{equation}
```
## References to tables, figures and equations
Currently, referencing tables and auto-numbering only works for `kable`, not for pander or DT. Recent versions of `flextable` and partially `huxtable` can mimic the behavior of `kable` with a more verbose syntax.
- Explicit reference to chapter: Check also Chapter \@ref(firstchap)...
- Explicit reference to chapter with optional category: Check also Chapter \@ref(subchapter).
- Implicit reference: As Chapter \@ref(another-one) shows...
- Table: `kable` table \@ref(tab:iris) is best seen here. The `tab:` is implicit, the chunk must not have the `tab:` prefix.
- Reference to `flextable`: Please look at flextable \@ref(tab:flexiris).
- Reference to `huxtable`: Please look at huxtable \@ref(tab:huxiris); in more recent version, this refers to the chunk label.
- Fig. \@ref(fig:irisf) shows that everything works nicely with figures. Great work by Yihui.
- Equation: Also see Equation \@ref(eq:mean).
## Links to tables and figures
- [An internal link](#atext) to arbitrary text. `[An internal link](#atext)`. The hash is required.
- [An internal link](#subchapter) to a subchapter.
- [An implicit internal link](#another-one) to a chapter heading.
- [Link to figure](#fig:irisf), a link to a figure `[Link to figure](#fig:irisf)`, the hash is required.
- [Non-working link](#tab:panderiris) to pander table
- [Link to kable](#tab:iris) works as one should expect
- [Link to flextable](#tab:flexiris) works in github version after March 8, 2021.
- [Link to huxtable](#tab:huxiris) works when flextable works.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment