Search code examples
javascriptrshinykatex

Render KaTeX inside a modal directly without an extra "click" inside the modal in R Shiny


I am struggling ro render the KaTeX formulas inside my popups. The Javascript function I'm using does this, but unfortunately only after i made a "click" inside of the generated popup.

And yes, sadly I have 0 knowledge in js and couldn't find an appropiate argument(?), which does render everything without the need to make a click somewhere.

Here is an RME:

renderKaTeX <- '
$(document).ready(function() {
        $("body").on("click", function() {
          var mathElements = document.getElementsByClassName("math");
          for(var i = 0; i < mathElements.length; i++) {
            renderMathInElement(
              mathElements[i], {
                delimiters: [{left: "$", right: "$", display: false}]
              });
          }
        });
 });
'

library(shiny)
library(shinyMobile)

shinyApp(
  ui = f7Page(
    tags$head(
      tags$link(rel="stylesheet", href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css", integrity="sha384-dbVIfZGuN1Yq7/1Ocstc1lUEm+AT+/rCkibIcC/OmWo5f0EA48Vf8CytHzGrSwbQ",crossorigin="anonymous"),
      tags$script(defer = "", src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js",integrity="sha384-2BKqo+exmr9su6dir+qCw08N2ZKRucY4PrGQPPWU1A7FtlCGjmEGFqXCv5nyM5Ij",crossorigin="anonymous"),
      tags$script(defer = "",src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js",integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI",crossorigin="anonymous"),
      tags$script(HTML(renderKaTeX))
    ),
    title = "Popup",
    f7SingleLayout(
      navbar = f7Navbar(title = ""),
      f7Button("btn", "Open Popup")
    )
  ),
  server = function(input, output, session) {
    observeEvent(input$btn, {
      f7Popup(
        id = "popup1",
        title = "test",
        tags$div(class = "math",
                 tags$p("render me without click pls: $X$")         
        )
      )
    })
  }
)

It's probably just one argument I am missing, but still struggling since days on this matter.

Thank you for your help


Solution

  • You can use the katex package:

    library(katex)
    library(shiny)
    library(shinyMobile)
    
    shinyApp(
      ui = f7Page(
        tags$head(
          tags$link(rel="stylesheet", href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css", integrity="sha384-dbVIfZGuN1Yq7/1Ocstc1lUEm+AT+/rCkibIcC/OmWo5f0EA48Vf8CytHzGrSwbQ",crossorigin="anonymous"),
          tags$script(defer = "", src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js",integrity="sha384-2BKqo+exmr9su6dir+qCw08N2ZKRucY4PrGQPPWU1A7FtlCGjmEGFqXCv5nyM5Ij",crossorigin="anonymous"),
          tags$script(defer = "",src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js",integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI",crossorigin="anonymous")
        ),
        title = "Popup",
        f7SingleLayout(
          navbar = f7Navbar(title = ""),
          f7Button("btn", "Open Popup")
        )
      ),
      server = function(input, output, session) {
        observeEvent(input$btn, {
          f7Popup(
            id = "popup1",
            title = "test",
            tags$div(
              class = "math",
              tags$p(HTML(
                katex_html("\\int f = \\pi", displayMode = FALSE, preview = FALSE)
              ))         
            )
          )
        })
      }
    )