rmarkdown icon indicating copy to clipboard operation
rmarkdown copied to clipboard

html_document lib_dir behavior

Open tdsmith opened this issue 10 years ago • 1 comments

I was trying to rename the my-document-name_files folder that rmarkdown::render places in my output_dir when I render with the html_document format. I expected setting lib_dir to "media" to place all of the dependent files in e.g. output_dir/media.

There are two problems:

  1. Specifying a lib_dir that is not a child of the path containing the input file (but which is a child of output_dir) causes rendering to fail; this is true whether the path is specified as a relative path (i.e. "media") or an absolute path (paste0(getwd(), "/media")).
  2. images are still rendered to output_dir/my-document-name_files/figure-html and not lib_dir/figure-html

An example call is:

render(
    input="../client-code/result-illustrations.Rmd",
    output_format=html_document(
        dev="svg",
        self_contained=FALSE,
        lib_dir=paste0(getwd(), "/media")),
    output_dir=".")

where getwd() returns /Users/tim/rp/Biactivation/FlowAnalysis/manuscript.

The error which is thrown by render for this call is:

Error in relativeTo(basepath, dir) : 
  The path /Users/tim/Documents/research/projects/Biactivation/FlowAnalysis/client-code/media/jquery-1.11.0 does not appear to be a descendant of /Users/tim/Documents/research/projects/Biactivation/FlowAnalysis/manuscript/
Calls: render ... html_dependencies_as_string -> lapply -> FUN -> relativeTo
Execution halted

Note that render has (mis-)re-specified lib_dir relative to the input path!

I expected that specifying a lib_dir which is a child of output_dir but is not a child of the dir containing the input file should succeed, and that figure-html would be placed inside lib_dir.

tdsmith avatar Aug 25 '15 22:08 tdsmith

This is an old issue but as I began doing some cleaning, I started by the oldest one.

This issue is still happening but it is rather a documentation feature I guess. Currently, lib_dir will be evaluated relatively to the input directory. Not the output, not the current working dir from which render is run from.

See the reprex:

dir.create(tmp_proj <- tempfile())
old <- setwd(tmp_proj)
dir.create("rmd")
dir.create("output")
xfun::write_utf8(c(
  "---",
  "title: test",
  "---",
  "",
  "```{r}",
  "plot(cars)",
  "```"), "rmd/test.Rmd")
library(rmarkdown)
#' lib_dir is relative to the input directory
#' It will not work here as media will be put in the input directory
render(
  input="rmd/test.Rmd",
  output_format=html_document(
    dev="svg",
    self_contained=FALSE,
    lib_dir="media"),
  output_dir="output", quiet = TRUE)
fs::dir_ls("rmd")
fs::dir_ls("output")
fs::dir_delete("rmd/media")

#' lib_dir is relative to the input directory
render(
  input="rmd/test.Rmd",
  output_format=html_document(
    dev="svg",
    self_contained=FALSE,
    lib_dir="../output/media"),
  output_dir="output", quiet = TRUE)
fs::dir_ls("rmd")
fs::dir_ls("output")
fs::dir_ls("output/media/")
fs::dir_ls("output/test_files/")
fs::dir_delete("output"); fs::dir_create("output")

#' you can use absolute path too but it currently
#' needs to be evaluated before rendering. Otherwise, it will be evaluated later,
#' and getwd() won't be what you expect. It will be the input directory, 
#' from which pandoc is run
xfun::in_dir("output", {
             lib_dir <- paste0(getwd(), "/media")
             render(
               input="../rmd/test.Rmd",
               output_format=html_document(
                 dev="svg",
                 self_contained=FALSE,
                 lib_dir=lib_dir),
               output_dir=".")
})
fs::dir_ls("rmd")
fs::dir_ls("output")
fs::dir_ls("output/media/")
fs::dir_ls("output/test_files/")    

# clean
setwd(old)
fs::dir_delete(tmp_proj)

To improve this, we can document better the lib_dir is relative to the input directory , and I guess we can force the evaluation of lib_dir before changing setwd during the rendering so that an absolute path like paste0(getwd(), "/media") is working as expected (getwd() being the working dir from which render is called.)

cderv avatar Oct 20 '20 11:10 cderv