Search code examples
rshinymathjax

How to utilize renderUI and load MathJax manually


I am building a shiny app with MathJax. However, I need to load the javascript manually because I need the \cancel extension. This works as intended with one exception. I can't get the app to render MathJax with the renderUI shiny function. The code below does not display the math as is, but works fine with the usual withMathJax() procedure.

library(shiny)

js <- "
window.MathJax = {
  loader: {load: ['[tex]/cancel']},
  tex: {packages: {'[+]': ['cancel']}}
};
"

out_text <- "Equation 1: $$1+1=2$$"

ui <- fluidPage(
  tags$head(
    tags$script(async="", src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"),
    tags$script(HTML(js))
  ),
  uiOutput("main")
)

server <- function(input, output, session) {
  output$main <- renderUI({
    out_text
  })
}

shinyApp(ui, server)

Solution

  • With MathJax 3, one has to call MathJax.typeset() to refresh the MathJax process. You can add this call in a tags$script inside the renderUI:

    library(shiny)
    
    js <- "
    window.MathJax = {
      loader: {load: ['[tex]/cancel']},
      tex: {packages: {'[+]': ['cancel']}}
    };
    "
    
    ui <- fluidPage(
      tags$head(
        tags$script(async="", src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"),
        tags$script(HTML(js))
      ),
      div("$$1+2=3$$"), 
      div("$$\\cancel{10a}$$"),
      uiOutput("equation")
    )
    
    server <- function(input, output, session) {
      output[["equation"]] <- renderUI({
        tagList(
          div("$$\\cancel{10b}$$"),
          tags$script(HTML('MathJax.typeset();'))
        )
      })
    }
    
    shinyApp(ui, server)