yihui / knitr

A general-purpose tool for dynamic report generation in R
https://yihui.org/knitr/
2.39k stars 878 forks source link

Package build problems with Rmd vignette using child Rmd files #1540

Open aryoda opened 6 years ago

aryoda commented 6 years ago

I have modularized my vignette Rmd file using child chunks to be able to reuse the child Rmd files in other Rmd documents via

```{r child = "child_doc.Rmd"} ...

for this output and engine type (excerpt from Rmd master file YAML)

output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Vignette Title}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}

and observe package build problems.

As a result of an Stackoverflow question (https://stackoverflow.com/q/50078849/4468078) I am opening this issue.

Problems:

  1. R CMD build succeeds but the child Rmd file is missing in inst/doc
  2. R CMD build fails if an empty inst/doc folder exists ("cannot open file")

The error message is:

** installing vignettes
   ‘master_vignette.Rmd’ using ‘UTF-8’ 
Warning in readLines(if (is.character(input2)) { :
  cannot open file './child_doc.Rmd': No such file or directory
Quitting from lines 15-15 (./child_doc.Rmd) 
Error in readLines(if (is.character(input2)) { : 
  cannot open the connection
ERROR: installing vignettes failed

Reproducible example

If have created a minimal example package at github together with a detailled description of the problems:

https://github.com/aryoda/R_pkg_knitr_child_vignette_issue

System environment

R version 3.4.4 (2018-03-15)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 14.04.5 LTS
knitr_1.20 
dmurdoch commented 6 years ago

You can use the .install_extras file to get your child_doc.Rmd file installed, but that's not enough to get things to work. R needs fixing for that.

A minimal workaround (a bit better than the one on SO) is:

  1. Name the children something that doesn't look like a vignette, e.g. child_doc.txt
  2. Create a file with that name in inst\doc as well as the real file in vignettes. The content in inst\doc can be empty (unless child_doc.txt needs to include its own children, I imagine).
  3. Create a file .install_extras in vignettes that has a pattern to match all the child filenames, e.g. a single line containing "txt$" (without the quotes).
aryoda commented 6 years ago

I am happy to have an "official" workaround now :-)

Changing the file extensions of the child docs does work but has a small "penalty" (which is no tragedy): RStudio does no longer show a "Knit" button (which is helpful to preview only the child doc).

The documentation for .install_extras (https://cran.r-project.org/doc/manuals/r-devel/R-exts.html#Writing-package-vignettes) also mentions .Rinstignore which could be helpful to filter out the unwanted child HTML files again.

BTW: OSX with R3.2.3 shows the same problems

dmurdoch commented 6 years ago

Not "official". I haven't been on R Core since last year.

aryoda commented 6 years ago

@dmurdoch

R needs fixing for that.

So I would propose to close this issue (if nothing must be done on the knitr side).

Next step is to ask for opinions at the r-devel mailing list.

All hints are welcome to be more precise when asking at r-devel...

dmurdoch commented 6 years ago

I'm pretty sure R needs fixing, but I don't know when that will happen, or what the fix will be, so I'd leave the issue open for now. I wouldn't expect any action on knitr before R is fixed.

dmurdoch commented 6 years ago

One problem with a fix for R: it can't tell whether child_doc.Rmd is a vignette where the author forgot to put in the \VignetteEngine line, or a file included by a vignette. Any suggestions as to what markup would be appropriate to indicate it is the latter?

aryoda commented 6 years ago

@dmurdoch I already want to prepare my child Rmd vignette files for your patch to support all R versions (with and without your patch).

What is supposed to happen in the current R implementation if I set the vignette engine to a non-existing engine, e. g. %\VignetteEngine{none} (like seen in your patch)?

Currently I do not get any error (what I want) even though the document is ignored (not rendered) due to a non-registered rendering engine.

PS: Your workaround described above does work like a charm, THX :-)

dmurdoch commented 6 years ago

If you use a non-existent engine, you should get a note during check:

Files named as vignettes but with no recognized vignette engine: ‘vignettes/child_doc.Rmd’ (Is a VignetteBuilder field missing?)

Part of the patch I attached to https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=17416 will recognize "none" as a special name and won't generate the note for that name, but it will still give the note for other unrecognized names.

I haven't heard anything at all from R Core about the patch, so I suspect it won't make it into R-patched in time for 3.5.1, but I can't predict if it will ever be accepted. I don't know if CRAN will object to the spurious NOTE if you just use "none" as the engine without the patch. (You'll also need the hack of a second child file in the inst/doc directory; the patch fixes that bug, so in the long run it might not be necessary and might even generate its own note or warning.)

aryoda commented 6 years ago

OK, thanks for clarification and your commitment to solve the gap.

This will be a long-living workaround I guess (until everyone is using R 3.5.x with the applied patch).

dcnorris commented 5 years ago

I've just found that @dmurdoch's 4/29/2018 workaround did not work for a package vignette that includes an htmlwidget injected via widgetframe::frameWidget(). When I build locally, the widget ends up in vignettes/widget_D3-viz.html alongside the built-vignette html, but widget_D3-viz.html does not get copied to inst/doc/ — despite the presence of an .install_extras file requesting this, and despite (per workaround) my creating an empty inst/doc/widget_D3-viz.html file. It seems necessary for me to copy that file over manually.

cderv commented 3 years ago

Is this still an issue ? I believe it works as expected now. @aryoda can you confirm ? Is this still something you are using ? Thanks.

aryoda commented 3 years ago

@cderv Please give me few more weeks time to check this (I cannot see any implementations to fix this).

I am still using the workaround described by @dmurdoch since it works like a charm and is backwards compatible with older R versions.

Perhaps closing this issue because a simple workaround exists is the best now for this old issue.

bastistician commented 3 years ago
  1. R CMD build succeeds but the child Rmd file is missing in inst/doc

I'd put child documents in a subdirectory such as vignettes/inputs/ (to avoid misinterpretation as main vignette files) and add the line inputs$ to the vignettes/.install_extras file for completeness of the installed vignette sources. This procedure works with both Sweave and knitr child documents in current R and probably also in older R versions.

  1. R CMD build fails if an empty inst/doc folder exists ("cannot open file")

Yes, this is a bug in R CMD build. I've submitted a patch proposal at https://bugs.r-project.org/show_bug.cgi?id=18156 .

hughjonesd commented 1 year ago

For reference, an approach that works for me, as of 2022, is:

This seems to work for:

florisvdh commented 1 year ago

From vignettes, refer to them with ../man/rmd/child.Rmd

In my experience, this does work locally for pkgdown::build_site() (and all the rest), but not in a pkgdown GitHub Actions workflow because there it looks for the child document at /tmp/Rtmpzf2bRh/../man/vignette_childs/ (the /tmp/Rtmpzf2bRh directory being the package root).

I had success for all situations with: file.path(rprojroot::find_root(rprojroot::is_r_package), "man/vignette_childs/_child1.Rmd").

cderv commented 1 year ago

not in a pkgdown GitHub Actions workflow because there it looks for the child document at /tmp/Rtmpzf2bRh/../man/vignette_childs/

I wonder if in github action it should built with install = FALSE so that package is not installed in a temp directory. 🤔

florisvdh commented 1 year ago

It happened with install=FALSE in the first place (https://github.com/r-spatial/qgisprocess/actions/runs/4513359382/jobs/7948093970). Dropping install=FALSE gave same result (https://github.com/florisvdh/qgisprocess/pull/10). Not sure what's going on then; the workflow file is https://github.com/r-spatial/qgisprocess/blob/4dac770/.github/workflows/pkgdown.yaml