Skip to content

Instantly share code, notes, and snippets.

@dmenne
Last active February 14, 2023 20:16
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save dmenne/f8eb291c9e71a5de44764d442e8bdefd to your computer and use it in GitHub Desktop.
Save dmenne/f8eb291c9e71a5de44764d442e8bdefd to your computer and use it in GitHub Desktop.
Markdown to HTML: Cross-references and captions for tables and figure
---
title: "Markdown to HTML: Cross-references and captions for tables and figure"
output:
bookdown::html_document2
---
Update December 2022: `gt` and `rtables` (partially) have cross-references.
And there is [`quarto`](https://quarto.org/docs/authoring/cross-references.html), not treated here, which has a much more elegant referencing syntax.
```{css, echo=FALSE}
blockquote {
font-size: 16px;
}
```
# The first chapter {#firstchap}
See this [gist](https://gist.github.com/dmenne/ab32c6ef0d8d927927337f80d6904c6e) for Word output; not all packages work in a portable way.
This is the first chapter with id `{#firstchap}.`
In recent versions of 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.
## 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
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(pander)
library(DT)
library(kableExtra)
library(ggplot2)
library(gt)
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.
```{r iris}
# Chunk iris, not tab:iris!. Gives Table 1.1
kable(head(iris), caption = "Iris with kable")
```
### `kableExtra` Table
`kableExtra` also plays well with numbering and captions.
```{r irisextra}
kable(head(iris), caption = "Iris with kableExtra") %>%
kable_styling()
```
### `pander` Table
Pander can set the caption, but does not produces table numbers.
```{r panderiris, results='asis', echo = FALSE}
pander(head(iris), caption = "This is a pander table", label = "panderiris")
```
References worked in earlier versions, but I gave up using `pander`.
### `DT` Table
Super for large tables when used with the search and export feature. It's the great brother by the same father as `kable`, but for reasons unknown needs hand-knitted intervention for autonumbering and caption.
```{r datatableiris, results='asis', echo=FALSE}
mcaption("dtiris", "This is a DT")
DT::datatable(head(iris), caption = "Iris with pander")
```
### `flextable`
[Great documentation](https://ardata-fr.github.io/flextable-book/), works in HTML, Word, PowerPoint and PDF.
```{r}
use_flex = TRUE # set to FALSE to test huxtable
```
```{r flexiris, echo=FALSE, eval = use_flex}
suppressPackageStartupMessages(library(flextable))
ft = flextable( head( iris ) )
#ft = set_caption(ft, "Iris with flextable")
ft
```
Captions are documented [here](https://davidgohel.github.io/flextable/reference/set_caption.html). You can also set the caption in the chunk label:
```{r flexiriscap, tab.cap="Iris with flextable, caption in chunk label", echo=FALSE, eval = use_flex, label="flexiriscap"}
flextable( head( iris ) )
```
### `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)`.
```{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
```
### `gt`
As of [version 0.8.0](https://github.com/rstudio/gt/issues/635), `gt` has captions and cross-references.
```{r tbl-iris, echo= FALSE}
gt(head(iris)) %>%
tab_caption("Iris Data")
```
### `rtables`
`rtables` has Roche as sponsor and so we can expect good code quality. As far I understand, the `rtables` is focused on ASCII output that is directly consumable, to create tables looking like the SPSS I love since 50 years when I did my Diplom degree.
The current (December 2022) state of art is summarized [here](https://github.com/Roche/rtables/issues/168). It looks like markdown support is not very high on the list.
### 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 autonumbering 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 a `kableExtra`table: As the extra Table \@ref(tab:irisextra) shows ....
- Reference to `flextable`: Please look at flextable \@ref(tab:flexiris) (not working) and \@ref(tab:flexiristab). These worked in earlier version, but fail now (Dec 2022)
- Reference to `huxtable`: Please look at huxtable \@ref(tab:huxiris); in more recent version, this refers to the chunk label.
- As Table \@ref(tab:tbl-iris) shows, `gt` flower tables can be beautiful.
- 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.
- [Not working link to pander](#tab:panderiris)
- [Link to flextable](#tab:flexiriscap)
- [Link to huxtable](#tab:huxiris);
For `pander` a link to the chunk label fails `\@ref(panderiris)`, but you can use the `mcaption` tag using the function defined in this document. Do not forget to put `results='asis'` into the chunk header.
- You should check Table \@ref(tab:panderiris).... Don't use underscores in tag!
- [Link to table](#tab:panderiris). Must use hash here, because it is part of the `mcaption` function.
@cinkova
Copy link

cinkova commented Oct 27, 2021

Thank you!!! This was what I was looking for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment