I'm rendering a Quarto document to HTML which contains a code chuck that generates more than 26 figures, to which I'm adding subcaptions. Quarto uses letters to sub-caption figures. In the English language, we only have 26 letters, so the 27th figure subcaption continues with the next ASCII character which is {
. How do I label the 27th figure subcaption with aa
, then bb
, etc?
Below is the last row of charts. Notice the figure on the right is captioned ({)
and I'd like that to be (aa)
.
EDIT: Note that the code below is a REPREX, and the answer should be for the general case. I.e., my figure subcaptions are NOT static and will change from script to script.
---
title: "27Figures"
format:
html
---
```{r}
#| label: fig-charts
#| layout-ncol: 2
#| fig-cap: "Plots of all data for all extensometer sensors."
#| fig-subcap:
#| - "DM0001_1"
#| - "DM0001_2"
#| - "DM0001_3"
#| - "DM0001_4"
#| - "DM0001_5"
#| - "DM0002_3"
#| - "DM0002_4"
#| - "DM0003_1"
#| - "DM0003_2"
#| - "DM0003_3"
#| - "DM0003_4"
#| - "DM0003_5"
#| - "DM0004_1"
#| - "DM0004_2"
#| - "DM0004_3"
#| - "DM0004_4"
#| - "DM0004_5"
#| - "DM0005_1"
#| - "DM0005_2"
#| - "DM0005_3"
#| - "DM0005_4"
#| - "DM0005_5"
#| - "DM0006_1"
#| - "DM0007_1"
#| - "DM0008_1"
#| - "DM0009_1"
#| - "DM0010_1"
#| - "DM0010_2"
#| - "DM0010_3"
for (i in 1:30) {
plot(i, i)
}
```
Add a JavaScript function that runs after the document loads that finds all subfigure captions using the class quarto-subfloat-caption and for captions beyond the 26th figure (index >= 26):
(*letter**letter*) *figure_label*
Figure 27 will show as "(aa) Fig-aa"
as you wanted!
Edit: It will reset this now for each new figure.
---
title: "27Figures"
format:
html:
include-after-body:
text: |
<script>
// Function to replace figure subcaptions beyond 'z'
document.addEventListener('DOMContentLoaded', function() {
const figures = document.querySelectorAll('.quarto-float-fig');
figures.forEach(figure => {
// Get all subfigure captions within this figure
const subfigCaptions = figure.querySelectorAll('.quarto-subfloat-caption');
subfigCaptions.forEach((caption, index) => {
if (index >= 26) { // Only process captions after 'z'
const currentText = caption.textContent.trim();
const figLabel = currentText.match(/\) (.*)/)[1]; // Extract everything after ") "
// Calculate the double letter (aa, bb, etc.)
const pos = index - 25; // 27th figure starts at pos 1
const letter = String.fromCharCode(96 + pos); // 97 is 'a' in ASCII
const newLabel = `(${letter}${letter}) ${figLabel}`;
caption.textContent = newLabel;
}
});
});
});
</script>
---
```{r}
#| label: fig-charts
#| layout-ncol: 2
#| fig-cap: "Plots of all data for all extensometer sensors."
#| fig-subcap:
#| - "DM0001_1"
#| - "DM0001_2"
#| - "DM0001_3"
#| - "DM0001_4"
#| - "DM0001_5"
#| - "DM0002_3"
#| - "DM0002_4"
#| - "DM0003_1"
#| - "DM0003_2"
#| - "DM0003_3"
#| - "DM0003_4"
#| - "DM0003_5"
#| - "DM0004_1"
#| - "DM0004_2"
#| - "DM0004_3"
#| - "DM0004_4"
#| - "DM0004_5"
#| - "DM0005_1"
#| - "DM0005_2"
#| - "DM0005_3"
#| - "DM0005_4"
#| - "DM0005_5"
#| - "DM0006_1"
#| - "DM0007_1"
#| - "DM0008_1"
#| - "DM0009_1"
#| - "DM0010_1"
#| - "DM0010_2"
#| - "DM0010_3"
for (i in 1:27) {
plot(i, i)
}
```
```{r}
#| label: fig-charts2
#| layout-ncol: 2
#| fig-cap: "Plots of all data for all extensometer sensors."
#| fig-subcap:
#| - "DM0001_1"
#| - "DM0001_2"
#| - "DM0001_3"
#| - "DM0001_4"
#| - "DM0001_5"
#| - "DM0002_3"
#| - "DM0002_4"
#| - "DM0003_1"
#| - "DM0003_2"
#| - "DM0003_3"
#| - "DM0003_4"
#| - "DM0003_5"
#| - "DM0004_1"
#| - "DM0004_2"
#| - "DM0004_3"
#| - "DM0004_4"
#| - "DM0004_5"
#| - "DM0005_1"
#| - "DM0005_2"
#| - "DM0005_3"
#| - "DM0005_4"
#| - "DM0005_5"
#| - "DM0006_1"
#| - "DM0007_1"
#| - "DM0008_1"
#| - "DM0009_1"
#| - "DM0010_1"
#| - "DM0010_2"
#| - "DM0010_3"
for (i in 1:27) {
plot(i, i)
}
```
As you can see, that works for 27 plots and more. It resets for each new .quarto-float-fig
class div.