# Render one xaringan deck as the online deck, the offline deck, or both.
# The .Rmd YAML is the online profile (xaringan CDN defaults).
# The offline profile only overrides chakra, mathjax, and the output file name.

render_xaringan_slide <- function(input, profile = c("online", "offline", "both")) {
  profile <- match.arg(profile)
  input <- normalizePath(input, winslash = "/", mustWork = TRUE)

  if (identical(profile, "both")) {
    render_xaringan_slide(input, "online")
    render_xaringan_slide(input, "offline")
    return(invisible(input))
  }

  stem <- tools::file_path_sans_ext(basename(input))
  if (identical(profile, "online")) {
    output_file <- paste0(stem, ".html")
    output_options <- NULL
  } else {
    output_file <- paste0(stem, "-offline.html")
    rel_root <- remark_asset_prefix(dirname(input))
    output_options <- list(
      chakra = paste0(rel_root, "/assets-remarkjs/remark-latest.min.js"),
      mathjax = paste0(rel_root, "/vendor/mathjax/load-mathjax.js")
    )
  }

  rmarkdown::render(
    input = input,
    output_file = output_file,
    output_options = output_options,
    envir = new.env(parent = globalenv()),
    quiet = FALSE
  )
}

remark_asset_prefix <- function(input_dir) {
  input_dir <- normalizePath(input_dir, winslash = "/", mustWork = TRUE)
  root <- normalizePath(here::here(), winslash = "/", mustWork = TRUE)
  if (!startsWith(paste0(input_dir, "/"), paste0(root, "/")) && !identical(input_dir, root)) {
    stop("Input is outside the project root: ", input_dir)
  }
  extra <- substring(input_dir, nchar(root) + 2L)
  if (!nzchar(extra)) {
    return(".")
  }
  depth <- length(strsplit(extra, "/", fixed = TRUE)[[1]])
  paste(rep("..", depth), collapse = "/")
}
