12.1 ソースコードを検閲する
ときにはレポートにソースコードの全文を掲載したくないこともあるでしょう. 例えばコードのある行にパスワードが書かれているかもしれません. 11.7節ではチャンクオプション echo
で R コードの文ごとに表示の有無を選べることを言及しました. 例えば echo = 2
で2つ目の文を表示します. この節では, コードのインデックスを指定する必要のない, より柔軟な方法を提供します.
基本的なアイディアはコードに特殊なコメント, 例えば # 秘密!!
のようなものを追加するということです. このコメントがコードのある行から検出されると, 行を省略します. 以下は source
フックを使用した完全な例です.
---
title: "`source` フックを使用してコードのある行を隠す"
---
`# 秘密!!` という文字列を含むコードの行を排除する `source` フックを用意します.
初めに, 末尾に
```{r, include=FALSE}
local({
hook_source <- knitr::knit_hooks$get('source')
knitr::knit_hooks$set(source = function(x, options) {
x <- x[!grepl('# 秘密!!$', x)]
hook_source(x, options)
})
})
```
`# 秘密!!` のある行が見えなくなります.
これで新しいフックをテストできます. この文書を knit すると, 特殊なコメント
```{r}
1 + 1 # 表示されるべき通常のコード
# 実際のユーザー名とパスワードを使ってみてください
auth <- httr::authenticate("user", "passwd")
auth <- httr::authenticate("yihui", "horsebattery") # 秘密!!
httr::GET("http://httpbin.org/basic-auth/user/passwd", auth)
```
上記の source
フックの重要な部分はこの行です. これはソースコードの入ったベクトル x
から grepl()
で追跡用のコメントの # 秘密!!
とマッチングしたものを排除しています.
正確に言うなら, 上記のフックは追跡用の # 秘密!!
というコメントのある行ではなく, 評価式 (expressions) を全て排除します. x
は実際には R 評価式のベクトルだからです. 例えば以下のコードチャンクを考えます.
source
フック内の x
の値はこうなります.
R 評価式ではなく行単位で隠したいなら, x
を行ごとに分割しなければなりません. xfun::split_lines()
の使用を検討するとよいでしょう. フック関数の本体はこうなります.
x <- xfun::split_lines(x) # 個別の行に分割する
x <- x[!grepl("# SECRET!!$", x)]
x <- paste(x, collapse = "\n") # 結合して1つの行にする
hook_source(x, options)
この例はソースコードの文字列を操作する方法を, そして grepl()
は決して文字列操作の唯一の方法ではない, ということを示しています. 12.2節では他の例もお見せしています.