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

Render mathematical expressions in Markdown #15433

Open
sbrunk opened this issue Jun 13, 2022 · 8 comments
Open

Render mathematical expressions in Markdown #15433

sbrunk opened this issue Jun 13, 2022 · 8 comments

Comments

@sbrunk
Copy link

sbrunk commented Jun 13, 2022

Many tools like vscode support rendering math expressions in LaTeX style inside Markdown. Since a few weeks this is also supported here on GitHub.

I.e. we can put our expression into two $ $$y = xA^T + b$$ and get a nicely rendered expression: $$y = xA^T + b$$
Or alternatively we can get inline rendering $y = xA^T + b$ by using a single $: $y = xA^T + b$

Rendering is done with MathJax, an apache-licenced JavaScript rendering library that can be included in any webpage.

I think this is quite useful for documentation inside of i.e. numeric and scientific libraries or just anything with math operations so I'd like to propose to add support for MathJax in Scaladoc.

I did a small POC by including the necessary JS and config manually into a Scaladoc generated html file, and it seems to work well:

<script>
    MathJax = {
        tex: {
            inlineMath: [['$', '$']]
        }
    };
</script>
<script type="text/javascript" id="MathJax-script" defer="true" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>

grafik

I guess the MathJax script URL using a CDN should be added here:
https://github.com/lampepfl/dotty/blob/6635929a036ac8d340cd17eaea0c2a89bbc497b2/scaladoc/src/dotty/tools/scaladoc/renderers/Resources.scala#L111-L117

I'm less sure about configuration script. Should that be generated from Scala? If someone more familiar with the codebase could point me in the right direction I'd be grateful.

@odersky
Copy link
Contributor

odersky commented Jun 14, 2022

I am not sure whether this is in scope. Generally, we try to minimize external dependencies. @pikinier20 WDYT?

@pikinier20
Copy link
Contributor

I don't know if external dependencies added as the scripts in the HTML hurt us that much. However, there's also the other side of the coin that we probably don't want to spam dependencies inside HTML to have all possible features. I have a thought that maybe we should add an entry point in Scaladoc (setting or sth like that) to allow users to add scripts to their docs? @odersky

The above opinion is not exactly related to the Mathjax. It sounds interesting and I don't have anything against adding that. The libraries implementing FP concepts might also find it useful and describe theoretical stuff using it. Also, I can help you with the configuration part (you're right, we should generate that in Scala).

@sbrunk
Copy link
Author

sbrunk commented Jun 14, 2022

@odersky I understand the need to minimize external dependencies, but I'd like to argue that it's worth it for a few reasons:

MathJax is widely used by many websites and large organizations. See its Wikipedia page for instance. It is well supported, well documented and compatible with all browsers and even screenreaders.

Python supports math notation inside docstrings as well (via the reST math directive in this case). Sphinx, the de-facto Python doc tool can use MathJax as renderer. Libraries like Numpy use it to render math expression from their docstrings (example).

For creating similar libraries in Scala, or porting things over, rendering support for these kinds of expressions would be really helpful.

@sbrunk
Copy link
Author

sbrunk commented Jun 14, 2022

Also, I can help you with the configuration part (you're right, we should generate that in Scala).

Thanks @pikinier20 that'd be great! I could just start with a fork until we have a clearer picture if/how scripts should be included in general.

@pikinier20
Copy link
Contributor

So, basically I think that the simplest way to add this config would be to generate a small file with script. You can see an example in file Resources.scala :

private def dynamicJsData =
    val str = jsonObject("filterDefaults" -> jsonObject(
      FilterAttributes.defaultValues.toSeq.map { case  (n, v) => n -> jsonString(v) }:_*
    ))
    Resource.Text("scripts/data.js", s"var scaladocData = $str")

So, you need to generate the Resource.Text object and then append it to commonResources. First param describe the path in which the file will be rendered, second param is the body of file.

@julienrf
Copy link
Collaborator

Do you think scaladoc should or could be extensible so that third parties could provide support for various features (e.g., mermaid diagrams, etc.)?

@sake92
Copy link

sake92 commented Jun 16, 2022

Just my 2 cents here, I'd go with KaTeX instead of MathJax. See discussion in my PR for Scala 2 PDF: scala/scala#7432
It is much more lightweight, loads and renders faster, printing friendly etc. :)
You can see for yourself how site looks like here (loads in <1s), and PDF here.

@aschweig
Copy link

aschweig commented Jan 5, 2023

I'd also like to see this feature baked-in; as a stop-gap, I am using the following to update the .html files to add-in MathJax before publishing to a static site:

sbt doc
find target/scala*/api -type f -name '*.html' -mmin -5 -exec sed -i '0,/<script/s//<script type="text\/javascript" id="MathJax-script" async src="https:\/\/cdn.jsdelivr.net\/npm\/mathjax@3\/es5\/tex-mml-chtml.js"><\/script><script/' {} \;

The above requires GNU sed. (Macs may need to install it.)
I assume all files were generated in the last 5 minutes: I use -mmin -5 as a kludge to ensure that orphan .html files (those note being written in the last sbt doc command) are not getting continuously "fixed" and growing. I've left the glob target/scala*/api to facilitate easy reuse; it is better to use an explicit target directory.

Here's how an inline math formula looks in the scaladoc:

/** MathJax example -- note the double-backslash:
  *  Square root = \\( \sqrt{2} = 1.414214\dots\\) 
  */

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants