.main <- function() {
spin <- function(input) {
if (utils::packageVersion("knitr") < "1.44") {
stop(
"knitr >= 1.44 is required for rendering with Quarto from `.R` files. ",
"Please update knitr.",
call. = FALSE
)
}
text <- xfun::read_utf8(input)
knitr::spin(text = text, knit = FALSE, format = "qmd")
}
dependencies <- function(
input,
format,
output,
tempDir,
libDir,
data,
quiet
) {
knit_meta <- lapply(data, jsonlite::unserializeJSON)
files_dir <- if (!is.null(libDir)) {
libDir
} else {
rmarkdown:::knitr_files_dir(output)
}
list(
includes = pandoc_includes(
input,
format,
output,
files_dir,
knit_meta,
tempDir
)
)
}
postprocess <- function(input, format, output, preserved_chunks) {
isHTML <- knitr::is_html_output(
format$pandoc$to,
c("markdown", "epub", "gfm", "commonmark", "commonmark_x", "markua")
)
code_link <- isHTML && isTRUE(format$render$`code-link`)
if (length(preserved_chunks) == 0 && code_link == FALSE) {
return()
}
oldwd <- setwd(dirname(rmarkdown:::abs_path(input)))
on.exit(setwd(oldwd), add = TRUE)
input <- basename(input)
r_options <- format$metadata$`r-options`
if (!is.null(r_options)) {
do.call(options, r_options)
}
output_str <- xfun::read_utf8(output)
output_res <- output_str
if (isTRUE(code_link)) {
has_annotations <- function(input) {
inputLines <- readLines(input)
chunkStarts <- grep(knitr::all_patterns$md$chunk.begin, inputLines)
chunkEnds <- grep(knitr::all_patterns$md$chunk.end, inputLines)
annotations <- grep(".*\\Q#\\E\\s*<[0-9]+>\\s*", inputLines)
hasAnnotations <- FALSE
if (length(chunkStarts) > 0 && length(annotations) > 0) {
lastLine <- max(max(chunkEnds), max(chunkStarts), max(annotations))
chunkMap <- rep(FALSE, lastLine)
for (x in seq_along(chunkStarts)) {
start <- chunkStarts[x]
end <- start
for (e in chunkEnds) {
if (e > start) {
end <- e
break
}
}
for (y in start:end) {
if (y > start && y < end) {
chunkMap[y] <- TRUE
}
}
}
for (a in annotations) {
if (chunkMap[a] == TRUE) {
hasAnnotations <- TRUE
break
}
}
}
hasAnnotations
}
if (!has_annotations(input)) {
if (
requireNamespace("downlit", quietly = TRUE) &&
requireNamespace("xml2", quietly = TRUE)
) {
downlit::downlit_html_path(output, output)
downlit_output <- paste(xfun::read_utf8(output), collapse = "\n")
downlit_output <- gsub(
'(</div>)\n(<div class="column")',
"\\1\\2",
downlit_output
)
output_res <- strsplit(downlit_output, "\n", fixed = TRUE)[[1]]
} else {
warning(
"The downlit and xml2 packages are required for code linking",
call. = FALSE
)
}
} else {
warning(
"Since code annotations are present, code-linking has been disabled",
call. = FALSE
)
}
}
if (length(preserved_chunks) > 0) {
names <- names(preserved_chunks)
preserved_chunks <- as.character(preserved_chunks)
names(preserved_chunks) <- names
if (isHTML) {
for (i in names(preserved_chunks)) {
output_res <- gsub(
paste0("<p>", i, "</p>"),
i,
output_res,
fixed = TRUE,
useBytes = TRUE
)
output_res <- gsub(
paste0(' id="[^"]*?', i, '[^"]*?" '),
' ',
output_res,
useBytes = TRUE
)
}
output_res <- htmltools::restorePreserveChunks(
output_res,
preserved_chunks
)
} else {
output_res <- knitr::restore_raw_output(output_str, preserved_chunks)
}
}
if (!identical(output_str, output_res)) {
xfun::write_utf8(output_res, output)
}
}
run <- function(input, port, host) {
shiny_args <- list()
if (!is.null(port)) {
shiny_args$port <- port
}
if (!is.null(host)) {
shiny_args$host <- host
}
Sys.setenv(RMARKDOWN_RUN_PRERENDER = "0")
rmarkdown::run(input, shiny_args = shiny_args)
}
stdin <- file("stdin", "r", encoding = "")
input <- readLines(stdin, warn = FALSE, encoding = "UTF-8")
close(stdin)
request <- jsonlite::parse_json(input, simplifyVector = TRUE)
params <- request$params
setwd(request$wd)
if (!is.null(params$resourceDir)) {
res_dir <- file.path(params$resourceDir, "rmd")
source(file.path(res_dir, "patch.R"), local = TRUE)
source(file.path(res_dir, "execute.R"), local = TRUE)
source(file.path(res_dir, "hooks.R"), local = TRUE)
}
debug <- (!request$action %in% c("spin", "run")) &&
isTRUE(params$format$execute[["debug"]])
if (debug) {
message("[knitr engine]: ", request$action)
}
if (request$action == "spin") {
result <- spin(params$input)
result <- paste(result, collapse = '\n')
} else if (request$action == "execute") {
result <- execute(
params$input,
params$format,
params$tempDir,
params$libDir,
params$dependencies,
params$cwd,
params$params,
params$resourceDir,
params$handledLanguages,
params$markdown
)
} else if (request$action == "dependencies") {
result <- dependencies(
params$input,
params$format,
params$output,
params$tempDir,
params$libDir,
params$dependencies,
params$quiet
)
} else if (request$action == "postprocess") {
result <- postprocess(
params$input,
params$format,
params$output,
params$preserve
)
} else if (request$action == "run") {
result <- run(params$input, params$port, params$host)
}
if (debug) {
message("[knitr engine]: writing results")
}
resultJson <- jsonlite::toJSON(auto_unbox = TRUE, result)
xfun:::write_utf8(paste(resultJson, collapse = "\n"), request[["results"]])
if (debug) message("[knitr engine]: exiting")
}
if (!rmarkdown::pandoc_available(error = FALSE)) {
quarto_bin_path <- Sys.getenv("QUARTO_BIN_PATH", NA_character_)
if (!is.na(quarto_bin_path)) {
pandoc_dir <- normalizePath(file.path(quarto_bin_path, "tools"))
invisible(rmarkdown::find_pandoc(dir = pandoc_dir))
}
}
.main()