r-lib / lintr

Static Code Analysis for R
https://lintr.r-lib.org
Other
1.2k stars 187 forks source link

`Missing chunk end for chunk` false-positive if there are multiple code blocks in the R string #1928

Open eitsupi opened 1 year ago

eitsupi commented 1 year ago

An error occurs if there are multiple code blocks within a single string in an R code chunk in an R Markdown file, as shown below.

````{r}
inner <- r"(
```{r}
cat("inner")
# 2nd code block

)"

The error does not seem to occur if there is no second code block.

````{r}
inner <- r"(
```{r}
cat("inner")

)"

The R Markdown file that caused this error can be found here. https://github.com/eitsupi/prqlr/blob/6d1199fd4d0cf3dbde0c3f2b9417a0f6b1223e7d/vignettes/knitr.Rmd

This is definitely a complicated pattern, thanks for working of this project.

MichaelChirico commented 1 year ago

@yihui is there any exported function we could use to match knitr's definition of "rmd file" for cases like this?

yihui commented 1 year ago

Sorry, there isn't. I've been hoping to export a function, though, which may look like this:

parse_rmd = function(file) {
  x = xfun::read_utf8(file)
  on.exit(knitr::knit_code$restore(), add = TRUE)
  res = knitr:::split_file(x, patterns = knitr::all_patterns$md)
  lapply(res, function(el) {
    if (!is.null(label <- el$params$label)) el$src = knitr::knit_code$get(label)
    el
  })
}

I don't mind if you use hacks like getFromNamespace() to access the internal function split_file() in knitr. This function should be fairly stable, and unlikely to change in future.