12.3 スクロール可能なテキスト出力

7.4節ではコードブロックとテキスト出力ブロックの高さを CSS で制御する方法を紹介しました. 実際には, もっと簡単なやり方で, チャンクオプション attr.sourceattr.output を使って style 属性を Markdown のコードブロックに追加できます(これらのオプションの説明は11.13節参照). 例えば, このようなコードに対してチャンクオプション attr.output を使います.

```{r, attr.output='style="max-height: 100px;"'}
1:300
```

Markdown 出力はこうなります.

```r
1:300
```

```{style="max-height: 100px;"}
##   [1]   1   2   3   4   5   6   7   8   9  10
##  [11]  11  12  13  14  15  16  17  18  19  20
##  ... ...
```

そして, テキスト出力ブロックは Pandoc によって HTML へと変換されます.

<pre style="max-height: 100px;">
<code>##   [1]   1   2   3   4   5   6   7   8   9  10
##  [11]  11  12  13  14  15  16  17  18  19  20
##  ... ...</code>
</pre>

Pandoc の fenced code blocks についてより詳しく学ぶには, https://pandoc.org/MANUAL.html#fenced-code-blocks のマニュアルを読んでください.

attr.sourceattr.output オプションによって個別のコードチャンクに対して最大の高さを指定することができます. しかしこの構文は少しばかり野暮ったく, CSS と Pandoc の Markdown 構文をより理解する必要があります. 以下にカスタムチャンクオプション max.height と連動するカスタム output フックの例を示します. attr.output = 'style="max-height: 100px;"' の代わりに max.height = "100px" のようにオプションを設定するだけでよいのです. この例では x 引数には手を付けず, options 引数のみを操作しています.

---
title: スクロール可能なコードブロック
output: 
  html_document: 
    highlight: tango
---

チャンクオプション `max.height` が設定されている時, テキスト出力に `style` 属性を追加するような `output` フックを設定します.

```{r, include=FALSE}
options(width = 60)
local({
  hook_output <- knitr::knit_hooks$get('output')
  knitr::knit_hooks$set(output = function(x, options) {
    if (!is.null(options$max.height)) options$attr.output <- c(
      options$attr.output,
      sprintf('style="max-height: %s;"', options$max.height)
    )
    hook_output(x, options)
  })
})
```

`max.height` がない場合, 出力の全体が表示されます. 例えば...,

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

ここで `max.height``100px` を設定します. この高さは 100px を超えているので, テキスト出力にスクロールバーが現れます.

```{r, max.height='100px'}
1:100
```

原則として `max.height` オプションは `attr.output` オプションに変換されます. `attr.output` が既に設定されていたとしても動作します. つまり `attr.output` オプションは上書きされません. 例えば `.numberLines` 属性を付けてテキスト出力の端に行番号を表示させてみます.

```{r, max.height='100px', attr.output='.numberLines'}
1:100
```

12.1がその出力です. 最後のコードチャンクにあるチャンクオプション attr.output に注意してください. そのオプションは max.height によっては上書きされないのです. なぜなら, max.height が生成する style 属性を使って既存の属性と結合することで, 既存の属性を尊重しているからです.

options$attr.output <- c(
  options$attr.output,
  sprintf('style="max-height: %s;"', options$max.height)
)
チャンクオプション max.height を指定した, スクロール可能なテキスト出力の例

図 12.1: チャンクオプション max.height を指定した, スクロール可能なテキスト出力の例

source フックでも同様の小ワザを使って, ソースコードブロックの高さを制限できます.