knitr icon indicating copy to clipboard operation
knitr copied to clipboard

Package build problems with Rmd vignette using child Rmd files

Open aryoda opened this issue 6 years ago • 17 comments

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 

aryoda avatar Apr 29 '18 11:04 aryoda

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).

dmurdoch avatar Apr 29 '18 20:04 dmurdoch

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

aryoda avatar Apr 29 '18 21:04 aryoda

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

dmurdoch avatar Apr 29 '18 23:04 dmurdoch

@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...

aryoda avatar Apr 30 '18 07:04 aryoda

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 avatar Apr 30 '18 10:04 dmurdoch

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?

dmurdoch avatar Apr 30 '18 20:04 dmurdoch

@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 :-)

aryoda avatar May 05 '18 15:05 aryoda

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.)

dmurdoch avatar May 05 '18 20:05 dmurdoch

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).

aryoda avatar May 05 '18 21:05 aryoda

I've just found that @dmurdoch's 4/29/2018 workaround did not work for a [package vignette](url https://cran.r-project.org/web/packages/DTAT/vignettes/Designing-33PC.html) 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.

dcnorris avatar Feb 20 '19 12:02 dcnorris

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

cderv avatar Jan 27 '21 11:01 cderv

@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.

aryoda avatar Feb 07 '21 23:02 aryoda

  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 .

bastistician avatar Jul 29 '21 20:07 bastistician

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

  • Put child documents in the man/rmd subdirectory.
  • From vignettes, refer to them with ../man/rmd/child.Rmd.
  • From roxygen documentation and README.Rmd, refer to them with man/rmd/child.Rmd.

This seems to work for:

  • knitting the README.md file
  • building vignettes, also in R CMD CHECK
  • building package documentation
  • building a website using pkgdown

hughjonesd avatar Nov 25 '22 19:11 hughjonesd

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").

florisvdh avatar Mar 24 '23 19:03 florisvdh

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. 🤔

cderv avatar Mar 24 '23 19:03 cderv

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

florisvdh avatar Mar 24 '23 20:03 florisvdh