Update:
I figured out how to do this. The first step was to write specific book.rmd files (e.g. book1.rmd
) into a temporary directory along with an _output.yml
file. bookdown::render_book()
expects the book.rmd
file to be in the working directory, so my workflow involved a setwd()
statement.
input_file <- "book1.rmd"
#Extract Rmd from project directory
prev_wd <- here::here()
rmd <- readr::read_lines(file.path(prev_wd,paste0("docs/",input_file)))
output <- readr::read_lines(file.path(prev_wd,"docs/_output.yml"))
#Create a temporary directory to build the book
wd <- tempdir()
#bookdown::render_book() requires that your input_file is in the wd
#NOTE: Bookdown will try to knit all Rmds into one (and break) if you try to knit
#directly from /docs
setwd(wd)
You need to make sure the temporary directory is empty prior to dropping in a new .Rmd or else bookdown::render_book()
will try to merge the individual files into a single (breaking) .Rmd file.
Hence:
file.remove(file.path(list.files(wd)))
Next I removed the extension from the filename so I could paste it into a _bookdown.yml
file created inside the temporary directory. This file should be written each time a new .Rmd is rendered.
#Pull out name of file without extension
stock <- stringr::str_remove(input_file, "\\.rmd|\\.Rmd")
#Creates yml file in temp directory. Important for getting download button
temp_book_yml <- paste0('book_filename: "',paste0(stock),'_.rmd"\ndelete_merged_file: true')
I then wrote the .Rmd file of interest and both .yml files (_output + _bookdown) to the temporary directory. Once you've made it this far, you can call bookdown::render_book()
. Note the I've re-routed the rendered bookdown files to my /docs
directory. This is the directory that will host the files as github pages. All html and pdf files are written out to this directory.
#Write critical files for creating book with downloadable pdfs
readr::write_lines(temp_book_yml, file.path(wd, "_bookdown.yml"))
write(rmd, file.path(wd,input_file))
write(output, file.path(wd,"_output.yml"))
bookdown::render_book(input = input_file,
output_format = "all",
output_dir = file.path(prev_wd,"docs"))
My goal is to have simple URLs that can be accessed from the github repo; however, bookdown::render_book()
seems to want input files to have different names from output files (e.g. index.rmd vs. _main.rmd), and will break otherwise. To avert this, I added an underscore to the input filename above and removed it below.
#Simplifies filenames by removing extra underscores. These underscores are necessary to build
#the pdf
file.rename(from = file.path(prev_wd,"docs",paste0(stock,"_.pdf")),
to = file.path(prev_wd,"docs",paste0(stock,".pdf")))
file.rename(from = file.path(prev_wd,"docs",paste0(stock,"_.html")),
to = file.path(prev_wd,"docs",paste0(stock,".html")))
The same thing needs to happen within the output html document, or else you'll be linking to a pdf that doesn't exist
#Read in html and alter pdf filename for downloading
html <- readr::read_lines(file.path(prev_wd, "docs",paste0(stock,".html")))
html <- gsub(paste0(stock,'_\\.pdf'),
paste0(stock,'\\.pdf'),
html)
html <- readr::write_lines(html, file.path(prev_wd, "docs",paste0(stock,".html")))
#Get back to the original directory
setwd(prev_wd)
message(paste(input_file, "rendered to"), prev_wd)
good luck