diff --git a/.lintr b/.lintr index 34473d27..0a0bb22f 100644 --- a/.lintr +++ b/.lintr @@ -1,5 +1,6 @@ linters: linters_with_defaults( line_length_linter = line_length_linter(120), cyclocomp_linter = NULL, - object_usage_linter = NULL + object_usage_linter = NULL, + indentation_linter = NULL ) diff --git a/DESCRIPTION b/DESCRIPTION index 99ec742e..7c0ff475 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -31,6 +31,7 @@ Imports: zip (>= 1.1.0) Suggests: DT (>= 0.13), + formatR (>= 1.5), ggplot2 (>= 3.4.0), lattice (>= 0.18-4), png, @@ -44,8 +45,8 @@ RdMacros: Config/Needs/verdepcheck: rstudio/bslib, mllg/checkmate, rstudio/htmltools, yihui/knitr, r-lib/lifecycle, r-lib/R6, rstudio/rmarkdown, rstudio/shiny, dreamRs/shinyWidgets, - yaml=vubiostat/r-yaml, r-lib/zip, davidgohel/flextable, rstudio/DT, - tidyverse/ggplot2, deepayan/lattice, cran/png, + yaml=vubiostat/r-yaml, r-lib/zip, davidgohel/flextable, rstudio/DT, + yihui/formatR, tidyverse/ggplot2, deepayan/lattice, cran/png, insightsengineering/rtables, r-lib/testthat, rstudio/tinytex Config/Needs/website: insightsengineering/nesttemplate Encoding: UTF-8 diff --git a/NEWS.md b/NEWS.md index a210d1ef..54b61fff 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,8 @@ * `add_card_button_srv` allows to specify `card_fun` with `label` parameter for card's title & content customization. +* Supports automatic `Rcode` formatting using the suggested `formatR` package in reports. + # teal.reporter 0.2.1 ### Miscellaneous diff --git a/R/DownloadModule.R b/R/DownloadModule.R index f3f080a8..147b5269 100644 --- a/R/DownloadModule.R +++ b/R/DownloadModule.R @@ -33,11 +33,16 @@ download_report_button_ui <- function(id) { #' For more details see the vignette: `vignette("simpleReporter", "teal.reporter")`. #' @param id `character(1)` this `shiny` module's id. #' @param reporter [`Reporter`] instance. +#' @param global_knitr `list` a of `knitr` parameters (passed to `knitr::opts_chunk$set`) +#' for customizing the rendering process. #' @inheritParams reporter_download_inputs #' @return `shiny::moduleServer` +#' @details `r global_knitr_details()` +#' #' @export download_report_button_srv <- function(id, reporter, + global_knitr = getOption("teal.reporter.global_knitr"), rmd_output = c( "html" = "html_document", "pdf" = "pdf_document", "powerpoint" = "powerpoint_presentation", "word" = "word_document" @@ -48,6 +53,7 @@ download_report_button_srv <- function(id, toc = FALSE )) { checkmate::assert_class(reporter, "Reporter") + checkmate::assert_subset(names(global_knitr), names(knitr::opts_chunk$get())) checkmate::assert_subset( rmd_output, c( @@ -134,8 +140,7 @@ download_report_button_srv <- function(id, shiny::showNotification("Rendering and Downloading the document.") input_list <- lapply(names(rmd_yaml_args), function(x) input[[x]]) names(input_list) <- names(rmd_yaml_args) - global_knitr <- list() - if (is.logical(input$showrcode)) global_knitr <- list(echo = input$showrcode) + if (is.logical(input$showrcode)) global_knitr[["echo"]] <- input$showrcode report_render_and_compress(reporter, input_list, global_knitr, file) }, contentType = "application/zip" diff --git a/R/Previewer.R b/R/Previewer.R index 7ccaf2ff..41a3d913 100644 --- a/R/Previewer.R +++ b/R/Previewer.R @@ -31,10 +31,15 @@ reporter_previewer_ui <- function(id) { #' For more details see the vignette: `vignette("previewerReporter", "teal.reporter")`. #' @param id `character(1)` this `shiny` module's id. #' @param reporter `Reporter` instance +#' @param global_knitr `list` a of `knitr` parameters (passed to `knitr::opts_chunk$set`) +#' for customizing the rendering process. #' @inheritParams reporter_download_inputs +#' @details `r global_knitr_details()` +#' #' @export reporter_previewer_srv <- function(id, reporter, + global_knitr = getOption("teal.reporter.global_knitr"), rmd_output = c( "html" = "html_document", "pdf" = "pdf_document", "powerpoint" = "powerpoint_presentation", @@ -45,6 +50,7 @@ reporter_previewer_srv <- function(id, toc = FALSE )) { checkmate::assert_class(reporter, "Reporter") + checkmate::assert_subset(names(global_knitr), names(knitr::opts_chunk$get())) checkmate::assert_subset( rmd_output, c( @@ -179,8 +185,7 @@ reporter_previewer_srv <- function(id, shiny::showNotification("Rendering and Downloading the document.") input_list <- lapply(names(rmd_yaml_args), function(x) input[[x]]) names(input_list) <- names(rmd_yaml_args) - global_knitr <- list() - if (is.logical(input$showrcode)) global_knitr <- list(echo = input$showrcode) + if (is.logical(input$showrcode)) global_knitr[["echo"]] <- input$showrcode report_render_and_compress(reporter, input_list, global_knitr, file) }, contentType = "application/zip" diff --git a/R/Renderer.R b/R/Renderer.R index 1ce2be5b..f086cc82 100644 --- a/R/Renderer.R +++ b/R/Renderer.R @@ -22,14 +22,16 @@ Renderer <- R6::R6Class( # nolint: object_name_linter. #' @description getting the `Rmd` text which could be easily rendered later. #' #' @param blocks `list` of `c("TextBlock", "PictureBlock", "NewpageBlock")` objects. - #' @param yaml_header `character` a `rmarkdown` `yaml` header. - #' @param global_knitr `list` a global `knitr` parameters, like echo. - #' But if local parameter is set it will have priority. - #' Defaults to empty `list()`. + #' @param yaml_header `character` an `rmarkdown` `yaml` header. + #' @param global_knitr `list` a of `knitr` parameters (passed to `knitr::opts_chunk$set`) + #' for customizing the rendering process. + #' @details `r global_knitr_details()` #' #' @return `character` a `Rmd` text (`yaml` header + body), ready to be rendered. - renderRmd = function(blocks, yaml_header, global_knitr = list()) { + renderRmd = function(blocks, yaml_header, global_knitr = getOption("teal.reporter.global_knitr")) { checkmate::assert_list(blocks, c("TextBlock", "PictureBlock", "NewpageBlock", "TableBlock", "RcodeBlock")) + checkmate::assert_subset(names(global_knitr), names(knitr::opts_chunk$get())) + if (missing(yaml_header)) { yaml_header <- md_header(yaml::as.yaml(list(title = "Report"))) } @@ -84,13 +86,13 @@ Renderer <- R6::R6Class( # nolint: object_name_linter. #' #' @param blocks `list` of `c("TextBlock", "PictureBlock", "NewpageBlock")` objects. #' @param yaml_header `character` an `rmarkdown` `yaml` header. - #' @param global_knitr `list` a global `knitr` parameters, like echo. - #' But if local parameter is set it will have priority. - #' Defaults to empty `list()`. - #' @param ... `rmarkdown::render` arguments, `input` and `output_dir` should not be updated.z + #' @param global_knitr `list` a of `knitr` parameters (passed to `knitr::opts_chunk$set`) + #' for customizing the rendering process. + #' @param ... `rmarkdown::render` arguments, `input` and `output_dir` should not be updated. + #' @details `r global_knitr_details()` #' #' @return `character` path to the output - render = function(blocks, yaml_header, global_knitr = list(), ...) { + render = function(blocks, yaml_header, global_knitr = getOption("teal.reporter.global_knitr"), ...) { args <- list(...) input_path <- self$renderRmd(blocks, yaml_header, global_knitr) args <- append(args, list( diff --git a/R/ReportCard.R b/R/ReportCard.R index 37f902bf..49352409 100644 --- a/R/ReportCard.R +++ b/R/ReportCard.R @@ -60,7 +60,7 @@ ReportCard <- R6::R6Class( # nolint: object_name_linter. self$append_content(TextBlock$new(text, style)) invisible(self) }, - #' @description Appends a `rmarkdown` R chunk to this `ReportCard`. + #' @description Appends an `rmarkdown` R chunk to this `ReportCard`. #' #' @param text (`character(0)` or `character(1)`) the text #' @param ... any `rmarkdown` R chunk parameter and its value. diff --git a/R/SimpleReporter.R b/R/SimpleReporter.R index a5f0d1bb..6766fab9 100644 --- a/R/SimpleReporter.R +++ b/R/SimpleReporter.R @@ -46,12 +46,16 @@ simple_reporter_ui <- function(id) { #' @param reporter [`Reporter`] instance. #' @param card_fun `function` which returns a [`ReportCard`] instance, #' the function has a `card` argument and an optional `comment` argument. +#' @param global_knitr `list` a global `knitr` parameters for customizing the rendering process. #' @inheritParams reporter_download_inputs +#' @details `r global_knitr_details()` +#' #' @return `shiny::moduleServer` #' @export simple_reporter_srv <- function(id, reporter, card_fun, + global_knitr = getOption("teal.reporter.global_knitr"), rmd_output = c( "html" = "html_document", "pdf" = "pdf_document", "powerpoint" = "powerpoint_presentation", "word" = "word_document" @@ -68,6 +72,7 @@ simple_reporter_srv <- function(id, download_report_button_srv( "download_button_simple", reporter = reporter, + global_knitr = global_knitr, rmd_output = rmd_output, rmd_yaml_args = rmd_yaml_args ) diff --git a/R/utils.R b/R/utils.R index 59064a22..c9b10403 100644 --- a/R/utils.R +++ b/R/utils.R @@ -277,3 +277,21 @@ split_text_block <- function(x, n) { ind <- rep(1:nblocks, each = n)[seq_along(lines)] unname(lapply(split(lines, ind), paste, collapse = "\n")) } + +#' Retrieve text details for global_knitr options +#' This function returns a character string describing the default settings for the global_knitr options. +#' @noRd +#' +#' @keywords internal +global_knitr_details <- function() { + paste0( + c( + " To access the default values for the `global_knitr` parameter,", + " use `getOption('teal.reporter.global_knitr')`. These defaults include:", + " - `echo = TRUE`", + " - `tidy.opts = list(width.cutoff = 60)`", + " - `tidy = TRUE` if `formatR` package is installed, `FALSE` otherwise" + ), + collapse = "\n" + ) +} diff --git a/R/zzz.R b/R/zzz.R new file mode 100644 index 00000000..61c594fc --- /dev/null +++ b/R/zzz.R @@ -0,0 +1,22 @@ +.onLoad <- function(libname, pkgname) { + op <- options() + default_global_knitr <- list(teal.reporter.global_knitr = list( + echo = TRUE, + tidy.opts = list(width.cutoff = 60), + tidy = requireNamespace("formatR", quietly = TRUE) + )) + + if (!("teal.reporter.global_knitr" %in% names(op))) { + options(default_global_knitr) + } + + invisible() +} + +.onAttach <- function(libname, pkgname) { + packageStartupMessage( + if (!requireNamespace("formatR", quietly = TRUE)) { + "For better code formatting, consider installing the formatR package." + } + ) +} diff --git a/man/Renderer.Rd b/man/Renderer.Rd index e2e2610e..990d95c2 100644 --- a/man/Renderer.Rd +++ b/man/Renderer.Rd @@ -53,7 +53,11 @@ Finalizes a \code{Renderer} object. \subsection{Method \code{renderRmd()}}{ getting the \code{Rmd} text which could be easily rendered later. \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{Renderer$renderRmd(blocks, yaml_header, global_knitr = list())}\if{html}{\out{
}} +\if{html}{\out{
}}\preformatted{Renderer$renderRmd( + blocks, + yaml_header, + global_knitr = getOption("teal.reporter.global_knitr") +)}\if{html}{\out{
}} } \subsection{Arguments}{ @@ -61,14 +65,23 @@ getting the \code{Rmd} text which could be easily rendered later. \describe{ \item{\code{blocks}}{\code{list} of \code{c("TextBlock", "PictureBlock", "NewpageBlock")} objects.} -\item{\code{yaml_header}}{\code{character} a \code{rmarkdown} \code{yaml} header.} +\item{\code{yaml_header}}{\code{character} an \code{rmarkdown} \code{yaml} header.} -\item{\code{global_knitr}}{\code{list} a global \code{knitr} parameters, like echo. -But if local parameter is set it will have priority. -Defaults to empty \code{list()}.} +\item{\code{global_knitr}}{\code{list} a of \code{knitr} parameters (passed to \code{knitr::opts_chunk$set}) +for customizing the rendering process.} } \if{html}{\out{}} } +\subsection{Details}{ +To access the default values for the \code{global_knitr} parameter, +use \code{getOption('teal.reporter.global_knitr')}. These defaults include: +\itemize{ +\item \code{echo = TRUE} +\item \code{tidy.opts = list(width.cutoff = 60)} +\item \code{tidy = TRUE} if \code{formatR} package is installed, \code{FALSE} otherwise +} +} + \subsection{Returns}{ \code{character} a \code{Rmd} text (\code{yaml} header + body), ready to be rendered. } @@ -79,7 +92,12 @@ Defaults to empty \code{list()}.} \subsection{Method \code{render()}}{ Renders the content of this \code{Report} to the output file \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{Renderer$render(blocks, yaml_header, global_knitr = list(), ...)}\if{html}{\out{
}} +\if{html}{\out{
}}\preformatted{Renderer$render( + blocks, + yaml_header, + global_knitr = getOption("teal.reporter.global_knitr"), + ... +)}\if{html}{\out{
}} } \subsection{Arguments}{ @@ -89,14 +107,23 @@ Renders the content of this \code{Report} to the output file \item{\code{yaml_header}}{\code{character} an \code{rmarkdown} \code{yaml} header.} -\item{\code{global_knitr}}{\code{list} a global \code{knitr} parameters, like echo. -But if local parameter is set it will have priority. -Defaults to empty \code{list()}.} +\item{\code{global_knitr}}{\code{list} a of \code{knitr} parameters (passed to \code{knitr::opts_chunk$set}) +for customizing the rendering process.} -\item{\code{...}}{\code{rmarkdown::render} arguments, \code{input} and \code{output_dir} should not be updated.z} +\item{\code{...}}{\code{rmarkdown::render} arguments, \code{input} and \code{output_dir} should not be updated.} } \if{html}{\out{}} } +\subsection{Details}{ +To access the default values for the \code{global_knitr} parameter, +use \code{getOption('teal.reporter.global_knitr')}. These defaults include: +\itemize{ +\item \code{echo = TRUE} +\item \code{tidy.opts = list(width.cutoff = 60)} +\item \code{tidy = TRUE} if \code{formatR} package is installed, \code{FALSE} otherwise +} +} + \subsection{Returns}{ \code{character} path to the output } diff --git a/man/ReportCard.Rd b/man/ReportCard.Rd index 4a563a17..204ff30f 100644 --- a/man/ReportCard.Rd +++ b/man/ReportCard.Rd @@ -255,7 +255,7 @@ invisibly self \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ReportCard-append_rcode}{}}} \subsection{Method \code{append_rcode()}}{ -Appends a \code{rmarkdown} R chunk to this \code{ReportCard}. +Appends an \code{rmarkdown} R chunk to this \code{ReportCard}. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{ReportCard$append_rcode(text, ...)}\if{html}{\out{
}} } diff --git a/man/download_report_button_srv.Rd b/man/download_report_button_srv.Rd index 18ced465..28b22b44 100644 --- a/man/download_report_button_srv.Rd +++ b/man/download_report_button_srv.Rd @@ -7,6 +7,7 @@ download_report_button_srv( id, reporter, + global_knitr = getOption("teal.reporter.global_knitr"), rmd_output = c(html = "html_document", pdf = "pdf_document", powerpoint = "powerpoint_presentation", word = "word_document"), rmd_yaml_args = list(author = "NEST", title = "Report", date = @@ -18,6 +19,9 @@ download_report_button_srv( \item{reporter}{\code{\link{Reporter}} instance.} +\item{global_knitr}{\code{list} a of \code{knitr} parameters (passed to \code{knitr::opts_chunk$set}) +for customizing the rendering process.} + \item{rmd_output}{\code{character} vector with \code{rmarkdown} output types, by default all possible \code{c("pdf_document", "html_document", "powerpoint_presentation", "word_document")}. If vector is named then those names will appear in the \code{UI}.} @@ -37,3 +41,12 @@ server for downloading the Report. For more details see the vignette: \code{vignette("simpleReporter", "teal.reporter")}. } +\details{ +To access the default values for the \code{global_knitr} parameter, +use \code{getOption('teal.reporter.global_knitr')}. These defaults include: +\itemize{ +\item \code{echo = TRUE} +\item \code{tidy.opts = list(width.cutoff = 60)} +\item \code{tidy = TRUE} if \code{formatR} package is installed, \code{FALSE} otherwise +} +} diff --git a/man/reporter_previewer_srv.Rd b/man/reporter_previewer_srv.Rd index bc1a15f5..cea7f90c 100644 --- a/man/reporter_previewer_srv.Rd +++ b/man/reporter_previewer_srv.Rd @@ -7,6 +7,7 @@ reporter_previewer_srv( id, reporter, + global_knitr = getOption("teal.reporter.global_knitr"), rmd_output = c(html = "html_document", pdf = "pdf_document", powerpoint = "powerpoint_presentation", word = "word_document"), rmd_yaml_args = list(author = "NEST", title = "Report", date = @@ -18,6 +19,9 @@ reporter_previewer_srv( \item{reporter}{\code{Reporter} instance} +\item{global_knitr}{\code{list} a of \code{knitr} parameters (passed to \code{knitr::opts_chunk$set}) +for customizing the rendering process.} + \item{rmd_output}{\code{character} vector with \code{rmarkdown} output types, by default all possible \code{c("pdf_document", "html_document", "powerpoint_presentation", "word_document")}. If vector is named then those names will appear in the \code{UI}.} @@ -33,3 +37,12 @@ The default value for \code{"output"} has to be in the \code{rmd_output} argumen server supporting the functionalities of the reporter previewer For more details see the vignette: \code{vignette("previewerReporter", "teal.reporter")}. } +\details{ +To access the default values for the \code{global_knitr} parameter, +use \code{getOption('teal.reporter.global_knitr')}. These defaults include: +\itemize{ +\item \code{echo = TRUE} +\item \code{tidy.opts = list(width.cutoff = 60)} +\item \code{tidy = TRUE} if \code{formatR} package is installed, \code{FALSE} otherwise +} +} diff --git a/man/simple_reporter_srv.Rd b/man/simple_reporter_srv.Rd index 741fcf50..dbbec8fe 100644 --- a/man/simple_reporter_srv.Rd +++ b/man/simple_reporter_srv.Rd @@ -8,6 +8,7 @@ simple_reporter_srv( id, reporter, card_fun, + global_knitr = getOption("teal.reporter.global_knitr"), rmd_output = c(html = "html_document", pdf = "pdf_document", powerpoint = "powerpoint_presentation", word = "word_document"), rmd_yaml_args = list(author = "NEST", title = "Report", date = @@ -22,6 +23,8 @@ simple_reporter_srv( \item{card_fun}{\code{function} which returns a \code{\link{ReportCard}} instance, the function has a \code{card} argument and an optional \code{comment} argument.} +\item{global_knitr}{\code{list} a global \code{knitr} parameters for customizing the rendering process.} + \item{rmd_output}{\code{character} vector with \code{rmarkdown} output types, by default all possible \code{c("pdf_document", "html_document", "powerpoint_presentation", "word_document")}. If vector is named then those names will appear in the \code{UI}.} @@ -43,3 +46,12 @@ and the reset module the \code{reset_button_simple} id. For more details see the vignette: \code{vignette("simpleReporter", "teal.reporter")}. } +\details{ +To access the default values for the \code{global_knitr} parameter, +use \code{getOption('teal.reporter.global_knitr')}. These defaults include: +\itemize{ +\item \code{echo = TRUE} +\item \code{tidy.opts = list(width.cutoff = 60)} +\item \code{tidy = TRUE} if \code{formatR} package is installed, \code{FALSE} otherwise +} +}