diff --git a/DESCRIPTION b/DESCRIPTION index 8e44da66f0..2812f98d60 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: rmarkdown Title: Dynamic Documents for R -Version: 2.11.6 +Version: 2.11.7 Authors@R: c( person("JJ", "Allaire", , "jj@rstudio.com", role = "aut"), person("Yihui", "Xie", , "xie@yihui.name", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-0645-5666")), @@ -75,6 +75,7 @@ Suggests: dygraphs, fs, rsconnect, + downlit (>= 0.4.0), sass (>= 0.4.0), shiny (>= 1.6.0), testthat (>= 3.0.0), diff --git a/NEWS.md b/NEWS.md index d9420952da..005c0bffa0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,11 @@ rmarkdown 2.12 ================================================================================ +- Improved the highlighting mechanism for HTML outputs: + * It is now possible to pass a custom theme file `.theme` in `highlight` argument for customizing the [syntax highlighting style used by Pandoc](https://pandoc.org/MANUAL.html#syntax-highlighting). + * In addition to Pandoc's own supported themes, two more themes are bundled in the package: `highlight: arrow` a theme [optimized for accessibility and color constrast](https://www.a11yproject.com/) (thanks to @apreshill), and `highlight: rstudio` to mimic the RStudio editor theme. + * Added optional [downlit](https://downlit.r-lib.org/) support in `html_document()` for R syntax highlighting and autolinking. Use `highlight_downlit = TRUE` to activate it (same argument as in **distill**). This features require the **downlit** package. + - Added a global option `rmarkdown.html_dependency.header_attr` (`TRUE` by default). It can be set to `FALSE` to opt-out the HTML dependency `html_dependency_header_attrs()` in documents based on `html_document_base()` (thanks, @salim-b rstudio/bookdown#865, @maelle r-lib/downlit#1538). - `draft()` now works with `devtools::load_all()` and **testthat** when used in other packages. diff --git a/R/html_document.R b/R/html_document.R index 4fa16716f7..e0fd4d5508 100644 --- a/R/html_document.R +++ b/R/html_document.R @@ -58,9 +58,33 @@ #' * `NULL` for no theme (i.e., no [html_dependency_bootstrap()]). #' * A character string specifying a [Bootswatch 3](https://bootswatch.com/3/) #' theme name (for backwards-compatibility). -#'@param highlight Syntax highlighting style. Supported styles include -#' "default", "tango", "pygments", "kate", "monochrome", "espresso", "zenburn", -#' "haddock", and "textmate". Pass \code{NULL} to prevent syntax highlighting. +#'@param highlight Syntax highlight engine and style. See the +#' \emph{Highlighting} section below for details. +#' +#' "default" (and "textmate") will use highlightjs as syntax highlighting +#' engine instead of Pandoc. +#' +#' Any other value will be passed to Pandoc's +#' \href{https://pandoc.org/MANUAL.html#syntax-highlighting}{highlighting +#' style}. Pandoc's built-in styles include "tango", "pygments", "kate", +#' "monochrome", "espresso", "zenburn", "haddock" and "breezedark". +#' +#' Two custom styles are also included, "arrow", an accessible color scheme, +#' and "rstudio", which mimics the default IDE theme. Alternatively, supply a +#' path to a \samp{.theme} to use a custom Pandoc style. Note that custom theme +#' requires Pandoc 2.0+. +#' +#' Pass \code{NULL} to prevent syntax highlighting. +#' +#'@param highlight_downlit \code{TRUE} to use the \pkg{downlit} package as +#' syntax highlight engine to highlight inline code and R code chunks +#' (including providing hyperlinks to function documentation). The package +#' needs to be installed to use this feature. +#' +#' Only Pandoc color schemes are supported with this engine. With +#' \code{highlight = "default"}, it will use the accessible theme called +#' "arrow". To learn more about \pkg{downlit} highlighting engine, see +#' \url{https://downlit.r-lib.org/}. #'@param mathjax Include mathjax. The "default" option uses an https URL from a #' MathJax CDN. The "local" option uses a local version of MathJax (which is #' copied into the output directory). You can pass an alternate URL or pass @@ -91,6 +115,56 @@ #' base R Markdown HTML output formatter \code{\link{html_document_base}} #'@return R Markdown output format to pass to \code{\link{render}} #' +#'@section Highlighting: +#' +#' There are three highlighting engines available to HTML documents: +#' +#' \describe{ +#' \item{highlightjs}{It does highlighting in the browser, using javascript It +#' can only be used with the default template (i.e \code{template = "default"}) +#' and it has two styles ("default" and "textmate"). When activated, it adds +#' two additional dependencies to the output file: a JS script and a CSS file. +#' For now, this is the default engine for the default template - this could +#' change in the future.} +#' +#' \item{Pandoc}{Pandoc's built-in highlighting.engine works with any template, +#' default or custom, and style can be chosen among the built-in ones ("tango", +#' "pygments", "kate", "monochrome", "espresso", "zenburn", "haddock" and +#' "breezedark") or a path to a custom theme ".theme" file (see Details in the +#' \href{https://pandoc.org/MANUAL.html#syntax-highlighting}{Pandoc Manual}). +#' \pkg{rmarkdown} includes two custom themes to select with \code{highlight} +#' parameter: +#' \itemize{ +#' \item{"arrow", an accessible style using colors \href{https://www.a11yproject.com/}{optimized for +#' accessibility and color contrast}} +#' \item{"rstudio", a color scheme close to RStudio's default highlighting and +#' highglightjs's textmate.} +#' } +#' Custom themes are only available for Pandoc 2.0 and above.} +#' +#' \item{downlit}{\href{https://downlit.r-lib.org/}{\pkg{downlit}} is an R package that +#' provides a syntax highlighting engine in R. It will also do automatic +#' linking of R code (requires internet connectivity). It is activated only if +#' \code{highlight_downlit = TRUE} and only affects R code, leaving +#' highlighting for other languages unchanged. The default color scheme is +#' the accessible theme "arrow". +#' +#' It requires some CSS in the template to correctly style links. This is included +#' in the default template, but if you want to use with a custom template, you will +#' need to add this to your template: +#' +#' \preformatted{ +#' $if(highlight-downlit)$ +#' +#' $endif$} +#' }} +#' #'@section Anchor Sections Customization: #' #' This will be the default to activate anchor sections link on header @@ -214,16 +288,19 @@ #' Note however that if you choose not to use the "default" HTML template then #' several aspects of HTML document rendering will behave differently: #' -#' \itemize{ \item{The \code{theme} parameter does not work (you can still -#' provide styles using the \code{css} parameter). } \item{For the -#' \code{highlight} parameter, the default highlighting style will resolve to -#' "pygments" and the "textmate" highlighting style is not available } -#' \item{The \code{toc_float} parameter will not work. } \item{The -#' \code{code_folding} parameter will not work. } \item{Tabbed sections (as -#' described above) will not work.} \item{Navigation bars (as described above) -#' will not work. }\item{MathJax will not work if \code{self_contained} is -#' \code{TRUE} (these two options can't be used together in normal pandoc -#' templates). } } +#' \itemize{ +#' \item{The \code{theme} parameter does not work (you can still provide styles +#' using the \code{css} parameter). } +#' \item{For the \code{highlight} parameter, the default highlighting engine +#' will resolve to Pandoc instead of highlightjs and highlighting style will default to +#' "pygments". "textmate" style is not available as related to highlightjs} +#' \item{The \code{toc_float} parameter will not work. } +#' \item{The \code{code_folding} parameter will not work. } +#' \item{Tabbed sections (as described above) will not work.} +#' \item{Navigation bars (as described above) will not work. } +#' \item{MathJax will not work if \code{self_contained} is \code{TRUE} (these +#' two options can't be used together in normal pandoc templates). } +#' } #' #' Due to the above restrictions, you might consider using the \code{includes} #' parameter as an alternative to providing a fully custom template. @@ -255,6 +332,7 @@ html_document <- function(toc = FALSE, self_contained = TRUE, theme = "default", highlight = "default", + highlight_downlit = FALSE, mathjax = "default", template = "default", extra_dependencies = NULL, @@ -345,8 +423,14 @@ html_document <- function(toc = FALSE, ) } - # highlight - args <- c(args, pandoc_html_highlight_args(template, highlight)) + # highlighting --------- + if (highlight_downlit && !xfun::loadable("downlit")) { + stop("highlight_downlit=TRUE requires the downlit package to be installed.", + call. = FALSE) + } + args <- c(args, + pandoc_html_highlight_args(template, highlight, highlight_downlit) + ) # add highlight.js html_dependency if required extra_dependencies <- append( @@ -497,6 +581,20 @@ html_document <- function(toc = FALSE, args } + # post-processor that uses the output file from pandoc + post_processor <- function(metadata, input_file, output_file, clean, verbose) { + + # add a post processor for syntax highlighting with downlit if requested + if (highlight_downlit) { + output_file <- downlit::downlit_html_path( + output_file, output_file, + classes = downlit::classes_pandoc() + ) + } + + output_file + } + # return format output_format( knitr = knitr_options_html(fig_width, fig_height, fig_retina, keep_md, dev), @@ -510,6 +608,7 @@ html_document <- function(toc = FALSE, pre_knit = pre_knit, post_knit = post_knit, pre_processor = pre_processor, + post_processor = post_processor, on_exit = on_exit, base_format = html_document_base(theme = theme, self_contained = self_contained, diff --git a/R/html_notebook.R b/R/html_notebook.R index 019aedad8b..9dc435c465 100644 --- a/R/html_notebook.R +++ b/R/html_notebook.R @@ -27,6 +27,7 @@ html_notebook <- function(toc = FALSE, code_folding = "show", theme = "default", highlight = "textmate", + highlight_downlit = FALSE, mathjax = "default", extra_dependencies = NULL, css = NULL, @@ -189,6 +190,9 @@ html_notebook <- function(toc = FALSE, extra_dependencies <- append(extra_dependencies, list(html_dependency_pagedtable())) + # Change default value of highlight theme if downlit is to be used + if (highlight_downlit && missing(highlight)) highlight <- "default" + # generate actual format base_format <- html_document(toc = toc, toc_depth = toc_depth, @@ -201,6 +205,7 @@ html_notebook <- function(toc = FALSE, code_folding = code_folding, theme = theme, highlight = highlight, + highlight_downlit = highlight_downlit, mathjax = mathjax, extra_dependencies = extra_dependencies, css = css, diff --git a/R/pandoc.R b/R/pandoc.R index bb715b91ff..fe60b28e0a 100644 --- a/R/pandoc.R +++ b/R/pandoc.R @@ -553,29 +553,70 @@ unix_mathjax_path <- function() { pandoc_html_highlight_args <- function(template, - highlight) { + highlight, + highlight_downlit = FALSE) { + + # Reminder: we do not use pandoc_path_arg() for argument to --highlight-style + # https://github.com/rstudio/rmarkdown/issues/1976 args <- c() - if (is.null(highlight)) { - args <- c(args, "--no-highlight") - } - else if (!identical(template, "default")) { - if (identical(highlight, "default")) - highlight <- "pygments" - args <- c(args, "--highlight-style", highlight) - } - else { - highlight <- match.arg(highlight, html_highlighters()) - if (is_highlightjs(highlight)) { - args <- c(args, "--no-highlight") - args <- c(args, "--variable", "highlightjs=1") + # no highlighting engine + if (is.null(highlight)) return(pandoc_highlight_args(NULL)) + + # TODO: move out so that it works also for other formats + resolve_highlight <- function(highlight) { + # if Pandoc built-in highlighter, do no nothing + if (highlight %in% highlighters()) return(highlight) + if (!pandoc2.0()) { + stop("Using a custom highlighting style requires Pandoc 2.0 and above", + call. = FALSE) } - else { - args <- c(args, "--highlight-style", highlight) + custom <- list( + # from distill + # https://raw.githubusercontent.com/apreshill/distill/arrow/inst/rmarkdown/templates/distill_article/resources/arrow.theme + arrow = pkg_file_highlight("arrow.theme"), + # from distill + # https://github.com/rstudio/distill/blob/c98d332192ff75f268ddf69bddace34e4db6d89b/inst/rmarkdown/templates/distill_article/resources/rstudio.theme + rstudio = pkg_file_highlight("rstudio.theme") + ) + # if not an alias use the provided custom path + custom[[highlight]] %||% highlight + } + highlight <- resolve_highlight(highlight) + + check_highlightjs <- function(highlight, engine) { + if (highlight != "default" && is_highlightjs(highlight)) { + stop( + sprintf(c( + "'%s' theme is for highlightjs highlighting engine ", + "and can't be used with %s engine."), c(highlight, engine)), + call. = FALSE + ) } } + # downlit engine + if (highlight_downlit) { + check_highlightjs(highlight, "downlit") + default <- if (pandoc2.0()) resolve_highlight("arrow") else "pygments" + args <- c( + pandoc_highlight_args(highlight, default = default), + # variable used to insert some css in a Pandoc template + pandoc_variable_arg("highlight-downlit") + ) + } else if (identical(template, "default") && is_highlightjs(highlight)) { + # highlightjs engine for default template only + args <- c(pandoc_highlight_args(NULL), + # variable used to insert some css and js + # in the Pandoc default template + pandoc_variable_arg("highlightjs", "1")) + } else { + # Pandoc engine + check_highlightjs(highlight, "Pandoc") + args <- pandoc_highlight_args(highlight, default = "pygments") + } + args } diff --git a/R/util.R b/R/util.R index 3a9a748ec1..aa32d788e0 100644 --- a/R/util.R +++ b/R/util.R @@ -89,6 +89,10 @@ pkg_file_lua <- function(filters = NULL, package = "rmarkdown") { pandoc_path_arg(files) } +pkg_file_highlight <- function(file) { + pkg_file("rmarkdown", "highlight", file, mustWork = TRUE) +} + #' @rdname rmarkdown_format #' @export from_rmarkdown <- function(implicit_figures = TRUE, extensions = NULL) { diff --git a/inst/rmarkdown/highlight/arrow.theme b/inst/rmarkdown/highlight/arrow.theme new file mode 100644 index 0000000000..e3f35d56c5 --- /dev/null +++ b/inst/rmarkdown/highlight/arrow.theme @@ -0,0 +1,211 @@ +{ + "text-color": null, + "background-color": null, + "line-number-color": "#aaaaaa", + "line-number-background-color": null, + "text-styles": { + "Other": { + "text-color": "#007BA5", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Attribute": { + "text-color": null, + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "SpecialString": { + "text-color": "#20794D", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Annotation": { + "text-color": "#5E5E5E", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Function": { + "text-color": "#4758AB", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "String": { + "text-color": "#20794D", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "ControlFlow": { + "text-color": "#007BA5", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Operator": { + "text-color": "#5E5E5E", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Error": { + "text-color": "#AD0000", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "BaseN": { + "text-color": "#AD0000", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Alert": { + "text-color": "#AD0000", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Variable": { + "text-color": "#111111", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "BuiltIn": { + "text-color": null, + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Extension": { + "text-color": null, + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Preprocessor": { + "text-color": "#AD0000", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Information": { + "text-color": "#5E5E5E", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "VerbatimString": { + "text-color": "#20794D", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Warning": { + "text-color": "#5E5E5E", + "background-color": null, + "bold": false, + "italic": true, + "underline": false + }, + "Documentation": { + "text-color": "#5E5E5E", + "background-color": null, + "bold": false, + "italic": true, + "underline": false + }, + "Import": { + "text-color": null, + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Char": { + "text-color": "#20794D", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "DataType": { + "text-color": "#AD0000", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Float": { + "text-color": "#AD0000", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Comment": { + "text-color": "#5E5E5E", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "CommentVar": { + "text-color": "#5E5E5E", + "background-color": null, + "bold": false, + "italic": true, + "underline": false + }, + "Constant": { + "text-color": "#8f5902", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "SpecialChar": { + "text-color": "#5E5E5E", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "DecVal": { + "text-color": "#AD0000", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Keyword": { + "text-color": "#007BA5", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + } + } +} diff --git a/inst/rmarkdown/highlight/rstudio.theme b/inst/rmarkdown/highlight/rstudio.theme new file mode 100644 index 0000000000..e638834d91 --- /dev/null +++ b/inst/rmarkdown/highlight/rstudio.theme @@ -0,0 +1,190 @@ +{ + "text-color": null, + "background-color": null, + "line-number-color": "#aaaaaa", + "line-number-background-color": null, + "text-styles": { + "Other": { + "text-color": "#ff4000", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Attribute": { + "text-color": null, + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "SpecialString": { + "text-color": "#008080", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Annotation": { + "text-color": "#008000", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "String": { + "text-color": "#036a07", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "DecVal": { + "text-color": "#0000cd", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Float": { + "text-color": "#0000cd", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "ControlFlow": { + "text-color": "#0000ff", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Operator": { + "text-color": "#687687", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Error": { + "text-color": "#ff0000", + "background-color": null, + "bold": true, + "italic": false, + "underline": false + }, + "Alert": { + "text-color": "#ff0000", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Variable": { + "text-color": null, + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "BuiltIn": { + "text-color": null, + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Extension": { + "text-color": null, + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Preprocessor": { + "text-color": "#ff4000", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Information": { + "text-color": "#008000", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "VerbatimString": { + "text-color": "#008080", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Warning": { + "text-color": "#008000", + "background-color": null, + "bold": true, + "italic": false, + "underline": false + }, + "Documentation": { + "text-color": "#008000", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Import": { + "text-color": null, + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Char": { + "text-color": "#008080", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Comment": { + "text-color": "#4c886b", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "CommentVar": { + "text-color": "#008000", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Constant": { + "text-color": "#585cf6", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "SpecialChar": { + "text-color": "#008080", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + }, + "Keyword": { + "text-color": "#0000ff", + "background-color": null, + "bold": false, + "italic": false, + "underline": false + } + } +} diff --git a/inst/rmd/h/default.html b/inst/rmd/h/default.html index e0dd5be0bb..1ef7109d01 100644 --- a/inst/rmd/h/default.html +++ b/inst/rmd/h/default.html @@ -58,6 +58,17 @@ $endif$ +$if(highlight-downlit)$ + +$endif$ + $if(highlighting-css)$ + $endif$} +}} +} + \section{Anchor Sections Customization}{ @@ -300,16 +377,19 @@ the basic pandoc template by passing \code{template = NULL}. Note however that if you choose not to use the "default" HTML template then several aspects of HTML document rendering will behave differently: -\itemize{ \item{The \code{theme} parameter does not work (you can still -provide styles using the \code{css} parameter). } \item{For the -\code{highlight} parameter, the default highlighting style will resolve to -"pygments" and the "textmate" highlighting style is not available } -\item{The \code{toc_float} parameter will not work. } \item{The -\code{code_folding} parameter will not work. } \item{Tabbed sections (as -described above) will not work.} \item{Navigation bars (as described above) -will not work. }\item{MathJax will not work if \code{self_contained} is -\code{TRUE} (these two options can't be used together in normal pandoc -templates). } } +\itemize{ +\item{The \code{theme} parameter does not work (you can still provide styles +using the \code{css} parameter). } +\item{For the \code{highlight} parameter, the default highlighting engine +will resolve to Pandoc instead of highlightjs and highlighting style will default to +"pygments". "textmate" style is not available as related to highlightjs} +\item{The \code{toc_float} parameter will not work. } +\item{The \code{code_folding} parameter will not work. } +\item{Tabbed sections (as described above) will not work.} +\item{Navigation bars (as described above) will not work. } +\item{MathJax will not work if \code{self_contained} is \code{TRUE} (these +two options can't be used together in normal pandoc templates). } +} Due to the above restrictions, you might consider using the \code{includes} parameter as an alternative to providing a fully custom template. diff --git a/man/html_notebook.Rd b/man/html_notebook.Rd index aab9f258cb..06fb2fd337 100644 --- a/man/html_notebook.Rd +++ b/man/html_notebook.Rd @@ -16,6 +16,7 @@ html_notebook( code_folding = "show", theme = "default", highlight = "textmate", + highlight_downlit = FALSE, mathjax = "default", extra_dependencies = NULL, css = NULL, @@ -72,9 +73,33 @@ parameter may utilize the \code{theme}'s underlying Sass utilities theme name (for backwards-compatibility). }} -\item{highlight}{Syntax highlighting style. Supported styles include -"default", "tango", "pygments", "kate", "monochrome", "espresso", "zenburn", -"haddock", and "textmate". Pass \code{NULL} to prevent syntax highlighting.} +\item{highlight}{Syntax highlight engine and style. See the +\emph{Highlighting} section below for details. + +"default" (and "textmate") will use highlightjs as syntax highlighting +engine instead of Pandoc. + +Any other value will be passed to Pandoc's +\href{https://pandoc.org/MANUAL.html#syntax-highlighting}{highlighting +style}. Pandoc's built-in styles include "tango", "pygments", "kate", +"monochrome", "espresso", "zenburn", "haddock" and "breezedark". + +Two custom styles are also included, "arrow", an accessible color scheme, +and "rstudio", which mimics the default IDE theme. Alternatively, supply a +path to a \samp{.theme} to use a custom Pandoc style. Note that custom theme +requires Pandoc 2.0+. + +Pass \code{NULL} to prevent syntax highlighting.} + +\item{highlight_downlit}{\code{TRUE} to use the \pkg{downlit} package as +syntax highlight engine to highlight inline code and R code chunks +(including providing hyperlinks to function documentation). The package +needs to be installed to use this feature. + +Only Pandoc color schemes are supported with this engine. With +\code{highlight = "default"}, it will use the accessible theme called +"arrow". To learn more about \pkg{downlit} highlighting engine, see +\url{https://downlit.r-lib.org/}.} \item{mathjax}{Include mathjax. The "default" option uses an https URL from a MathJax CDN. The "local" option uses a local version of MathJax (which is diff --git a/tests/testthat/test-pandoc.R b/tests/testthat/test-pandoc.R index 7b60ca80ae..d96f572521 100644 --- a/tests/testthat/test-pandoc.R +++ b/tests/testthat/test-pandoc.R @@ -1,6 +1,64 @@ # TODO: to remove when switching the package to edition 3 local_edition(3) +test_that("build highlight args for pandoc correctly", { + hl_style <- function(name) c("--highlight-style", name) + expect_equal(pandoc_highlight_args(NULL), "--no-highlight") + expect_equal(pandoc_highlight_args("default"), hl_style("tango")) + expect_equal(pandoc_highlight_args("default", "zenburn"), hl_style("zenburn")) + expect_equal(pandoc_highlight_args("zenburn"), hl_style("zenburn")) +}) + + +test_that("Correct HTML highlighting argument as requested", { + # helpers + hl_args <- function(highlight, template, downlit = FALSE) { + pandoc_html_highlight_args(template = template, highlight = highlight, + highlight_downlit = downlit) + } + hl_style <- pandoc_highlight_args + downlit <- pandoc_variable_arg("highlight-downlit") + highlightjs <- pandoc_variable_arg("highlightjs", "1") + arrow_theme <- hl_style(pkg_file_highlight("arrow.theme")) + rstudio_theme <- hl_style(pkg_file_highlight("rstudio.theme")) + # check logic + # no engine + expect_equal(hl_args(NULL, "default"), hl_style(NULL)) + expect_equal(hl_args(NULL, "dummy.html"), hl_style(NULL)) + # pandoc + expect_equal(hl_args("default", "dummy.html"), hl_style("pygments")) + expect_equal(hl_args("zenburn", "dummy.html"), hl_style("zenburn")) + expect_equal(hl_args("breezedark", "default"), hl_style("breezedark")) + # highlight + expect_equal(hl_args("default", "default"), c(hl_style(NULL), highlightjs)) + expect_equal(hl_args("textmate", "default"), c(hl_style(NULL), highlightjs)) + expect_error(hl_args("textmate", "dummy.html"), "Pandoc engine") + # downlit + expect_equal(hl_args("tango", "default", TRUE), c(hl_style("tango"), downlit)) + expect_equal(hl_args("tango", "dummy.html", TRUE), c(hl_style("tango"), downlit)) + expect_error(hl_args("textmate", "dummy.html", TRUE), "downlit engine") + expect_error(hl_args("textmate", "default", TRUE), "downlit engine") + # custom theme + skip_if_not(pandoc2.0()) + expect_equal(hl_args("default", "default", TRUE), c(arrow_theme, downlit)) + expect_equal(hl_args("default", "dummy.html", TRUE), c(arrow_theme, downlit)) + expect_equal(hl_args("arrow", "default", FALSE), c(arrow_theme)) + expect_equal(hl_args("arrow", "dummy.html", FALSE), c(arrow_theme)) + expect_equal(hl_args("rstudio", "default", TRUE), c(rstudio_theme, downlit)) + expect_equal(hl_args("rstudio", "dummy.html", TRUE), c(rstudio_theme, downlit)) + expect_equal(hl_args("path/to.theme", "default"), c(hl_style("path/to.theme"))) + expect_equal(hl_args("path/to.theme", "dummy.html"), c(hl_style("path/to.theme"))) +}) + +test_that("detect highlightjs theme", { + expect_false(is_highlightjs(NULL)) + expect_false(is_highlightjs("zenburn")) + expect_false(is_highlightjs("path/to/hl.theme")) + + expect_true(is_highlightjs("default")) + expect_true(is_highlightjs("textmate")) +}) + test_that("Converting bib file is working", { skip_on_cran() skip_if_not_pandoc("2.11") # only test with newer Pandoc citeproc