Last active
February 14, 2023 20:16
-
-
Save dmenne/f8eb291c9e71a5de44764d442e8bdefd to your computer and use it in GitHub Desktop.
Markdown to HTML: Cross-references and captions for tables and figure
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
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. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you!!! This was what I was looking for.