R help pages with multiline LaTeX equations
Asked Answered
T

2

3

I am writing R package documentation with roxygen2. I want to insert the following multiline equation into a help page, but my LaTeX code is not being rendered.

enter image description here

#' hello2
#'
#' @description
#' \deqn{
#' F(t)= \begin{cases}\alpha(t) f_{L}(t)+[1-\alpha(t)] f_{C}(t) & t_{L}<t<t_{C} \\ \beta(t) f_{C}(t)+[1-\beta(t)] f_{R}(t) & t_{C}<t<t_{R}\end{cases}
#' }
#' 
#' @export
hello2 <- function() {}

enter image description here

Trivet answered 18/2, 2022 at 2:53 Comment(4)
See #37398107 or #54999115. The RStudio help viewer uses the HTML markup which does not seem to support LaTeX formatting.Hallvard
I noticed those links. But still cannot figure out the solution for my caseTrivet
The point of those links is that it's not possible cases is not a base LaTeX function. It comes from the AMS styles and therefore cannot be used. See also colinfay.me/writing-r-extensions/…Hallvard
Yes, Rd macros \eqn and \deqn do not support cases. However, it is possible to have that equation rendered in the HTML help using macros provided by package mathjaxr, which embeds MathJax. You'll need to add mathjaxr as a dependency of your package...Strengthen
S
4

New answer

Support for KaTeX in HTML rendering of Rd files was added in R 4.2.0. Support for amsmath in PDF rendering of Rd files was added in R 4.2.2. Hence packages with Depends: R (>= 4.3) can safely specify multiline equations using \deqn. No need for mathjaxr.


Original answer

Just to demonstrate that it's possible once you've integrated mathjaxr correctly:

tmp <- tempfile()
dir.create(tmp)
cwd <- setwd(tmp)

pkgname <- "foo"
usethis::create_package(pkgname, rstudio = FALSE, open = FALSE,
                        fields = list(Imports = "mathjaxr", RdMacros = "mathjaxr"))
setwd(pkgname)
text <- "#' A title
#' 
#' \\loadmathjax{}
#' A description.
#' 
#' @param a,b Arguments.
#' 
#' @details
#' An irrelevant equation:
#' \\mjtdeqn{F(t) = \\left\\lbrace\\begin{array}{ll} \\alpha(t) f_{L}(t) + \\lbrack 1 - \\alpha(t) \\rbrack f_{C}(t)\\,, & t_{L} < t < t_{C}\\,, \\cr \\beta(t) f_{C}(t) + \\lbrack 1 - \\beta(t) \\rbrack f_{R}(t)\\,, & t_{C} < t < t_{R}\\,. \\end{array}\\right.}{%
#'           F(t) = \\begin{cases} \\alpha(t) f_{L}(t) + \\lbrack 1 - \\alpha(t) \\rbrack f_{C}(t)\\,, & t_{L} < t < t_{C}\\,, \\cr \\beta(t) f_{C}(t) + \\lbrack 1 - \\beta(t) \\rbrack f_{R}(t)\\,, & t_{C} < t < t_{R}\\,. \\end{cases}}{%
#'           ... a plain text translation ...}
#' 
#' @noMd
#' @export
#' @importFrom mathjaxr preview_rd
add <- function(a, b) a + b
"
cat(text, file = file.path("R", "add.R"))
roxygen2::roxygenize(".")

PDF output

mathjaxr::preview_rd("add.Rd", type = "pdf")

enter image description here

HTML output

mathjaxr::preview_rd("add.Rd", type = "html")

enter image description here

Plain text output

mathjaxr::preview_rd("add.Rd", type = "txt")

enter image description here

A few remarks

  • We are only escaping back slashes because we are typing the contents of add.R into a string. The text file created by cat does not contain the escapes.
  • \loadmathjax{} injects a MathJax script into the HTML file. It is usually placed at the top of the description, so that you can typeset math everywhere after that.
  • We are using macro \mjtdeqn to supply LaTeX for the PDF manual, LaTeX for the HTML help page, and plain text for the plain text help page, in that order. There are other macros that you can use in simpler cases. They are all documented in the README, which you should read carefully.
  • In the PDF field, you do not have access to AMS extensions, so you have to implement cases yourself with array.
  • In both the PDF and HTML fields, you need to use \cr in place of the usual \\ in multiline environments. I'm not sure why.
  • I haven't figured out how to encode line breaks in the plain text field (yet). It's going to be hard to translate multiline equations to plain text without line breaks...
  • I disabled Markdown support for this header with @noMd because, in my experience, the Markdown parser doesn't always play nicely with the mathjaxr macros. In my own packages, I disable Markdown support globally via DESCRIPTION.
  • You need @importFrom mathjaxr preview_rd somewhere in your package to circumvent R CMD check warnings about having mathjaxr in your Imports without using any functions exported by mathjaxr.
  • To preview help pages that use MathJax without installing your package, you need to use mathjaxr::preview_rd. The devtools preview will show you unrendered LaTeX code.
  • You'll have to decide whether MathJax support is worth having mathjaxr in your Imports. Anyone who tries to install your package is going to have to install mathjaxr, too.

Cleaning up

setwd(cwd)
unlink(tmp, recursive = TRUE)
Strengthen answered 18/2, 2022 at 8:40 Comment(1)
Thanks for your solution and detailed remarks.Trivet
T
0

Base on the solution of Mikael, a cleaner version:

#' A title
#'
#' @param a,b Arguments.
#'
#' @section options:
#' - `item1`:
#'    \mjtdeqn{
#'    F(t) = \left\lbrace\begin{array}{ll}
#'         \alpha(t) f_{L}(t) + (1 - \alpha(t)) f_{C}(t), & t_{L} < t < t_{C}, \cr
#'         \beta(t) f_{C}(t) + (1 - \beta(t)) f_{R}(t), & t_{C} < t < t_{R}. \end{array}\right.}{%
#'    F(t) = \begin{cases}
#'         \alpha(t) f_{L}(t) + (1 - \alpha(t)) f_{C}(t), & t_{L} < t < t_{C}, \cr
#'         \beta(t) f_{C}(t) + (1 - \beta(t)) f_{R}(t), & t_{C} < t < t_{R}. \end{cases}}{}
#'
#' - item2
#'
#' \loadmathjax{}
#' @export
#' @importFrom mathjaxr preview_rd
add <- function(a, b) a + b

Markdown is compatible with mathjaxr in this example

mathjaxr::preview_rd("add.Rd", type = "pdf")
mathjaxr::preview_rd("add.Rd", type = "html")

Above scripts returns the same result as Mikael's.

Trivet answered 18/2, 2022 at 12:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.