12.1 Redact source code

Sometimes we may not want to fully display our source code in the report. For example, you may have a password in a certain line of code. We mentioned in Section 11.7 that you can use the chunk option echo to select which expressions in the R code to display (e.g., show the second expression via echo = 2). In this section, we provide a more flexible method that does not require you to specify the indices of expressions.

The basic idea is that you add a special comment to the code (e.g., # SECRET!!). When this comment is detected in a line of code, you omit that line. Below is a full example using the source hook:

  1. ---
  2. title: Using the `source` hook to hide certain lines of code
  3. ---
  4. First, we set up a `source` hook to exclude the lines of code
  5. that contain the string `# SECRET!!` at the end.
  6. ```{r, include=FALSE}
  7. local({
  8. hook_source <- knitr::knit_hooks$get('source')
  9. knitr::knit_hooks$set(source = function(x, options) {
  10. x <- x[!grepl('# SECRET!!$', x)]
  11. hook_source(x, options)
  12. })
  13. })
  14. ```
  15. Now we can test the new hook. When you knit this document, you
  16. will not see the lines with the special comment `# SECRET!!`.
  17. ```{r}
  18. 1 + 1 # normal code to be displayed
  19. # please use your real username and password
  20. auth <- httr::authenticate("user", "passwd")
  21. auth <- httr::authenticate("yihui", "horsebattery") # SECRET!!
  22. httr::GET("http://httpbin.org/basic-auth/user/passwd", auth)
  23. ```

The key part in the above source hook is this line, which matches the trailing comment # SECRET!! in the source code vector x via grepl() and exclude the matches:

  1. x <- x[!grepl("# SECRET!!$", x)]

Precisely speaking, the above hook will exclude whole expressions containing the trailing comment # SECRET!!, instead of individual lines, because x is actually a vector of R expressions. For example, for the code chunk below:

  1. 1 + 1
  2. if (TRUE) {
  3. # SECRET!!
  4. 1:10
  5. }

The value of x in the source hook is:

  1. c("1 + 1", "if (TRUE) { # SECRET!!\n 1:10\n}")

If you want to hide lines instead of expressions of R code, you will have to split x into individual lines. You may consider using the function xfun::split_lines(). The body of the hook function will be:

  1. x <- xfun::split_lines(x) # split into individual lines
  2. x <- x[!grepl("# SECRET!!$", x)]
  3. x <- paste(x, collapse = "\n") # combine into a single string
  4. hook_source(x, options)

This example shows you how to manipulate the source code string, and grepl() is certainly not the only choice of string manipulation. In Section 12.2, we will show another example.