Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use R6 representation #33

Merged
merged 14 commits into from
Nov 6, 2020
31 changes: 31 additions & 0 deletions R/stylesheet.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
is_stylesheet <- function(stylesheet) {
inherits(stylesheet, "xml_document") &&
length(xml2::xml_name(stylesheet)) == 1L &&
xml2::xml_name(stylesheet) == "stylesheet"
maelle marked this conversation as resolved.
Show resolved Hide resolved
}

read_stylesheet <- function(stylesheet_path) {

# if the stylesheet already is an XML stylesheet, just return.
if (is_stylesheet(stylesheet_path)) {
return(stylesheet_path)
}

null_or_na <- is.null(stylesheet_path) ||
length(stylesheet_path) != 1L ||
any(is.na(stylesheet_path))

if (null_or_na) {
stop("'stylesheet_path' must be a path to an XSL stylesheet", call. = FALSE)
}
if (!file.exists(stylesheet_path)) {
stop(glue::glue("The file '{stylesheet_path}' does not exist."), call. = FALSE)
}
out <- xml2::read_xml(stylesheet_path)
if (is_stylesheet(out)) {
return(out)
} else {
stop(glue::glue('{stylesheet_path} is not a valid stylesheet'))
}

}
50 changes: 36 additions & 14 deletions R/to_md.R
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
#' Write YAML and XML back to disk as (R)Markdown
#'
#' @param yaml_xml_list result from a call to \code{to_xml} and editing.
#' @param path path of the new file
#' @param yaml_xml_list result from a call to [to_xml()] and editing.
#' @param path path of the new file. Defaults to `NULL`, which will not write
#' any file, but will still produce the conversion and pass the output as
#' a character vector.
#' @param stylesheet_path path to the XSL stylesheet
#'
#' @details The stylesheet you use will decide whether lists
#' are built using "*" or "-" for instance. If you're keen to
#' keep your own Markdown style when using \code{to_md} after
#' \code{to_xml}, you can tweak the XSL stylesheet a bit and provide
#' the path to your XSL stylesheet as argument.
#' keep your own Markdown style when using [to_md()] after
#' [to_xml()], you can tweak the XSL stylesheet a bit and provide
#' the path to your XSL stylesheet as argument.
#'
#'
#' @return the converted document, invisibly.
#'
#' @export
#'
Expand All @@ -31,25 +36,42 @@
#' # file.edit("newmd.md")
#' file.remove(newmd)
#'
to_md <- function(yaml_xml_list, path,
to_md <- function(yaml_xml_list, path = NULL,
stylesheet_path = system.file("extdata", "xml2md_gfm.xsl", package = "tinkr")){

stylesheet_path %>%
xml2::read_xml() -> stylesheet

# duplicate document to avoid overwriting
body <- copy_xml(yaml_xml_list$body)
yaml <- yaml_xml_list$yaml

# read stylesheet and fail early if it doesn't exist
stylesheet <- read_stylesheet(stylesheet_path)

transform_code_blocks(body)

md_out <- transform_to_md(body, yaml, stylesheet)

if (!is.null(path)) {
writeLines(md_out, con = path, useBytes = TRUE, sep = "\n\n")
}

invisible(md_out)
}

# convert body and yaml to markdown text given a stylesheet
transform_to_md <- function(body, yaml, stylesheet) {
if (!is_stylesheet(stylesheet)) {
stop(glue::glue(
"stylesheet should be an object of class 'xml_document' ",
"where the top-level element is a <stylesheet>, ",
"not an object of class ",
"'{glue::glue_collapse(class(stylesheet), sep = ', ')}'"
))
}
body <- xslt::xml_xslt(body, stylesheet = stylesheet)

yaml_xml_list$yaml %>%
glue::glue_collapse(sep = "\n") -> yaml
yaml <- glue::glue_collapse(yaml, sep = "\n")

writeLines(c(yaml, body), con = path,
useBytes = TRUE,
sep = "\n\n")
c(yaml, body)
}

copy_xml <- function(xml) {
Expand Down
15 changes: 10 additions & 5 deletions man/to_md.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions man/yarn.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.