diff --git a/DESCRIPTION b/DESCRIPTION index 068be9a1b85ef2ced5f6df044b836fa3738d43ea..19311b4d882018c7d1817fc513af0b4190700d6f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,20 +1,22 @@ Package: fairify Title: Produce FAIR reports with Rmarkdown and data in the cloud Version: 0.0.0.9000 -Authors@R: +Authors@R: person("David", "Dorchies", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-6595-7984"), email = "david.dorchies@inrae.fr") Description: R-package proposing a framework to apply FAIR principles based on reports created using the bookdown R-package and published as a website (e.g. gitlab pages) and data located on a owncloud/nextcloud server. License: AGPL (>= 3) Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.3 -Imports: +Imports: bookdown, gert, magrittr, + rlang, usethis, - yaml -Suggests: + yaml, + zlib +Suggests: testthat (>= 3.0.0), tinytex Config/testthat/edition: 3 diff --git a/NAMESPACE b/NAMESPACE index 69bee355ce198689b048f789318fb191b8e30f8b..463745ba2479984957340ea089bf2091b8726353 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -6,6 +6,8 @@ export(add_report) export(create_fairify) export(create_reports) export(iconv_filename) +export(mermaid) +export(mermaid_gen_link) export(pkg_sys) export(purge_string) export(render_report) diff --git a/R/mermaid.R b/R/mermaid.R new file mode 100644 index 0000000000000000000000000000000000000000..1dffaa2da21ad41c20d0a31199a12d6617bccee0 --- /dev/null +++ b/R/mermaid.R @@ -0,0 +1,88 @@ +#' Generate a file from a mermaid diagram +#' +#' This function download the file from https://mermaid.ink which generates the image. +#' The file is downloaded only if it does not already exist. +#' +#' @details +#' Use this function with [knitr::include_graphics] to display a mermaid diagram +#' in a Rmarkdown document. Compared to the `diagrammeR::mermaid` function, the +#' generated image is not a HTMLwidget and can be knit in pdf through latex and +#' moreover, its size can be controlled with `fig.width` and `fig.height`. +#' +#' @param diagram Diagram in mermaid markdown-like language or file (as a connection or file name) containing a diagram specification +#' @param theme Mermaid theme (See https://mermaid.js.org/config/theming.html#available-themes) +#' @param format Image format (either `"jpg"`, or `"png"`, or `"svg"`) +#' @param file Path to the downloaded image +#' +#' @return The path to the downloaded image. +#' @export +#' @rdname mermaid +#' +#' @examples +#' diagram <- "flowchart LR\n A --> B" +#' mermaid_gen_link(diagram) +#' f <- mermaid(diagram) +#' f +#' \dontrun{ +#' # For displaying the diagram in Rmarkdown document +#' knitr::include_graphics(mermaid(diagram)) +#' } +#' +#' # Clean temporary folder +#' unlink(f) +mermaid <- function(diagram, + format = "png", + theme = "default", + file = file.path(tempdir(), paste0(rlang::hash(diagram), ".", format))) { + if (!file.exists(file)) { + link <- mermaid_gen_link(diagram, theme = theme, format = format) + download.file(link, file, quiet = TRUE, mode = "wb") + } + return(file) +} + +#' Compress data in pako format +#' +#' @param data [character] data to compress +#' +#' @return Raw compresses data. +#' @source Translated from python script +#' https://github.com/mermaid-js/mermaid-live-editor/discussions/1291#discussioncomment-6837936 +#' @noRd +pako_deflate <- function(data) { + # compress = zlib.compressobj(9, zlib.DEFLATED, 15, 8,zlib.Z_DEFAULT_STRATEGY) + compress <- zlib::compressobj( + level = 9, + method = zlib::zlib$DEFLATED, + wbits = 15, + memLevel = 8, + strategy = zlib::zlib$Z_DEFAULT_STRATEGY + ) + compressed_data <- compress$compress(charToRaw(data)) + compressed_data <- c(compressed_data, compress$flush()) +return(compressed_data) +} + +#' @rdname mermaid +#' @export +mermaid_gen_link <- function(diagram, theme = "default", format = "png") { + is_connection_or_file <- inherits(diagram[1], "connection") || + file.exists(diagram[1]) + if (is_connection_or_file) { + diagram <- readLines(diagram, encoding = "UTF-8", warn = FALSE) + } + if (length(diagram) > 1) { + diagram <- paste(diagram, collapse = "\n") + } + jGraph <- + list(code = diagram, + mermaid = list(theme = theme)) |> jsonlite::toJSON(auto_unbox = TRUE) + deflated <- pako_deflate(jGraph) + dEncode = gsub("\n", "", jsonlite::base64url_enc(deflated)) + mode <- ifelse(format != "svg", "img", "svg") + link = sprintf('https://mermaid.ink/%s/pako:%s', mode, dEncode) + if (format != "svg") { + link <- paste0(link, "?type=", format) + } + return(link) +} diff --git a/man/mermaid.Rd b/man/mermaid.Rd new file mode 100644 index 0000000000000000000000000000000000000000..6d8a3f9cafee5efd689afd9f4d524c80075bab34 --- /dev/null +++ b/man/mermaid.Rd @@ -0,0 +1,51 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/mermaid.R +\name{mermaid} +\alias{mermaid} +\alias{mermaid_gen_link} +\title{Generate a file from a mermaid diagram} +\usage{ +mermaid( + diagram, + format = "png", + theme = "default", + file = file.path(tempdir(), paste0(rlang::hash(diagram), ".", format)) +) + +mermaid_gen_link(diagram, theme = "default", format = "png") +} +\arguments{ +\item{diagram}{Diagram in mermaid markdown-like language or file (as a connection or file name) containing a diagram specification} + +\item{format}{Image format (either \code{"jpg"}, or \code{"png"}, or \code{"svg"})} + +\item{theme}{Mermaid theme (See https://mermaid.js.org/config/theming.html#available-themes)} + +\item{file}{Path to the downloaded image} +} +\value{ +The path to the downloaded image. +} +\description{ +This function download the file from https://mermaid.ink which generates the image. +The file is downloaded only if it does not already exist. +} +\details{ +Use this function with \link[knitr:include_graphics]{knitr::include_graphics} to display a mermaid diagram +in a Rmarkdown document. Compared to the \code{diagrammeR::mermaid} function, the +generated image is not a HTMLwidget and can be knit in pdf through latex and +moreover, its size can be controlled with \code{fig.width} and \code{fig.height}. +} +\examples{ +diagram <- "flowchart LR\n A --> B" +mermaid_gen_link(diagram) +f <- mermaid(diagram) +f +\dontrun{ +# For displaying the diagram in Rmarkdown document +knitr::include_graphics(mermaid(diagram)) +} + +# Clean temporary folder +unlink(f) +} diff --git a/tests/testthat/test-mermaid.R b/tests/testthat/test-mermaid.R new file mode 100644 index 0000000000000000000000000000000000000000..b15546772f6c2667808d29f0c8bcbbcf49c02d50 --- /dev/null +++ b/tests/testthat/test-mermaid.R @@ -0,0 +1,7 @@ +test_that("Conversion of mmd to pako works", { + diagram <- "flowchart LR\n A --> B" + pako <- "https://mermaid.ink/img/pako:eNqrVkrOT0lVslJKy8kvT85ILCpR8AmKyVNQcFTQ1bVTcFLSUcpNLcpNzExRsqpWKslIzQUpTklNSyzNKVGqrQUAjIcUfg?type=png" + expect_equal(mermaid_gen_link(diagram), pako) + diagram <- strsplit(diagram, "\n")[[1]] + expect_equal(mermaid_gen_link(diagram), pako) +})