6.11 Use the <details> disclosure element

As mentioned in Section 6.5, we can fold source code chunks via the option code_fold: true in the html_document format. Currently it is not possible to fold output blocks, but we can use some JavaScript tricks to make output foldable, too. This can be useful especially when the output is relatively long but not very important, so we fold it initially. If the reader is interested, they can unfold it to view the content. Figure 6.5 shows an example: you may click on the “Details” button to unfold the output.

Wrap text output in the details element.Wrap text output in the details element.

FIGURE 6.5: Wrap text output in the details element.

If you are viewing the HTML version of this book, you can actually see it in action below. If you are reading the PDF or printed version, such an interaction (clicking the “Details” button) is certainly not possible.

1:100
##   [1]   1   2   3   4   5   6   7   8   9  10  11  12
##  [13]  13  14  15  16  17  18  19  20  21  22  23  24
##  [25]  25  26  27  28  29  30  31  32  33  34  35  36
##  [37]  37  38  39  40  41  42  43  44  45  46  47  48
##  [49]  49  50  51  52  53  54  55  56  57  58  59  60
##  [61]  61  62  63  64  65  66  67  68  69  70  71  72
##  [73]  73  74  75  76  77  78  79  80  81  82  83  84
##  [85]  85  86  87  88  89  90  91  92  93  94  95  96
##  [97]  97  98  99 100

Below is the full source Rmd document that includes the JavaScript code to find output blocks, and wrap them into the <details> tags.

---
title: Use the `<details>` disclosure element
output: html_document
---

We show text output inside the `<details>` tags in this
example. We used JavaScript to wrap text output blocks
in `<details></details>`. The JavaScript code needs to
be executed at the end of this document, so it is placed
at the end. Below is a testing code chunk:

```{r}
1:100
```

The actual JavaScript code is below.

```{js, echo=FALSE}
(function() {
  var codes = document.querySelectorAll('pre:not([class])');
  var code, i, d, s, p;
  for (i = 0; i < codes.length; i++) {
    code = codes[i];
    p = code.parentNode;
    d = document.createElement('details');
    s = document.createElement('summary');
    s.innerText = 'Details';
    // <details><summary>Details</summary></details>
    d.appendChild(s);
    // move the code into <details>
    p.replaceChild(d, code);
    d.appendChild(code);
  }
})();
```

You may try to adapt the JavaScript code above to your own need. The key is to find out the elements to be wrapped into <details>:

document.querySelectorAll('pre:not([class])');

The CSS selector pre:not([class]) means all <pre> elements without the class attribute. You can also select other types of elements. For more about CSS selectors, see https://www.w3schools.com/css/css_selectors.asp. For more about the HTML tags <details> and <summary>, see https://www.w3schools.com/tags/tag_details.asp.