Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom MathJax URL not working #915

Open
3 tasks done
timwaite opened this issue Jul 19, 2020 · 20 comments · May be fixed by #937
Open
3 tasks done

Custom MathJax URL not working #915

timwaite opened this issue Jul 19, 2020 · 20 comments · May be fixed by #937
Assignees
Labels
bug an unexpected problem or unintended behavior

Comments

@timwaite
Copy link

timwaite commented Jul 19, 2020

Thanks for the great package!

Custom URLs for MathJax aren't working for me in Bookdown. I have tried setting the mathjax option in _output.yml as below. However the rendered HTML just uses the out of date version 2.7.2 of MathJax from mathjax.rstudio.com/latest, not the version I have specified.

Am I doing something wrong, or is this a bug?

I can see in RStudio that the mathjax variable argument has been passed to the pandoc command line call. However it seems that the variable isn't being processed into the template gitbook.html.

I asked asked about this on StackOverflow, but I got no response. [Edit: fixed link]

Minimal example:

_output.yml:

bookdown::gitbook:
  css: style.css
  mathjax: "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" 

index.Rmd:

--- 
title: "Untitled"
author: "An author"
site: bookdown::bookdown_site
documentclass: book
---

$$E=mc^2$$

Session info:

> xfun::session_info('rmarkdown')
R version 3.6.3 (2020-02-29)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Mojave 10.14.6, RStudio 1.3.959

Locale: en_GB.UTF-8 / en_GB.UTF-8 / en_GB.UTF-8 / C / en_GB.UTF-8 / en_GB.UTF-8

Package version:
  base64enc_0.1.3 digest_0.6.25   evaluate_0.14  
  glue_1.4.1      graphics_3.6.3  grDevices_3.6.3
  highr_0.8       htmltools_0.5.0 jsonlite_1.7.0 
  knitr_1.29      magrittr_1.5    markdown_1.1   
  methods_3.6.3   mime_0.9        rlang_0.4.7    
  rmarkdown_2.3   stats_3.6.3     stringi_1.4.6  
  stringr_1.4.0   tinytex_0.24    tools_3.6.3    
  utils_3.6.3     xfun_0.15       yaml_2.2.1     

Pandoc version: 2.9.2.1

By filing an issue to this repo, I promise that

  • I have fully read the issue guide at https://yihui.org/issue/.
  • I have provided the necessary information about my issue.
    • If I'm asking a question, I have already asked it on Stack Overflow or RStudio Community, waited for at least 24 hours, and included a link to my question there.
    • If I'm filing a bug report, I have included a minimal, self-contained, and reproducible example, and have also included xfun::session_info('bookdown'). I have upgraded all my packages to their latest versions (e.g., R, RStudio, and R packages), and also tried the development version: remotes::install_github('rstudio/bookdown').
    • If I have posted the same issue elsewhere, I have also mentioned it in this issue.
  • I have learned the Github Markdown syntax, and formatted my issue correctly.

I understand that my issue may be closed if I don't fulfill my promises.

@cderv
Copy link
Collaborator

cderv commented Jul 20, 2020

Yes I think this is a bug.

In bookdown, to change the mathjax CDN used by gitbook, currently I think this should be passed as pandoc variable in index.Rmd yaml header because the template use a special js script

$if(math)$
<!-- dynamically load mathjax for compatibility with self-contained -->
<script>
(function () {
var script = document.createElement("script");
script.type = "text/javascript";
var src = "$if(mathjax)$$mathjax$$endif$";
if (src === "" || src === "true") src = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-MML-AM_CHTML";
if (location.protocol !== "file:")
if (/^https?:/.test(src))
src = src.replace(/^https?:/, '');
script.src = src;
document.getElementsByTagName("head")[0].appendChild(script);
})();
</script>

however, this does not behave as it should either, because

mathjax: "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"

is rendered as a html link before being passed to pandoc template. I need to understand why.

Anyway, I think it should work as you tried.
When passing mathjax in the output format argument, it passes to --mathjax flag in pandoc commandline and this set mathjax variable to true , and mathjaxurl to the url.

I think, that gitbook.html template should use that mathjaxurl variable.

Thanks for the report. I'll think about the correct fix

@cderv cderv added the bug an unexpected problem or unintended behavior label Jul 20, 2020
@cderv
Copy link
Collaborator

cderv commented Aug 26, 2020

@yihui so I have looked into this and I think we don't currently support properly setting a custom mathjax url with bookdown::gitbook.

Currently, all the mathjax handling is dealt in rmarkdown:::pandoc_mathjax_args mainly. What causing issue here is that rmarkdown does a correct handling only for its internal template (html_document(template = "default")) and as bookdown use its own template, we don't benefit from it in bookdown.

Here my analysis of the situation, to be a base of comparaison with a potential fix; I spend some time on it, mainly to be up to date with how mathjax is handle in rmarkdown and bookdown.

Current situation

# setting some helpers
temp_file <- tempfile(fileext = ".Rmd")
xfun::write_utf8(c(
  "---",
  "title: Test",
  "---",
  "",
  "# test",
  "",
  "$1+1$"
), temp_file)

# this will print the html part of custom mathjax code from RStudio's template
render_gitbook <- function(...) {
  # we insure pandoc 2.7.3 for now
  rmarkdown::find_pandoc(version = "2.7.3")
  res <- xfun::in_dir(tempdir(),
               rmarkdown::render(
                 temp_file, "bookdown::gitbook",
                 output_options = list(...),
                 quiet = TRUE)
  )
  html <- xfun::read_utf8(res)
  i <- grep("<!-- dynamically load mathjax for compatibility with self-contained -->",
       html)
  if (!length(i)) return("no Mathjax")
  start_s <- grep("<script>", html)
  end_s <- grep("</script>", html)
  xfun::raw_string(html[start_s[start_s > i][1]:end_s[end_s>i][1]])
}

custom_mathjax <- "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"

Let's note first that bookdown::gitbook with self_contained = TRUE does not work because mathjax won't be included. I think it should as we ofter to customise self_contained argument.
In fact this is due to the handling of mathjax in rmarkdown:::pandoc_mathjax_arg which remove mathjax is another template than the one included with rmarkdown. Obviously, bookdown::gitbook() is using another template

render_gitbook(self_contained = TRUE)
#> Warning: MathJax doesn't work with self_contained when not using the rmarkdown
#> "default" template.
#> [1] "no Mathjax"
render_gitbook(self_contained = TRUE, mathjax = custom_mathjax)
#> Warning: MathJax doesn't work with self_contained when not using the rmarkdown
#> "default" template.
#> [1] "no Mathjax"

Now on our issue here, currently custom url is not taken into account in the gitbook template. This is because only mathjax pandoc variable is used (and it is logical with no value set)

render_gitbook(mathjax = custom_mathjax)
#> <script>
#>   (function () {
#>     var script = document.createElement("script");
#>     script.type = "text/javascript";
#>     var src = "true";
#>     if (src === "" || src === "true") src = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-MML-AM_CHTML";
#>     if (location.protocol !== "file:")
#>       if (/^https?:/.test(src))
#>         src = src.replace(/^https?:/, '');
#>     script.src = src;
#>     document.getElementsByTagName("head")[0].appendChild(script);
#>   })();
#> </script>

Then, mathjax = "local" is not supported in gitbook either - the included code is still the same.

render_gitbook(mathjax = "local")
#> <script>
#>   (function () {
#>     var script = document.createElement("script");
#>     script.type = "text/javascript";
#>     var src = "true";
#>     if (src === "" || src === "true") src = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-MML-AM_CHTML";
#>     if (location.protocol !== "file:")
#>       if (/^https?:/.test(src))
#>         src = src.replace(/^https?:/, '');
#>     script.src = src;
#>     document.getElementsByTagName("head")[0].appendChild(script);
#>   })();
#> </script>

For no mathjax asked, it is working - no mathjax is used.

render_gitbook(mathjax = NULL)
#> [1] "no Mathjax"

I also tried with custom template, it has mostly the same behavior than rmarkdown for now.
We create a dummy template to show the pandoc variables set for the rendering, and we test several scenarios.

# dummy html file
library(htmltools)
html_content <- div(
  # hack to work with previous function render_gitbook
  HTML("<!-- dynamically load mathjax for compatibility with self-contained -->"),
  tags$script(
    p("this is mathjax variable: $mathjax$"),
    br(),
    p("this is mathjaxurl variable: $mathjaxurl$"),
    br(),
    p("this is mathjax-url variable: $mathjax-url$"),
    br(),
    p("this is math variable: $math$")
  )
)
template <- tempfile(fileext = ".html")
xfun::write_utf8(as.character(html_content), template)

# custom templates can use pandoc mathjaxurl variable or math variable
render_gitbook(mathjax = custom_mathjax, template = template)
#>   <script>
#>     <p>this is mathjax variable: true</p>
#>     <br/>
#>     <p>this is mathjaxurl variable: https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js</p>
#>     <br/>
#>     <p>this is mathjax-url variable: </p>
#>     <br/>
#>     <p>this is math variable: <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js" type="text/javascript"></script></p>

# same for mathjax = local
render_gitbook(mathjax = "local", template = template)
#>   <script>
#>     <p>this is mathjax variable: true</p>
#>     <br/>
#>     <p>this is mathjaxurl variable: libs/mathjax-local/MathJax.js</p>
#>     <br/>
#>     <p>this is mathjax-url variable: </p>
#>     <br/>
#>     <p>this is math variable: <script src="libs/mathjax-local/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script></p>

# still does work with self_contained = TRUE
render_gitbook(mathjax = custom_mathjax, template = template, self_contained= TRUE)
#> Warning: MathJax doesn't work with self_contained when not using the rmarkdown
#> "default" template.
#>   <script>
#>     <p>this is mathjax variable: </p>
#>     <br/>
#>     <p>this is mathjaxurl variable: </p>
#>     <br/>
#>     <p>this is mathjax-url variable: </p>
#>     <br/>
#>     <p>this is math variable: </p>
#>   </script>

# with default, the pandoc mathjax default and custom template one is used
render_gitbook(template = template)
#>   <script>
#>     <p>this is mathjax variable: true</p>
#>     <br/>
#>     <p>this is mathjaxurl variable: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js</p>
#>     <br/>
#>     <p>this is mathjax-url variable: </p>
#>     <br/>
#>     <p>this is math variable: <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-AMS_CHTML-full" type="text/javascript"></script></p>

That means that with a custom template, it is to the user responsability to do something based on pandoc feature mainly. (But let's note there is no easy way to get the full url with the query part in mathjaxurl variable)
Rmarkdown mathjax-url is never sets to helps create another self-contained format.

What do we want to do ?

  • Do we want to support custom mathjax in gibook() ?
    • If no, nothing to do and we can document then close.
    • If yes, I have some adjustment to make. but first...
  • Do we want to support mathjax = "local" also, and more generally have the same behavior in gitbook template than in default.html in rmarkdown ?

Depending on the choices, we could

  1. Try to come with a fix in gitbook only ? I have something to PR on this one.
  2. Rethink the way it works in rmarkdown so that it is better extensible with other format.

Choice 1 doesn't allow to remove the warning when self_contained = TRUE but choice 2 can enable that. Do we want to support self contained for gitbook (not sure).

I will share the work I have done for 1, but I would be interested in your thinking on all this. Thanks !

@cderv cderv linked a pull request Aug 26, 2020 that will close this issue
1 task
@yihui
Copy link
Member

yihui commented Aug 26, 2020

Thanks @cderv! I need more time to digest this, but let me ask a quick question first: will it help if we remove the restriction here https://github.com/rstudio/rmarkdown/blob/204aa41faea12212dc80642f5a8e53e4e52e0999/R/pandoc.R#L478-L483?

@cderv
Copy link
Collaborator

cderv commented Aug 27, 2020

Yes this is the part in Rmarkdown that is currently activated when using Gitbook. I see two impacts of this :

  1. this restriction on self_contained with the warning is to me the cause of bookdown::gitbook() not having mathjax when self_contained = TRUE. In this case, --mathjax is not added to command line pandoc and I guess default pandoc rendering is used. (again I don't know if anyone use some "self contained gitbook" and if it really makes sense - never used it myself). So math appears in the doc (I tried on bookdown-demo) but they are not rendered using mathjax.

  2. currently if the default rmarkdown template is not used (by default, we mean template = "default" for html_document only, so the default.html file in rmarkdown), rmarkdown only sets the --mathjax pandoc command line argument.

    args <- c(args, paste(c("--mathjax", mathjax), collapse = "="))

    That is what happens with gitbook() because a custom template is used (from rmarkdown point of view).
    It means we rely on pandoc mathjax handling for template, :

    • $math$ variable that contains the <script> line, transformed when --self-contained is used
    • $mathjax$ variable, logical and equal TRUE is --mathjax is used
    • $mathjaxurl$ variable, contains the url (up until the query part, so before any ?), mainly to be used in default beamer template from my understanding.

    but currently we only support the default Rstudio's mathjax url if mathjax is to be used.

    var src = "$if(mathjax)$$mathjax$$endif$";
    if (src === "" || src === "true") src = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-MML-AM_CHTML";

My current PR tries to solve 2 from bookdown directly. If we remove (or change the restriction) on rmarkdown side that would be different. I mentioned that in the PR discussion. 1 is blocked by rmarkdown restriction I guess - we could bypass it but we'll still get the warning.

I am wondering is this rmarkdown restriction is also impacting other 📦 BTW 🤔 - will look into it.

@cderv
Copy link
Collaborator

cderv commented Aug 27, 2020

(again I don't know if anyone use some "self contained gitbook" and if it really makes sense - never used it myself).

Another thought on that: If fact, it seems it is really discourage, from an old comment of yours #61 (comment) where you say

Also note MathJax may not work when self_contained = TRUE.

However, it is not really specified in the bookdown book : https://bookdown.org/yihui/bookdown/html.html#gitbook-style
only:

Please note that if you change self_contained = TRUE to make self-contained HTML pages, the total size of all HTML files can be significantly increased since there are many JS and CSS files that have to be embedded in every single HTML file.

I really wonder if we can't force self_contained = FALSE in gitbook and use the $math$ pandoc variable directly in the gitbook.html pandoc template.

@sentausa

This comment has been minimized.

@cderv

This comment has been minimized.

@sentausa

This comment has been minimized.

@cderv

This comment has been minimized.

@cderv

This comment has been minimized.

@sentausa

This comment has been minimized.

@sentausa
Copy link

@cderv finally I put my question on StackOverflow. Thanks!

@cderv
Copy link
Collaborator

cderv commented Mar 8, 2022

New extended math support in rmarkdown brings a workaround to this by switching to Katex rendering.
See here: https://community.rstudio.com/t/cannot-load-mathtools-mathjax-extension-in-bookdown/131073/2?u=cderv

bookdown::gitbook:
  math_method: r-katex

this is not a solution and now that new rmarkdown is on CRAN we'll improve support in bookdown.

@cderv cderv moved this to Backlog in R Markdown Team Projects Mar 8, 2022
@cderv cderv moved this from Backlog to Todo in R Markdown Team Projects Mar 8, 2022
@cderv cderv moved this from Todo to Backlog in R Markdown Team Projects Apr 8, 2022
@piiskop
Copy link

piiskop commented Jul 30, 2022

With r-katex labelling doesn't work and it doesn't recognize mhchem's \ce.

@pglpm
Copy link

pglpm commented May 26, 2023

I was wondering whether there are any updates on this issue. As I explain in this Stackoverflow question, I'd like to use the upgreek MathJax extension in Bookdown, but it's only available in V3, which cannot be used in Bookdown at present. Unfortunately the KaTeX workaround doesn't work either, as KaTeX doesn't offer upright lowercase Greek.

@cderv
Copy link
Collaborator

cderv commented May 26, 2023

Not yet. Work still need to be done and format Gitbook tested with Mathjax 3. For now you would need a HTML post processing probably to tweak the HTML and replace the url. Sorry for this.

I'll move this up in the list.

Also possible bs4_book() format does not have this issue.

@cderv cderv moved this from Backlog to Next / Ready for Dev in R Markdown Team Projects May 26, 2023
@pglpm
Copy link

pglpm commented May 26, 2023

Thank you! Great to hear it's on the todo list. I'll take a look at bs4_book in the meantime.

Thank you again for this great package!

@cderv
Copy link
Collaborator

cderv commented May 26, 2023

If you are working on a new Book, you could also have a look at the new Quarto publishing system. This could be seen a "the next generation of R Markdown" for R users. It builds on R Markdown experience and opens it to the non-R world for anyone doing scientific publishing no matter the tool (R, Python, Julia, ...)

There is a book format there: https://quarto.org/docs/books/

Just sharing in case you don't know. No need to change if bookdown works for you.

@pglpm
Copy link

pglpm commented May 26, 2023

Hi Christophe, just tried Quarto, and upright lowercase greek works natively. Thank you for the great suggestion.
This reply is a little off-topic, so feel free to delete it.

@cderv
Copy link
Collaborator

cderv commented May 26, 2023

I'll keep it ! Really great feedback thanks ! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug an unexpected problem or unintended behavior
Projects
Status: Backlog
Development

Successfully merging a pull request may close this issue.

6 participants