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

Add more highlighting support for HTML output #1941

Merged
merged 62 commits into from
Jan 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
734c1bd
add an argument defaulting to FALSE and check for downlit package
cderv Oct 6, 2020
c89fc5c
if using downlit, default to pygments and not highlight.js
cderv Oct 6, 2020
f2c8892
Add downlit as post-processing step
cderv Oct 6, 2020
b666a2a
missing bracket
cderv Oct 6, 2020
6cc1989
use dev downlit for Pandoc highlighting support
cderv Oct 29, 2020
b20a651
Correct wording.
cderv Oct 29, 2020
dbc9c43
use xfun here
cderv Nov 4, 2020
559f5f8
Add tests for pandoc syntax highlighting argument
cderv Nov 4, 2020
e35a921
style and add comment about the current logic
cderv Nov 4, 2020
eb1e04d
explicitly add the pandoc classes from downlit
cderv Nov 4, 2020
e7bfead
style
cderv Nov 4, 2020
41ee41f
typo
cderv Nov 4, 2020
5fe312a
separate highlight logic to add specific css in template
cderv Nov 4, 2020
b501a89
modify tests and refactor
cderv Nov 4, 2020
d24216c
document
cderv Nov 4, 2020
5ce2725
textmate does not work with downlit
cderv Nov 4, 2020
859be92
new downlit is on CRAN now
cderv Nov 4, 2020
0e0ed1c
use a11y.theme from distill by default for downlit.
cderv Nov 5, 2020
0cbcfd0
missing theme file
cderv Nov 5, 2020
a3dfe4a
and update test
cderv Nov 5, 2020
ffe52e7
throw an error insted of a warning if downlit engine for syntax highl…
cderv Nov 5, 2020
fa59bd1
new helper to get less wrapping in tests
cderv Nov 5, 2020
fab4098
there is a wrapper for pandoc highlight arg already
cderv Nov 5, 2020
450b02d
rewrite the logic separating highlighting engine from each other
cderv Nov 5, 2020
7fecaa8
allow to provide highlight = "a11y" to get the accessible theme
cderv Nov 5, 2020
6aa0b32
also add rstudio theme from distill
cderv Nov 5, 2020
509ca7a
Document downlit engine better
cderv Nov 6, 2020
b6e5c4c
more details on highlighting in the doc
cderv Nov 6, 2020
37ab96e
Apply suggestions from code review on wording
cderv Nov 6, 2020
41b04c4
missing space after \cr
cderv Nov 6, 2020
7f11dc9
document param on several paragraphs.
cderv Nov 6, 2020
50eb603
Add a section on Highlighting to document what behavior a user should…
cderv Nov 6, 2020
e2007dc
custom themes file for syntax highlighting style are only available f…
cderv Nov 9, 2020
83abaf3
Merge branch 'master' into downlit-support
cderv Nov 24, 2020
fba6bc2
use arrow.theme from https://github.com/rstudio/distill/pull/221
cderv Nov 24, 2020
98e7af9
\href is url then text
cderv Nov 24, 2020
e315e03
texmate can be used with non default template now.
cderv Nov 27, 2020
38a86cf
in fact stick with current behavior for highlight.js as it is safer t…
cderv Nov 27, 2020
1a33c36
Fix an issue with custom template and highlight=textmate
cderv Nov 27, 2020
3ee0e70
update documentation
cderv Nov 27, 2020
8cf69d9
Merge branch 'master' into downlit-support
cderv Nov 27, 2020
a0160b7
Merge branch 'master' into downlit-support
cderv Nov 27, 2020
5a8e474
Merge branch 'master' into downlit-support
cderv Nov 27, 2020
994a7b5
remove comment lines introduced by copy pasting the theme json file
cderv Nov 27, 2020
d88d9e3
reformart rstudio.theme correctly
cderv Nov 27, 2020
a1d40ef
Apply suggestions from code review
cderv Nov 30, 2020
827bfad
Other changes after @hadley's review
cderv Nov 30, 2020
c7e331c
update arrow.theme to last changes
cderv Dec 2, 2020
518d8ae
Add a reminder comment for #1976
cderv Dec 9, 2020
6f32c42
Merge branch 'master' into downlit-support
cderv Dec 15, 2020
deb612d
Merge branch 'master' into downlit-support
cderv Dec 18, 2020
a558848
Arrow theme tweaks from rstudio/distill#338
cderv Mar 10, 2021
26fc6ff
Merge branch 'master' into downlit-support
cderv May 20, 2021
b65bca4
Merge branch 'main' into downlit-support
cderv Jan 13, 2022
b373d09
Merge branch 'main' into downlit-support
cderv Jan 13, 2022
932b0dd
missing word in documentation
cderv Jan 13, 2022
36ce5d2
Update requirement for downlit in Suggests
cderv Jan 13, 2022
d1a9a6b
typo
cderv Jan 13, 2022
2345a80
Correctly test as `template` can be NULL
cderv Jan 13, 2022
d63608d
Add NEWS bullet and bump version
cderv Jan 14, 2022
5f9299d
Rebuild documentation
cderv Jan 14, 2022
0e3863f
Add correct support for highlight_downlit in html_notebook
cderv Jan 14, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -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", , "[email protected]", role = "aut"),
person("Yihui", "Xie", , "[email protected]", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-0645-5666")),
Expand Down Expand Up @@ -75,6 +75,7 @@ Suggests:
dygraphs,
fs,
rsconnect,
downlit (>= 0.4.0),
sass (>= 0.4.0),
shiny (>= 1.6.0),
testthat (>= 3.0.0),
Expand Down
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
129 changes: 114 additions & 15 deletions R/html_document.R
Original file line number Diff line number Diff line change
Expand Up @@ -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
cderv marked this conversation as resolved.
Show resolved Hide resolved
#' 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
Expand Down Expand Up @@ -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)$
#' <style type="text/css">
#' code a:any-link {
#' color: inherit; /* use colour from syntax highlighting */
#' text-decoration: underline;
#' text-decoration-color: #ccc;
#' }
#' </style>
#' $endif$}
#' }}
#'
#'@section Anchor Sections Customization:
#'
#' This will be the default to activate anchor sections link on header
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -255,6 +332,7 @@ html_document <- function(toc = FALSE,
self_contained = TRUE,
theme = "default",
highlight = "default",
highlight_downlit = FALSE,
cderv marked this conversation as resolved.
Show resolved Hide resolved
mathjax = "default",
template = "default",
extra_dependencies = NULL,
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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) {
cderv marked this conversation as resolved.
Show resolved Hide resolved

# 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),
Expand All @@ -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,
Expand Down
5 changes: 5 additions & 0 deletions R/html_notebook.R
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down
73 changes: 57 additions & 16 deletions R/pandoc.R
Original file line number Diff line number Diff line change
Expand Up @@ -553,29 +553,70 @@ unix_mathjax_path <- function() {


pandoc_html_highlight_args <- function(template,
cderv marked this conversation as resolved.
Show resolved Hide resolved
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")
cderv marked this conversation as resolved.
Show resolved Hide resolved
)
} 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
}

Expand Down
4 changes: 4 additions & 0 deletions R/util.R
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Loading