tic-toc-choc
tic-toc-choc

Reputation: 960

Inline LaTeX equations in shiny app with MathJax

A solution to display LaTeX equations in line is offered here with a working live demo

The above mentioned solution to display equations in line is (cutting a few lines of code):

ui.R:

library(shiny)

shinyUI(fluidPage(
  title = 'MathJax Examples with in-line equations',
  withMathJax(),
  # section below allows in-line LaTeX via $ in mathjax. Replace less-than-sign with < 
  # and grater-than-sign with >
  tags$div(HTML("less-than-sign script type='text/x-mathjax-config' greater-than-sign
                MathJax.Hub.Config({
                tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
                });
                less-than-sign /script greater-than-sign
                ")),
  helpText('An irrational number $\\sqrt{2}$
           and a fraction $1-\\frac{1}{2}$'),
  helpText('and a fact about $\\pi$:$\\frac2\\pi = \\frac{\\sqrt2}2 \\cdot
           \\frac{\\sqrt{2+\\sqrt2}}2 \\cdot
           \\frac{\\sqrt{2+\\sqrt{2+\\sqrt2}}}2 \\cdots$'),
  uiOutput('ex1')
  ))

server.R:

shinyServer(function(input, output, session) {
  output$ex1 <- renderUI({
    withMathJax(helpText('Dynamic output 1:  $\\alpha^2$'))
  })
})

I am running R version 3.5.2 on macOS, and shiny 1.2. The app output is some verbatim text instead of the expected blend of text and inline equations:

less-than-sign script type='text/x-mathjax-config' greater-than-sign MathJax.Hub.Config({ tex2jax: {inlineMath: [['$','$'], ['′,′
']]} }); less-than-sign /script greater-than-sign
and a fact about $\pi$:$\frac2\pi = \frac{\sqrt2}2 \cdot \frac{\sqrt{2+\sqrt2}}2 \cdot \frac{\sqrt{2+\sqrt{2+\sqrt2}}}2 \cdots$
Dynamic output 1: $\alpha^2$

Can it be because of my R environment?

Upvotes: 11

Views: 4422

Answers (4)

Andr&#225;s Asz&#243;di
Andr&#225;s Asz&#243;di

Reputation: 9680

The example for inline LaTeX equations linked by OP is a bit long in the tooth (posted in 2015). Here is another solution that uses renderUI:

output$descr <- renderUI(withMathJax(
    "The Poisson PMF is:
    $$\\mathrm{Pr}_{\\lambda}(x) = \\frac{\\lambda^x e^{-\\lambda}}{x!}$$
    where \\(\\lambda\\) is its sole parameter."))

The $$ delimiters render the LaTeX formula in "display mode". The \( ... \) pair indicates "inline mode". The example above renders \lambda inline (as λ ).

The backlashes need to be doubled ("leaning toothpick syndrome") due to the way R processes them.

Upvotes: 0

randy
randy

Reputation: 1091

Making the MathJax script work

The < script> tag needs to be <script> and < /script > needs to be </script >:

tags$div(HTML("<script type='text/x-mathjax-config' >
            MathJax.Hub.Config({
            tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
            });
            </script >
            "))

Fixing the math delimiter

However, the preceding code (following the code in the question) uses parentheses as math delimiters, which is a really bad idea. To use the more common \(...\), you need to escape characters with more backslashes:

tags$div(HTML("<script type='text/x-mathjax-config' >
            MathJax.Hub.Config({
            tex2jax: {inlineMath: [['$','$'], ['\\\\(','\\\\)']]}
            });
            </script >
            "))

When writing an inline equation, the backslash again needs to be escaped: p("The equation \\(x=2\\) is inline.")

Upvotes: 4

Dylan_Gomes
Dylan_Gomes

Reputation: 2242

Long answer:

The KaTeX solution (https://stackoverflow.com/a/54882204/9096420) is great, but it doesn't allow summation symbols to look as they should.

p(withMathJax("$$$ \\sum_{i=2}^{10} $$$")

Results in: enter image description here

Instead of: enter image description here

@randy's solution (https://stackoverflow.com/a/57998981/9096420; from the MathJax docs: https://docs.mathjax.org/en/v2.7-latest/options/preprocessors/tex2jax.html), does allow the summation math above to look correct, however, it has the unintended side effect of altering all text that is inside parentheses.

For example, this code:

p("this is a (test) paragraph to show (what #happens)"),

renders as:

enter image description here

For some reason having symbols within the parentheses leads to text being inside a box, and otherwise appearing as math text. This isn't ideal if you are hoping to use parentheticals elsewhere in your Shiny App (perhaps as references, etc.).

To fix this, you only have to remove (from randy's answer) , ['\\(','\\)'], which is the second delimiter listed (which isn't necessary).


Short answer:

    tags$div(HTML("<script type='text/x-mathjax-config' >
    MathJax.Hub.Config({
    tex2jax: {inlineMath: [['$','$']]}
    });
    </script >
    ")),

Session Info

> sessionInfo()
R version 4.3.0 (2023-04-21 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19045)

Matrix products: default


locale:
[1] LC_COLLATE=English_United States.utf8  LC_CTYPE=English_United States.utf8    LC_MONETARY=English_United States.utf8 LC_NUMERIC=C                          
[5] LC_TIME=English_United States.utf8    

time zone: America/Los_Angeles
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] extraDistr_1.9.1 scales_1.2.1     plyr_1.8.8       ggplot2_3.4.3    shiny_1.7.4.1   

loaded via a namespace (and not attached):
 [1] Matrix_1.5-4        jsonlite_1.8.7      gtable_0.3.3        crayon_1.5.2        dplyr_1.1.3         compiler_4.3.0      promises_1.2.0.1   
 [8] tidyselect_1.2.0    Rcpp_1.0.11         sourcetools_0.1.7-1 later_1.3.1         jquerylib_0.1.4     splines_4.3.0       fastmap_1.1.1      
[15] lattice_0.21-8      mime_0.12           R6_2.5.1            labeling_0.4.2      generics_0.1.3      tibble_3.2.1        munsell_0.5.0      
[22] bslib_0.5.0         pillar_1.9.0        rlang_1.1.1         utf8_1.2.3          cachem_1.0.8        httpuv_1.6.11       sass_0.4.7         
[29] memoise_2.0.1       cli_3.6.1           mgcv_1.8-42         withr_2.5.0         magrittr_2.0.3      digest_0.6.33       grid_4.3.0         
[36] fontawesome_0.5.1   rstudioapi_0.15.0   xtable_1.8-4        nlme_3.1-162        lifecycle_1.0.3     vctrs_0.6.3         glue_1.6.2         
[43] farver_2.1.1        rsconnect_1.1.0     fansi_1.0.4         colorspace_2.1-0    tools_4.3.0         pkgconfig_2.0.3     ellipsis_0.3.2     
[50] htmltools_0.5.5 

Upvotes: 0

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84599

An alternative way, using KaTeX instead of MathJax:

library(shiny)

ui <- fluidPage(
  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"),
    HTML('<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js" integrity="sha384-2BKqo+exmr9su6dir+qCw08N2ZKRucY4PrGQPPWU1A7FtlCGjmEGFqXCv5nyM5Ij" crossorigin="anonymous"></script>'),
    HTML('<script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js" integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI" crossorigin="anonymous"></script>'),
    HTML('
    <script>
      document.addEventListener("DOMContentLoaded", function(){
        renderMathInElement(document.body, {
          delimiters: [{left: "$", right: "$", display: false}]
        });
      })
    </script>')
  ),
  titlePanel("Hello Shiny!"),
  helpText('An irrational number $\\sqrt{2}$
           and a fraction $1-\\frac{1}{2}$'),
  helpText('and a fact about $\\pi$:$\\frac2\\pi = \\frac{\\sqrt2}2 \\cdot
           \\frac{\\sqrt{2+\\sqrt2}}2 \\cdot
           \\frac{\\sqrt{2+\\sqrt{2+\\sqrt2}}}2 \\cdots$'),
  uiOutput('ex1')
)

server <- function(input, output) {

  output$ex1 <- renderUI({
    tagList(
      helpText('Dynamic output 1: $\\alpha^2$'),
      tags$script('renderMathInElement(document.getElementById("ex1"), {delimiters: [{left: "$", right: "$", display: false}]});')
    )
  })  

}

enter image description here

Upvotes: 6

Related Questions