R Markdownで出力結果を隠せるようにしてみた (minidownパッケージ)

カテゴリ: r

minidownパッケージを使うと以下のような感じのことができるようになります。 Resultsの部分をクリックすると図が現れます。

plot(iris)

Results

実例は http://minidown.atusy.net/#results-folding を参照してください。

使いたい人は今すぐremotes::install_github('atusy/minidown')を実行しましょう!

バグレポお待ちしています!

使い方

YAMLを指定するだけ。

output:
  minidown::mini_document:
    results_folding: hide

その上で個別に状態を弄りたければ、チャンクオプションのresults.foldingNULL (無効)、"show" (表示)、"hide" (隠す) を指定します。

応用編として、以下のように全体的にresults.foldingNULLにしておくと、機能としては使えるようにしつつデフォルトで無効化できるので、ピンポイントに必要なところだけ折り畳みを許可できます。

knitr::opts_chunk$set(results.folding=NULL)

また、チャンクオプションのsummary.resultsに好きな文字列を指定すると、折り畳み部分の文字列を変更できます。

何かが隠れているよ

##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa

実装方法の概観

ざっくり言うと、knitr::knit_hooksという機能を使います。

  1. ソースコードのコードブロックの出力が完了したら、HTMLの<details>要素を挿入
  2. ソースコードの評価結果の出力が完了したら、HTMLの</details>要素を挿入

1と2ではそれぞれsourcefolding.resultsという別々の要素に注目します。

これを素朴に実装すると、一つのチャンクで複数の出力がある場合に、<details></details>を正しく対にできません。たとえば

'foo'
'bar'

が以下のようになってしまいます。

```r
'foo'
```

<details>

```
## 'foo'
```

```r
'bar'
```

<details>

```
## 'bar'
```

</details>

そこで、チャンクラベルを調査し、sourceに対するhookが発動した時は、チャンクラベルを調査して、現在のチャンクラベルと直前のチャンクラベルが同じであれば、ソースコードの直前に </details> を挿入するようにしました。

実際には<details>の後に<summary>Results</results>というのも挿入していて Resultsの部分はチャンクオプションで制御できるように工夫しています。

まあここでは概観だけということで詳しくはソースコード読んでください。

https://github.com/atusy/minidown

Enjoy!