If you are familiar with R Notebooks, you will know that the HTML output is re-generated every time you save the .Rmd
file.
I tried looking for a similar solution for non-notebook .Rmd
files, but came up empty-handed.
I then tried tweaking my entr
-based approach from my previous post and came up with this shell command that I ran for a bit in RStudio’s built-in terminal:
$ ls filename.Rmd | entr Rscript -e 'rmarkdown::render("filename.Rmd")'
This worked well enough but it was tedious to type out the whole thing. I wondered of the R community on Twitter had an alternative:
Does anyone know how to render output automatically on saving an .Rmd file?
— Achintya Rao • ಅಚಿಂತ್ಯ • अचिंत्य (@RaoOfPhysics) October 5, 2020
For now, I use entr in the terminal:
$ ls filename.Rmd | entr Rscript -e 'rmarkdown::render("filename.Rmd")'
There must be a better way?#rstats #Rmarkdown
However, I didn’t get any help, so I decided to persist on my own.
I remembered that Dirk Eddelbuettel had written a bunch of scripts for his littler
package.
I poked through the examples and came across the render.r
.
This was perfect!
I copied this to my /usr/local/bin
directory and ran chmod +x render.r
to make it an executable.
I tried running the following within the RStudio terminal and it worked, but when I tried using my desktop’s terminal, I got an error:
$ ls filename.Rmd | entr render.r filename.Rmd
Error in library(docopt) : there is no package called ‘docopt’
I didn’t have the time to troubleshoot the issue.
When I replaced r
with Rscript
in the #!
line at the top, the code ran without errors, so I decided to stick with the change (for now).
I then spent some time writing a small bash script so I wouldn’t have to remember to enter the correct filename twice.
I named it redoer
and ran chmod +x redoer
before dropping it into /usr/local/bin
as well.
If you run it without a filename for an argument or with an argument that doesn’t have the .Rmd
extension, it spits out error messages:
$ redoer
Please enter a valid .Rmd filename.
$ redoer dir/
This is not a valid file.
$ redoer filename.html
Please enter a valid .Rmd filename.
I am happy with the result.
It works in both the RStudio terminal and the standalone terminal.
I run the command redoer filename.Rmd
once and it keeps rebuilding the output files as defined in the YAML
frontmatter.
When I am done, I need to hit Ctrl+c to terminate the process.
(It is worth noting that the output files will not open in the RStudio viewer when built.)
Here are the sources for the files, if you want to grab them:
render.r
(© Dirk Eddelbuettel, GPL ≥ 2):
#!/usr/bin/env r
#
# Another example to run a shiny app
#
# (Littler replaced with Rscript by Achintya)
#
# Copyright (C) 2016 Dirk Eddelbuettel
#
# Released under GPL (>= 2)
suppressMessages(library(docopt)) # we need docopt (>= 0.3) as on CRAN
## configuration for docopt
doc <- "Usage: render.r [-h] [-x] [FILES...]
-h --help show this help text
-x --usage show help and short example usage"
opt <- docopt(doc) # docopt parsing
if (opt$usage) {
cat(doc, "\n\n")
cat("Examples:
render.r foo.Rmd bar.Rmd # convert two given files
render.r is part of littler which brings 'r' to the command-line.
See http://dirk.eddelbuettel.com/code/littler.html for more information.\n")
q("no")
}
library(rmarkdown)
## helper function
renderArg <- function(p) {
if (!file.exists(p)) stop("No file '", p, "' found. Aborting.", call.=FALSE)
render(p)
}
## render files using helper function
sapply(opt$FILES, renderArg)
redoer
(© Achintya Rao, CC0):
#! /bin/bash
if [ -f $1 ] ; then
case $1 in
*.Rmd) ls $1 | entr render.r $1;;
*) echo "Please enter a valid .Rmd filename.";;
esac
else
echo "This is not a valid file."
fi
I am a novice with both R
and bash
, so if you have a way to improve any of my code or have suggestions for how to rebuild the R Markdown output files on saving the source files, please annotate this blog post or reach out to me on Scholar.Social or on Twitter.