From d137af5c36d0ebc178e104914f60969ceea9d628 Mon Sep 17 00:00:00 2001 From: Jay Hesselberth Date: Thu, 19 Dec 2024 20:08:27 -0700 Subject: [PATCH 1/6] Improve support for katex math rendering. Closes #2704 --- NEWS.md | 3 ++- R/external-deps.R | 17 +---------------- R/markdown.R | 8 +++++++- R/test.R | 12 ++++++++++++ inst/BS5/assets/katex-auto.js | 14 -------------- inst/BS5/templates/head.html | 8 +++++++- man/test-math-examples.Rd | 12 ++++++++++++ tests/testthat/_snaps/init.md | 1 - tests/testthat/test-build-article.R | 2 +- 9 files changed, 42 insertions(+), 35 deletions(-) delete mode 100644 inst/BS5/assets/katex-auto.js diff --git a/NEWS.md b/NEWS.md index 9ff5b63ff..db4767983 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,7 @@ # pkgdown (development version) -* Articles (i.e., vignettes in `vignettes/articles`, created by `usethis::use_article()` and available on pkgdown sites but not included in a built package) have improved test cases (thanks to @venpopov and @ethanbass). +* Support for math rendering using katex (`math-rendering: katex`) was improved and now includes necessary components using CDN (#2704). +* Articles (i.e., Rmarkdown/Quarto documents in `vignettes/articles`, created by `usethis::use_article()` and available on pkgdown sites but not included in a built package) have improved test cases (thanks to @venpopov and @ethanbass). * New `clean_site(force = TRUE)` for cleaning of `docs/` regardless of whether it was built by pkgdown (#2827). * Links to favicons in page headers were updated to reflect changes to https://realfavicongenerator.net/ (#2804). Favicons should be re-generated by manually removing the `pkgdown/favicon` directory and then running `pkgdown::build_favicons()`. * Reinstate Rd macro loading, which was accidentally disabled in v2.1.1 (#2782). diff --git a/R/external-deps.R b/R/external-deps.R index c084bf7c1..39596f62b 100644 --- a/R/external-deps.R +++ b/R/external-deps.R @@ -70,21 +70,6 @@ math_dependency <- function(pkg, call = caller_env()) { ) ) ) - } else if (math == "katex") { - cached_dependency( - name = "KaTex", - version = "0.16.10", - files = list( - list( - url = "https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.js", - integrity = "sha384-hIoBPJpTUs74ddyc4bFZSM1TVlQDA60VBbJS0oA934VSz82sBx1X7kSx2ATBDIyd" - ), - list( - url = "https://cdn.jsdelivr.net/npm/katex@0.16.10/dist/katex.min.css", - integrity = "sha384-wcIxkf4k558AjM3Yz3BBFQUbk/zgIYC2R0QpeeYb+TwlBVMrlgLqwRjRtGZiK7ww" - ) - ) - ) } else { NULL } @@ -136,7 +121,7 @@ compute_hash <- function(path, size) { con <- file(path, encoding = "UTF-8") openssl::base64_encode(openssl::sha2(con, size)) } - + parse_integrity <- function(x) { size <- as.integer(regmatches(x, regexpr("(?<=^sha)\\d{3}", x, perl = TRUE))) hash <- regmatches(x, regexpr("(?<=^sha\\d{3}-).+", x, perl = TRUE)) diff --git a/R/markdown.R b/R/markdown.R index 8fae5ef21..6de9962fc 100644 --- a/R/markdown.R +++ b/R/markdown.R @@ -109,6 +109,7 @@ convert_markdown_to_html <- function(pkg, in_path, out_path, ...) { cli::cli_abort("Pandoc not available") } } + rmarkdown::pandoc_convert( input = in_path, output = out_path, @@ -120,7 +121,12 @@ convert_markdown_to_html <- function(pkg, in_path, out_path, ...) { "--indented-code-classes=R", "--section-divs", "--wrap=none", - paste0("--", config_math_rendering(pkg)), + ifelse( + # katex is handled separately + config_math_rendering(pkg) == "katex", + "", + paste0("--", config_math_rendering(pkg)) + ), ... )) ) diff --git a/R/test.R b/R/test.R index db9928ddd..986f0ee4b 100644 --- a/R/test.R +++ b/R/test.R @@ -285,6 +285,18 @@ NULL #' #' \deqn{y = \alpha + \beta X + \varepsilon} #' +#' Multi-line equation (correctly rendered by katex only): +#' +#' \deqn{\mathit{Minimize} \space l \\ +#' \mathit{subject \space to} \\ +#' \sum_{i = 1}^{I} x_i r_{ij} + y_j \geq t_j \forall j \in J \\ +#' l \geq \frac{y_j}{t_j} \forall j \in J \\ +#' \sum_{i = 1}^{I} x_i c_i \leq B}{ +#' Minimize l subject to +#' sum_i^I (xi * rij) + yj >= tj for all j in J & +#' l >= (yj / tj) for all j in J & +#' sum_i^I (xi * ci) <= B} +#' #' @name test-math-examples #' @keywords internal #' @family tests diff --git a/inst/BS5/assets/katex-auto.js b/inst/BS5/assets/katex-auto.js deleted file mode 100644 index 20651d9fd..000000000 --- a/inst/BS5/assets/katex-auto.js +++ /dev/null @@ -1,14 +0,0 @@ -// https://github.com/jgm/pandoc/blob/29fa97ab96b8e2d62d48326e1b949a71dc41f47a/src/Text/Pandoc/Writers/HTML.hs#L332-L345 -document.addEventListener("DOMContentLoaded", function () { - var mathElements = document.getElementsByClassName("math"); - var macros = []; - for (var i = 0; i < mathElements.length; i++) { - var texText = mathElements[i].firstChild; - if (mathElements[i].tagName == "SPAN") { - katex.render(texText.data, mathElements[i], { - displayMode: mathElements[i].classList.contains("display"), - throwOnError: false, - macros: macros, - fleqn: false - }); - }}}); diff --git a/inst/BS5/templates/head.html b/inst/BS5/templates/head.html index 94f3e394b..b67467099 100644 --- a/inst/BS5/templates/head.html +++ b/inst/BS5/templates/head.html @@ -12,8 +12,14 @@ {{/has_favicons}} +{{#uses_katex}} + + + + +{{/uses_katex}} + {{#lightswitch}}{{/lightswitch}} -{{#uses_katex}}{{/uses_katex}} {{{headdeps}}} {{#includes}}{{{head}}}{{/includes}} diff --git a/man/test-math-examples.Rd b/man/test-math-examples.Rd index de64ccaae..f20ade3c0 100644 --- a/man/test-math-examples.Rd +++ b/man/test-math-examples.Rd @@ -13,6 +13,18 @@ Test case: math rendering in examples Display equation: \deqn{y = \alpha + \beta X + \varepsilon} + +Multi-line equation (correctly rendered by katex only): + +\deqn{\mathit{Minimize} \space l \\ +\mathit{subject \space to} \\ +\sum_{i = 1}^{I} x_i r_{ij} + y_j \geq t_j \forall j \in J \\ +l \geq \frac{y_j}{t_j} \forall j \in J \\ +\sum_{i = 1}^{I} x_i c_i \leq B}{ +Minimize l subject to +sum_i^I (xi * rij) + yj >= tj for all j in J & +l >= (yj / tj) for all j in J & +sum_i^I (xi * ci) <= B} } \seealso{ Other tests: diff --git a/tests/testthat/_snaps/init.md b/tests/testthat/_snaps/init.md index 56b905cd8..cae1923e5 100644 --- a/tests/testthat/_snaps/init.md +++ b/tests/testthat/_snaps/init.md @@ -4,7 +4,6 @@ init_site(pkg) Message -- Initialising site ----------------------------------------------------------- - Copying /BS5/assets/katex-auto.js to katex-auto.js Copying /BS5/assets/lightswitch.js to lightswitch.js Copying /BS5/assets/link.svg to link.svg Copying /BS5/assets/pkgdown.js to pkgdown.js diff --git a/tests/testthat/test-build-article.R b/tests/testthat/test-build-article.R index 5429d9251..d8426f90b 100644 --- a/tests/testthat/test-build-article.R +++ b/tests/testthat/test-build-article.R @@ -141,7 +141,7 @@ test_that("can control math mode", { expect_equal(xpath_length(html, ".//span[contains(@class, 'math')]"), 1) expect_contains( path_file(xpath_attr(html, ".//script", "src")), - c("katex-auto.js", "katex.min.js") + c("auto-render.min.js", "katex.min.js") ) }) From 8854300bc2b7224dab1f169f3f8f92c5c62912dd Mon Sep 17 00:00:00 2001 From: Jay Hesselberth Date: Fri, 20 Dec 2024 07:36:03 -0700 Subject: [PATCH 2/6] Add a note to the math vignette section --- vignettes/customise.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vignettes/customise.Rmd b/vignettes/customise.Rmd index 7f671e656..9dfce65bc 100644 --- a/vignettes/customise.Rmd +++ b/vignettes/customise.Rmd @@ -226,7 +226,7 @@ template: ### Math rendering -By default, pkgdown will render math using mathml. mathml is the official standard for rendering math on the web, and requires no additional javascript or css dependencies. However, browser support for complex math is not always that good, so if you are including complex equations in your documentation, you may want to switch to either [`katex`](https://katex.org) or [`mathjax`](https://www.mathjax.org) by using the `template.math-rendering` field: +By default, pkgdown will render math using [mathml](https://w3c.github.io/mathml/). mathml is the official standard for rendering math on the web, and requires no additional javascript or css dependencies. However, browser support for complex math is not always that good, so if you are including complex equations in your documentation, you may want to switch to either [`katex`](https://katex.org), which we recommend for display of complex math expressions, or [`mathjax`](https://www.mathjax.org) by using the `template.math-rendering` field: ```yaml template: From 7da6b33f66a5c49409eba80441ee7999510ee011 Mon Sep 17 00:00:00 2001 From: Jay Hesselberth Date: Fri, 3 Jan 2025 06:16:36 -0700 Subject: [PATCH 3/6] Revert some changes to fix math in articles --- R/markdown.R | 7 +------ inst/BS5/assets/katex-auto.js | 14 ++++++++++++++ inst/BS5/templates/head.html | 1 + 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 inst/BS5/assets/katex-auto.js diff --git a/R/markdown.R b/R/markdown.R index 6de9962fc..b5dabba5b 100644 --- a/R/markdown.R +++ b/R/markdown.R @@ -121,12 +121,7 @@ convert_markdown_to_html <- function(pkg, in_path, out_path, ...) { "--indented-code-classes=R", "--section-divs", "--wrap=none", - ifelse( - # katex is handled separately - config_math_rendering(pkg) == "katex", - "", - paste0("--", config_math_rendering(pkg)) - ), + paste0("--", config_math_rendering(pkg)), ... )) ) diff --git a/inst/BS5/assets/katex-auto.js b/inst/BS5/assets/katex-auto.js new file mode 100644 index 000000000..20651d9fd --- /dev/null +++ b/inst/BS5/assets/katex-auto.js @@ -0,0 +1,14 @@ +// https://github.com/jgm/pandoc/blob/29fa97ab96b8e2d62d48326e1b949a71dc41f47a/src/Text/Pandoc/Writers/HTML.hs#L332-L345 +document.addEventListener("DOMContentLoaded", function () { + var mathElements = document.getElementsByClassName("math"); + var macros = []; + for (var i = 0; i < mathElements.length; i++) { + var texText = mathElements[i].firstChild; + if (mathElements[i].tagName == "SPAN") { + katex.render(texText.data, mathElements[i], { + displayMode: mathElements[i].classList.contains("display"), + throwOnError: false, + macros: macros, + fleqn: false + }); + }}}); diff --git a/inst/BS5/templates/head.html b/inst/BS5/templates/head.html index b67467099..ba3541467 100644 --- a/inst/BS5/templates/head.html +++ b/inst/BS5/templates/head.html @@ -17,6 +17,7 @@ + {{/uses_katex}} {{#lightswitch}}{{/lightswitch}} From 82f7da6a0097a0846d9481eb7f259ed0ec3c0da2 Mon Sep 17 00:00:00 2001 From: Jay Hesselberth Date: Fri, 3 Jan 2025 06:31:14 -0700 Subject: [PATCH 4/6] Update tests --- tests/testthat/_snaps/init.md | 1 + tests/testthat/test-build-article.R | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/testthat/_snaps/init.md b/tests/testthat/_snaps/init.md index cae1923e5..56b905cd8 100644 --- a/tests/testthat/_snaps/init.md +++ b/tests/testthat/_snaps/init.md @@ -4,6 +4,7 @@ init_site(pkg) Message -- Initialising site ----------------------------------------------------------- + Copying /BS5/assets/katex-auto.js to katex-auto.js Copying /BS5/assets/lightswitch.js to lightswitch.js Copying /BS5/assets/link.svg to link.svg Copying /BS5/assets/pkgdown.js to pkgdown.js diff --git a/tests/testthat/test-build-article.R b/tests/testthat/test-build-article.R index d8426f90b..9155ca9d7 100644 --- a/tests/testthat/test-build-article.R +++ b/tests/testthat/test-build-article.R @@ -141,7 +141,7 @@ test_that("can control math mode", { expect_equal(xpath_length(html, ".//span[contains(@class, 'math')]"), 1) expect_contains( path_file(xpath_attr(html, ".//script", "src")), - c("auto-render.min.js", "katex.min.js") + c("katex-auto.js", "auto-render.min.js", "katex.min.js") ) }) From cf6c288817bd7230fe52e8ee736731a7ae0dd94f Mon Sep 17 00:00:00 2001 From: Jay Hesselberth Date: Mon, 6 Jan 2025 11:35:21 -0700 Subject: [PATCH 5/6] CDN font support for Mathjax --- NEWS.md | 2 +- R/render.R | 1 + inst/BS5/templates/head.html | 11 +++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index db4767983..0d6db9d97 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,6 @@ # pkgdown (development version) -* Support for math rendering using katex (`math-rendering: katex`) was improved and now includes necessary components using CDN (#2704). +* Support for math rendering using katex and mathjax was improved and now includes necessary components using CDN (#2704). * Articles (i.e., Rmarkdown/Quarto documents in `vignettes/articles`, created by `usethis::use_article()` and available on pkgdown sites but not included in a built package) have improved test cases (thanks to @venpopov and @ethanbass). * New `clean_site(force = TRUE)` for cleaning of `docs/` regardless of whether it was built by pkgdown (#2827). * Links to favicons in page headers were updated to reflect changes to https://realfavicongenerator.net/ (#2804). Favicons should be re-generated by manually removing the `pkgdown/favicon` directory and then running `pkgdown::build_favicons()`. diff --git a/R/render.R b/R/render.R index f64fcdfbb..ab7a7c972 100644 --- a/R/render.R +++ b/R/render.R @@ -128,6 +128,7 @@ data_template <- function(pkg = ".", depth = 0L) { out$footer <- data_footer(pkg) out$lightswitch <- uses_lightswitch(pkg) out$uses_katex <- config_math_rendering(pkg) == "katex" + out$uses_mathjax <- config_math_rendering(pkg) == "mathjax" print_yaml(out) } diff --git a/inst/BS5/templates/head.html b/inst/BS5/templates/head.html index ba3541467..6f1131a7f 100644 --- a/inst/BS5/templates/head.html +++ b/inst/BS5/templates/head.html @@ -20,6 +20,17 @@ {{/uses_katex}} +{{#uses_mathjax}} + + +{{/uses_mathjax}} + {{#lightswitch}}{{/lightswitch}} {{{headdeps}}} From ced7fdc99cb39f742cec6ba4e07669413f4cdbca Mon Sep 17 00:00:00 2001 From: Jay Hesselberth Date: Mon, 6 Jan 2025 11:42:01 -0700 Subject: [PATCH 6/6] Update snapshot --- tests/testthat/_snaps/render.md | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/testthat/_snaps/render.md b/tests/testthat/_snaps/render.md index d7c109778..ac5482509 100644 --- a/tests/testthat/_snaps/render.md +++ b/tests/testthat/_snaps/render.md @@ -49,6 +49,7 @@ right:

Site built with pkgdown {version}.

lightswitch: no uses_katex: no + uses_mathjax: no # check_opengraph validates inputs