12.2 ソースコード内に行番号を追加する

この節では, ソースコードに行番号をコメントとして追加する source フックの定義の例を示します. 例えば, このコードチャンクに対するものを考えます.

```{r}
if (TRUE) {
  x <- 1:10
  x + 1
}
```

このような出力を求めているものとします.

if (TRUE) {    # 1
  x <- 1:10    # 2
  x + 1        # 3
}              # 4

完全な例は以下になります.

---
title: ソースコードに行番号を追加する
---

行番号をソースコードに追加する `source` フックを用意します.
番号は各行の末尾のコメントに現れます.

```{r, include=FALSE}
local({
  hook_source <- knitr::knit_hooks$get('source')
  knitr::knit_hooks$set(source = function(x, options) {
    x <- xfun::split_lines(x)
    n <- nchar(x, 'width')
    i <- seq_along(x)  # 行番号
    n <- n + nchar(i)
    s <- knitr:::v_spaces(max(n) - n)
    x <- paste(x, s, '  # ', i, sep = '', collapse = '\n')
    hook_source(x, options)
  })
})
```

ここで新しいフックのテストができます. この文書を knit するとき,
末尾のコメントに行番号が見られます.

```{r}
if (TRUE) {
  x <- 1:10
  x + 1
}
```

上記の例での主な小ワザは各行のコメントの前に必要なスペースの数を決めることです. これによってコメントが右揃えになっています. この数は各行のコードの文字列幅に依存しています. このフック関数の意味を咀嚼することは読者に任せます. 内部で使われている関数 knitr:::v_spaces() は特定の長さのスペースを生成することに使われている点に注意してください. これが例です.

knitr:::v_spaces(c(1, 3, 6, 0))
## [1] " "      "   "    "      " ""

5.7節で紹介した方法が, ソースコードに行番号を追加する方法としてあなたが本当に求めていたものかもしれません. その構文はより簡潔で, ソースコードでもテキスト出力ブロックでも動作します. 上記の source フックの小ワザは, カスタム関数でソースコードを操作できることの一例を示すのが主な狙いです.