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

The snippet help(...) inside a code tag breaks build_site() #1471

Closed
klmr opened this issue Jan 23, 2021 · 4 comments
Closed

The snippet help(...) inside a code tag breaks build_site() #1471

klmr opened this issue Jan 23, 2021 · 4 comments

Comments

@klmr
Copy link
Contributor

klmr commented Jan 23, 2021

Reprex

usethis::create_package(file.path(getwd(), 'down'))

writeLines(r'-(#' Test
#'
#' Execute \code{help(a$b)}
f = function () help(a$b))-', 'R/test.r')

devtools::document()
pkgdown::build_site()

Expected output

A working package page is generated.

Actual output

Error message:

Reading 'man/f.Rd'
Error in index[[topic]] :
  attempt to select more than one element in vectorIndex
In addition: Warning messages:
1: In if (has_name(index, topic)) { :
  the condition has length > 1 and only the first element will be used
2: In if (has_name(index, topic)) { :
  the condition has length > 1 and only the first element will be used
Error: callr subprocess failed: attempt to select more than one element in vectorIndex
Type .Last.error.trace to see where the error occured

The same error message is also shown for slight variations of the ‘roxygen2’ comment above, for instance \code{help(a-b)}. What seemingly triggers the behaviour is an arbitrary (but valid) R expression inside a help call inside \code{…}. Conversely, a single identifier (e.g. \code{help(a)}) works.

For context, this bug manifests in a package that provides (and exports) an own function called help; so help here doesn’t refer to utils::help — not that it should matter in this case.

.Last.error.trace
 Stack trace:

 Process 45636:
 1. pkgdown::build_site()
 2. pkgdown:::build_site_external(pkg = pkg, examples = examples,  ...
 3. callr::r(function(..., crayon_enabled, crayon_colors, pkgdown_internet) { ...
 4. callr:::get_result(output = out, options)
 5. throw(newerr, parent = remerr[[2]])

 x callr subprocess failed: attempt to select more than one element in vectorIndex

 Process 45725:
 17. (function (..., crayon_enabled, crayon_colors, pkgdown_internet)  ...
 18. pkgdown::build_site(...)
 19. pkgdown:::build_site_local(pkg = pkg, examples = examples, run_dont_run = r ...
 20. pkgdown:::build_reference(pkg, lazy = lazy, examples = examples,  ...
 21. purrr::map(topics, build_reference_topic, pkg = pkg, lazy = lazy,  ...
 22. pkgdown:::.f(.x[[i]], ...)
 23. pkgdown:::data_reference_topic(topic, pkg, examples = examples,  ...
 24. pkgdown:::as_data(tags$tag_description[[1]])
 25. pkgdown:::as_data.tag_description(tags$tag_description[[1]])
 26. pkgdown:::parse_section(x, "Description", ...)
 27. pkgdown:::flatten_para(x, ...)
 28. purrr::map(x, as_html, ...)
 29. pkgdown:::.f(.x[[i]], ...)
 30. pkgdown:::as_html.tag_code(.x[[i]], ...)
 31. pkgdown:::href_expr(expr)
 32. pkgdown:::href_topic(as.character(expr$topic))
 33. pkgdown:::href_topic_local(topic)
 34. pkgdown:::find_rdname_attached(topic)
 35. pkgdown:::find_rdname(package, topic)
 36. base:::.handleSimpleError(function (e)  ...
 37. h(simpleError(msg, call))

 x attempt to select more than one element in vectorIndex

Warning message:
partial match of 'topenv' to 'topenvs'
sessionInfo()
R version 4.0.2 (2020-06-22)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Mojave 10.14.6

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRblas.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib

locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

other attached packages:
[1] down_0.0.0.9000

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.4.6      pillar_1.4.3      compiler_4.0.2    git2r_0.26.1
 [5] prettyunits_1.1.1 remotes_2.1.1     tools_4.0.2       testthat_2.3.2
 [9] digest_0.6.25     pkgbuild_1.0.6    colorout_1.2-2    pkgload_1.0.2
[13] evaluate_0.14     lifecycle_0.2.0   tibble_3.0.0      memoise_1.1.0
[17] pkgconfig_2.0.3   rlang_0.4.6       cli_2.0.2         rstudioapi_0.11
[21] commonmark_1.7    pkgdown_1.5.1     xfun_0.13         withr_2.1.2
[25] stringr_1.4.0     roxygen2_7.1.0    xml2_1.3.2        knitr_1.28
[29] vctrs_0.3.1       desc_1.2.0        fs_1.4.1          devtools_2.3.0
[33] rprojroot_1.3-2   glue_1.4.1        R6_2.4.1          processx_3.4.2
[37] fansi_0.4.1       rmarkdown_2.1     sessioninfo_1.1.1 purrr_0.3.4
[41] callr_3.4.3       magrittr_1.5      htmltools_0.4.0   MASS_7.3-51.6
[45] backports_1.1.6   ps_1.3.2          ellipsis_0.3.1    usethis_1.6.0
[49] assertthat_0.2.1  stringi_1.4.6     crayon_1.3.4

(I also tried this with the dev version 1.6.1.9000 … same issue.)

@klmr
Copy link
Contributor Author

klmr commented Jan 23, 2021

Actually I just noticed that the stack trace had changed slightly for 1.6.1.9000, since the relevant functions are now found in the ‘downlit’ package.

.Last.error.trace
 Stack trace:

 Process 45636:
 1. pkgdown::build_site()
 2. pkgdown:::build_site_external(pkg = pkg, examples = examples,  ...
 3. callr::r(function(..., crayon_enabled, crayon_colors, pkgdown_internet) { ...
 4. callr:::get_result(output = out, options)
 5. throw(newerr, parent = remerr[[2]])

 x callr subprocess failed: Failed to parse Rd in f.Rd
ℹ attempt to select more than one element in vectorIndex

 Process 47770:
 17. (function (..., crayon_enabled, crayon_colors, pkgdown_internet)  ...
 18. pkgdown::build_site(...)
 19. pkgdown:::build_site_local(pkg = pkg, examples = examples, run_dont_run = r ...
 20. pkgdown:::build_reference(pkg, lazy = lazy, examples = examples,  ...
 21. purrr::map(topics, build_reference_topic, pkg = pkg, lazy = lazy,  ...
 22. pkgdown:::.f(.x[[i]], ...)
 23. base:::withCallingHandlers(data_reference_topic(topic, pkg, examples = exam ...
 24. pkgdown:::data_reference_topic(topic, pkg, examples = examples,  ...
 25. pkgdown:::as_data(tags$tag_description[[1]])
 26. pkgdown:::as_data.tag_description(tags$tag_description[[1]])
 27. pkgdown:::parse_section(x, "Description", ...)
 28. pkgdown:::flatten_para(x, ...)
 29. purrr::map(x, as_html, ...)
 30. pkgdown:::.f(.x[[i]], ...)
 31. pkgdown:::as_html.tag_code(.x[[i]], ...)
 32. downlit::autolink_url(text)
 33. downlit:::href_expr(expr[[1]])
 34. downlit:::href_topic(as.character(expr$topic))
 35. downlit:::href_topic_local(topic)
 36. downlit:::find_rdname_attached(topic)
 37. downlit:::find_rdname(package, topic)
 38. base:::.handleSimpleError(function (err)  ...
 39. pkgdown:::h(simpleError(msg, call))
 40. rlang:::abort(msg, parent = err)
 41. rlang:::signal_abort(cnd)
 42. base:::signalCondition(cnd)
 43. (function (e)  ...

 x Failed to parse Rd in f.Rd
ℹ attempt to select more than one element in vectorIndex

Warning message:
partial match of 'topenv' to 'topenvs'

Perhaps the bug should even be reported there instead of here? … Being unfamiliar with the code I’m not sure.

@klmr
Copy link
Contributor Author

klmr commented Jan 23, 2021

OK, after a bit of poking the obvious issue is that the auto-linking code, not expecting non-standard help calls, executes, in find_rdname(package, topic) with the arguments package = 'base', topic = c('$', 'a', 'b'):

  index <- topic_index(package)

  if (has_name(index, topic)) {
    index[[topic]]

And this in turn executes index[[c(TRUE, FALSE, FALSE)]], which causes the error. Adding a check (or a tryCatch …) would silence the issue.

But the more fundamental problem is still that auto-linking is over-eager here, and is interpreting any mention of any function called help as if it were utils::help. Ideally ‘pkgdown’/‘downlit’ would either understand the scope/context and realise that help doesn’t refer to utils::help, or provide a user option to selectively disable auto-linking.

@klmr klmr changed the title The snippet \code{help(...)} inside a ‘roxygen2’ comment breaks build_site() The snippet help(...) inside a code tag breaks build_site() Jan 24, 2021
@klmr
Copy link
Contributor Author

klmr commented Jan 24, 2021

I’ve adjusted the title to reflect the fact that this problem exists for all parts of the site touched by the auto-linker, not just the documentation. Having `help(a$b)` inside an R Markdown vignette, for instance, causes the same issue.

@hadley
Copy link
Member

hadley commented Feb 19, 2021

Moved to downlit: r-lib/downlit#77

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants