Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parsing \dontrun fails with conditionals #1087

Closed
agila5 opened this issue Jul 8, 2019 · 5 comments

Comments

@agila5
Copy link

commented Jul 8, 2019

I tried running the examples in the documentation of the do function (tidyverse/dplyr#4394 ) and they seem to work fine. I think that the issue in the documentation is linked to the pkgdown package. The examples with \dontrun fails if they are surrounded by conditionals like

if (TRUE) {
\dontrun{
something
}
}
@IndrajeetPatil

This comment was marked as resolved.

Copy link

commented Aug 10, 2019

Related to #976

@hadley

This comment was marked as resolved.

Copy link
Member

commented Aug 26, 2019

What is the problem?

@agila5

This comment was marked as resolved.

Copy link
Author

commented Aug 27, 2019

I think the problem is that pkgdown does not run examples properly if there are both conditional statements (like if clauses) and \dontrun as you can see on the dplyr website or tidyverse/dplyr#4394. If you manually run the examples in the do() function help page they all run just fine so it's not a problem of the examples. They fail only on the website help page.

I tried to create a minimal example of this problem forking the foofactors repository (since this is the simplest example of an R package I know) and I modified it creating two new functions: fbind_dontrun() and fbind_if_dontrun(). They are identical to fbind but I modified the examples with \dontrun{...} and if (TRUE) \dontrun{...}. If you run pkgdown::build_site() and look at the examples of fbind_dontrun() and fbind_if_dontrun() you should the same behaviour I described above:

test_if_dontrun_example

I hope it's clear.

@hadley

This comment has been minimized.

Copy link
Member

commented Aug 27, 2019

Thanks @agila5!

Here's a minimal reprex created with internal functions:

rd <- pkgdown:::rd_text("\\examples{
  if (TRUE) {
    \\dontrun{1}
  }
}", fragment = FALSE)
str(rd)
#> List of 2
#>  $ :List of 6
#>   ..$ : 'RCODE' chr "\n"
#>   ..$ : 'RCODE' chr "  if (TRUE) {\n"
#>   ..$ : 'RCODE' chr "    "
#>   ..$ :List of 1
#>   .. ..$ : 'VERB' chr "1"
#>   .. ..- attr(*, "class")= chr [1:2] "tag_dontrun" "tag"
#>   ..$ : 'RCODE' chr "\n"
#>   ..$ : 'RCODE' chr "  }\n"
#>   ..- attr(*, "class")= chr [1:2] "tag_examples" "tag"
#>  $ : 'TEXT' chr "\n"
#>  - attr(*, "class")= chr [1:2] "Rd" "tag"

cat(pkgdown:::as_data.tag_examples(rd[[1]]))
#> <div class='input'>  if (TRUE) {
#>     </div><div class='output co'>#&gt; <span class='error'>Error: &lt;text&gt;:3:0: unexpected end of input</span>
#> #&gt; <span class='error'>1:   if (TRUE) {</span>
#> #&gt; <span class='error'>2:     </span>
#> #&gt; <span class='error'>  ^</span></div><span class='co'># NOT RUN {</span>
#> <span class='fl'>1</span>
#> <span class='co'># }</span><div class='input'>  }
#> </div><div class='output co'>#&gt; <span class='error'>Error: &lt;text&gt;:1:3: unexpected '}'</span>
#> #&gt; <span class='error'>1:   }</span>
#> #&gt; <span class='error'>      ^</span></div>

Created on 2019-08-27 by the reprex package (v0.3.0)

And similarly if we use \ldots:

rd <- pkgdown:::rd_text("\\examples{
  foo(\\ldots)
}", fragment = FALSE)
str(rd)
#> List of 2
#>  $ :List of 4
#>   ..$ : 'RCODE' chr "\n"
#>   ..$ : 'RCODE' chr "  foo("
#>   ..$ : list()
#>   .. ..- attr(*, "class")= chr [1:2] "tag_ldots" "tag"
#>   ..$ : 'RCODE' chr ")\n"
#>   ..- attr(*, "class")= chr [1:2] "tag_examples" "tag"
#>  $ : 'TEXT' chr "\n"
#>  - attr(*, "class")= chr [1:2] "Rd" "tag"

cat(pkgdown:::as_data.tag_examples(rd[[1]]))
#> <div class='input'>  foo(</div><div class='output co'>#&gt; <span class='error'>Error: &lt;text&gt;:2:0: unexpected end of input</span>
#> #&gt; <span class='error'>1:   foo(</span>
#> #&gt; <span class='error'>   ^</span></div># NOT RUN {
#> &#8230;
#> # }
#> <div class='input'>)
#> </div><div class='output co'>#&gt; <span class='error'>Error: &lt;text&gt;:1:1: unexpected ')'</span>
#> #&gt; <span class='error'>1: )</span>
#> #&gt; <span class='error'>    ^</span></div>

Created on 2019-08-27 by the reprex package (v0.3.0)

@hadley

This comment has been minimized.

Copy link
Member

commented Aug 27, 2019

The key resource for understanding the parsing here is https://developer.r-project.org/parseRd.pdf and tools::Rd2ex(). Carefully reading its source suggests that as well as \dontrun, \donttest, \dontshow, \testonly and \ldots, I also need to handle \dots, \if, \ifelse, and \out.

@hadley hadley closed this in e6ab00a Aug 29, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.