#' Containerize R Markdown Documents
#'
#' @description
#' Containerize R Markdown documents. This function generates
#' \code{Dockerfile} based on the liftr metadata in the RMD document.
#'
#' @details
#' After running \link{lift}, run \link{render_docker} on the document to
#' render the containerized R Markdown document using Docker containers.
#' See \code{vignette('liftr-intro')} for details about the extended
#' YAML front-matter metadata format used by liftr.
#'
#' @param input Input (R Markdown) file.
#' @param use_config If \code{TRUE}, will parse the liftr metadata from
#' a YAML file, if \code{FALSE}, will parse such information from the
#' metadata section in the R Markdown file. Default is \code{FALSE}.
#' @param config_file Name of the YAML configuration file, under the
#' same directory as the input file. Default is \code{"_liftr.yml"}.
#' @param output_dir Directory to output \code{Dockerfile}.
#' If not provided, will be the same directory as \code{input}.
#'
#' @return \code{Dockerfile}.
#'
#' @export lift
#'
#' @importFrom knitr knit
#' @importFrom yaml yaml.load
#'
#' @examples
#' # copy example file
#' dir_example = paste0(tempdir(), '/liftr-minimal/')
#' dir.create(dir_example)
#' file.copy(system.file("examples/liftr-minimal.Rmd", package = "liftr"), dir_example)
#'
#' # containerization
#' input = paste0(dir_example, "liftr-minimal.Rmd")
#' lift(input)
#'
#' \dontrun{
#' # render the document with Docker
#' render_docker(input)
#'
#' # view rendered document
#' browseURL(paste0(dir_example, "liftr-minimal.html"))
#'
#' # purge the generated Docker image
#' purge_image(paste0(dir_example, "liftr-minimal.docker.yml"))}
lift = function(
input = NULL,
use_config = FALSE, config_file = '_liftr.yml',
output_dir = NULL) {
if (is.null(input))
stop('missing input file')
if (!file.exists(normalizePath(input)))
stop('input file does not exist')
if (!use_config) {
# locate YAML metadata block
doc_content = readLines(normalizePath(input))
header_pos = which(doc_content == '---')
# handling YAML blocks ending with three dots
if (length(header_pos) == 1L) {
header_dot_pos = which(doc_content == '...')
if (length(header_dot_pos) == 0L) {
stop('Cannot correctly locate YAML metadata block.
Please use three hyphens (---) as start line & end line,
or three hyphens (---) as start line with three dots (...)
as end line.')
} else {
header_pos[2L] = header_dot_pos[1L]
}
}
doc_yaml = paste(
doc_content[(header_pos[1L] + 1L):(header_pos[2L] - 1L)],
collapse = '\n')
opt_all_list = yaml.load(doc_yaml)
# liftr options handling
if (is.null(opt_all_list$liftr))
stop('Cannot find `liftr` option in file header')
opt_list = opt_all_list$liftr
}
if (use_config) {
liftrfile_path = paste0(file_dir(input), '/', config_file)
if (!file.exists(normalizePath(liftrfile_path)))
stop('The YAML config file does not exist')
opt_list = yaml.load_file(liftrfile_path)
}
# base image
liftr_from = parse_from(opt_list$from)
# maintainer's name
liftr_maintainer = parse_maintainer(opt_list$maintainer)
# maintainer's email
liftr_email = parse_email(opt_list$email)
# system dependencies
liftr_sysdeps = parse_sysdeps(opt_list$sysdeps)
# texlive
liftr_texlive = parse_texlive(opt_list$texlive)
# pandoc
liftr_pandoc = parse_pandoc(liftr_from, opt_list$pandoc)
# CRAN packages
liftr_cran = parse_cran(opt_list$cran)
# Bioconductor packages
liftr_bioc = parse_bioc(opt_list$bioc)
# remote packages
liftr_remotes = parse_remotes(opt_list$remotes)
# custom Dockerfile snippet
liftr_include = parse_include(input, opt_list$include)
# factory packages
liftr_factory = quote_str(c(
'devtools', 'BiocManager','knitr', 'rmarkdown', 'shiny', 'RCurl'))
# write output files
if (is.null(output_dir)) output_dir = file_dir(input)
output_dockerfile = paste0(normalizePath(output_dir), '/Dockerfile')
invisible(knit(
system.file('templates/base.Rmd', package = 'liftr'),
output = output_dockerfile, quiet = TRUE))
# remove consecutive blank lines
out = readLines(output_dockerfile)
out = sanitize_blank(out)
writeLines(out, output_dockerfile)
invisible(out)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.