From 50d6bb7ed3242246fca0e5849c8b59f77a7d4288 Mon Sep 17 00:00:00 2001 From: Yihui Xie Date: Tue, 24 Jan 2017 22:20:50 -0600 Subject: [PATCH] close #29: make it possible to refer to files in other directories --- NEWS.md | 2 ++ R/render.R | 24 +++++++++++++++++++----- R/utils.R | 4 ++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/NEWS.md b/NEWS.md index 65623ea..7810cc4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,8 @@ - A class `title-slide` was added to the automatically generated title slide (`moon_reader(seal = TRUE)`) so that you can customize the this slide using CSS (thanks, @ekstroem, #7). +- Added an argument `cast_from` to `infinite_moon_reader()` to specify the root directory of the server. Previously the root directory is the directory of the Rmd input file, which makes it impossible for the Rmd document to use resources in upper-level directories (e.g. `![](../gif/cute-kittens.gif)`). Now you can set the working directory to the upper-level directory and call `inf_mr('relative/path/to/input.Rmd')`, so that `input.Rmd` can use any files under the current working directory `./` (thanks, @pat-s, #29). + ## BUG FIXES - A local copy of MathJax should work with `moon_reader()` (thanks, @bnicenboim, #13). diff --git a/R/render.R b/R/render.R index 64ca8d2..ab96812 100644 --- a/R/render.R +++ b/R/render.R @@ -155,9 +155,12 @@ tsukuyomi = function(...) moon_reader(...) #' \code{inf_mr()} is an alias of \code{infinite_moon_reader()}. #' #' The Rmd document is compiled continuously to trap the world in the Infinite -#' Tsukuyomi. +#' Tsukuyomi. The genjutsu is cast from the directory specified by +#' \code{cast_from}, and the Rinne Sharingan will be reflected off of the +#' \code{moon}. #' @param moon The input Rmd file path (if missing and in RStudio, the current #' active document is used). +#' @param cast_from The root directory of the server. #' @references \url{http://naruto.wikia.com/wiki/Infinite_Tsukuyomi} #' @note This function is not really tied to the output format #' \code{\link{moon_reader}()}. You can use it to serve any single-HTML-file R @@ -165,7 +168,7 @@ tsukuyomi = function(...) moon_reader(...) #' @seealso \code{servr::\link{httw}} #' @export #' @rdname inf_mr -infinite_moon_reader = function(moon) { +infinite_moon_reader = function(moon, cast_from = '.') { # when this function is called via the RStudio addin, use the dir of the # current active document if (missing(moon) && requireNamespace('rstudioapi', quietly = TRUE)) { @@ -183,14 +186,25 @@ infinite_moon_reader = function(moon) { basename(moon), '".' ) } - moon = normalizePath(moon, mustWork = TRUE) + moon = normalize_path(moon) rebuild = function(...) { if (moon %in% normalizePath(c(...))) rmarkdown::render( moon, envir = globalenv(), encoding = 'UTF-8' ) } - html = rebuild(moon) # render slides initially - servr::httw(dirname(moon), initpath = basename(html), handler = rebuild) + html = normalize_path(rebuild(moon)) # render slides initially + d = normalize_path(cast_from) + f = rmarkdown::relative_to(d, html) + # see if the html output file is under the dir cast_from + if (f == html) { + d = dirname(html) + f = basename(html) + warning( + "Cannot use '", cast_from, "' as the root directory of the server because ", + "the HTML output is not under this directory. Using '", d, "' instead." + ) + } + servr::httw(d, initpath = f, handler = rebuild) } #' @export diff --git a/R/utils.R b/R/utils.R index 773b253..f7ad1e7 100644 --- a/R/utils.R +++ b/R/utils.R @@ -11,6 +11,10 @@ example_css = function() htmltools::htmlDependency( 'remark-css', '0.0.1', pkg_resource(), stylesheet = 'example.css', all_files = FALSE ) +normalize_path = function(path) { + normalizePath(path, winslash = '/', mustWork = TRUE) +} + # a simple JSON serializer tojson = function(x) { if (is.null(x)) return('null')