Discourse should render LaTeX


(Why not?) #1

LaTeX support should be easy to implement using MathJax.

IMHO this should be an official plugin (but maybe disabled by default).

If you agree, Like this post.


Discourse Q&A plugin for sorting posts with the most likes at the top
More advance editor should be here?
(Peter Stoinov) #2

What about just plugin? If speed and responsiveness is key to discourse.com then implementing such highly specialized features in core will be counterintuitive.


(Why not?) #3

If it was just a matter of putting some files in the right place, I’d be fine with it. But Ruby being Ruby, installing a third-party plugin is probably going to be painful: You’ll probably have to use bundle, and gems, and rake to migrate the production database, and in general installing it will be a Project involving nervously copy-pasting commands from instructions (if you’re lucky) or random blog/forum posts (if you’re not) with only a vague idea about what they do. I am emphatically not a Ruby/Rails developer.

I want to be able to do a vanilla install and check a box in the admin control panel that says “Yes, I want LaTeX.”


(Peter Stoinov) #4

as far as the description on What is Discourse? | Discourse - Civilized Discussion goes, I think it will be far easier. Maybe even automated. And once they get that directory up and running it will be matter of Building Your Own Forum™ :smiley:


(Henrik Enggaard) #5

I totally agree. There is no reason to get over nervous about the way it could work given the worst possible outcome. If the plug-in infrastructure and the vision of Discourse is to be taken seriously, then it will probably be a very straight forward process, as long as the administrator can set up the rest of Discourse. (Remember, Discourse will be offered on their servers - they will probably have a plug-in installer system in place.)


(Nilay Kumar) #6

What’s the status on this? I agree that MathJax support should be an officially available (but perhaps off by default).

As a purely technical question, how would one go about adding the functionality? i.e. where do we stick the script? Simply sticking it into views/layouts/application.html.erb seemed to be the simplest way of doing it, but it doesn’t render the math. Is there an obvious reason this shouldn’t work? (I’m new to Discourse and Rails, sorry)

Note that I’m ignoring all the “plugin” functionality for the moment; let’s say I just want MathJax on my own forum. How would I go about doing that?


(Aaron Weiss) #7

You’d need to add calls to the respective parsing functions from any place where you want it to be rendered, I’d imagine. After all, it needs to be told WHAT it’s parsing as LaTeX.


(Nilay Kumar) #8

Unless I’m mistaken, there should be no need for extra calls. Check out this jsFiddle.
All I’ve done is included the MathJax script, and math renders itself. That’s typically how I’ve seen MathJax used.


(Aaron Weiss) #9

Sorry, for some reason it didn’t even dawn on me that MathJax was a javascript script (didn’t even think about jax being ajax and I naturally assumed ruby). Nevertheless, you’re still best off having it included in pages that you want to render LaTeX and excluded otherwise. Definitely shouldn’t be hard to add in though.


(Andrew Hunn) #10

I got as far as making a plugin and getting it included in the head, but I don’t know enough about AJAX to make it force calling the script when displaying more posts and navigating, etc.

I assume, like the discourse_emoji plugin, it needs to be called specifically when performing certain actions.


(Nilay Kumar) #11

That’s as far as I got as well. I’m not sure how the Discourse rendering pieces fit together, so I’m not sure when/how to request MathJax to update…

Does anyone have this working/know how to get it working?


(Sam Saffron) #12

Just start by forking the emoji plugin, blank it out and then inject this into the markdown pipeline (like it does)

https://github.com/discourse/discourse/tree/master/vendor/gems/discourse_emoji


(David) #13

Hello,

I would like to share my solution.

At first I tried injecting mathjax into the markdown pipeline the way the emoji plugin does, as sam suggested. Very quickly, however, this became a nightmare after I realized that by design mathjax does not provide a MathJax2HTML function that can be used in the expected fashion.

As a workaround, I decided keeping the mathjax code fully client-side and I keep the math updated by monitoring DOM changes. I use the non standard DOMSubtreeModified event, which works well in our boards since we are a small community, and Chrome supports it. So far it’s ran smoothly :).

I would be willing to find a better way though.

https://github.com/rux-pizza/discourse/blob/master/vendor/gems/discourse_mathjax/vendor/assets/javascripts/discourse_mathjax.js

https://github.com/rux-pizza/discourse/blob/master/vendor/gems/discourse_mathjax/.


(Kasper Peulen) #14

Will this feature ever come ?
I’m not an expert at all, but chatjax does work for mathjax support at discourse. For example, try chatjaxing this:

$\sum_{n=k+1}^{b} {a_n}^2 ∈ ℝ$

Maybe adding this to the header may do the trick ?

<script>
		function startChatJax()
{
if (window.MathJax===undefined)
{
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML";
var config = 'MathJax.Hub.Config({' + 'extensions: ["tex2jax.js"],' + 'tex2jax: { inlineMath: [["$","$"],["\\\\\\\\\\\\(","\\\\\\\\\\\\)"]], displayMath: [["$$","$$"],["\\\\[","\\\\]"]], processEscapes: true },' + 'jax: ["input/TeX","output/HTML-CSS"]' + '});' + 'MathJax.Hub.Startup.onload();';
if (window.opera)
{
script.innerHTML = config
}
else
{
script.text = config
}
document.getElementsByTagName("head")[0].appendChild(script);
(doChatJax=function(){window.setTimeout(doChatJax,1000);
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
})();
}
else
{
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
}
}

startChatJax();
		</script>
		
<script type="text/x-mathjax-config"> 
MathJax.Hub.Config({"HTML-CSS": { preferredFont: "TeX", availableFonts: ["STIX","TeX"], linebreaks: { automatic:true }, EqnChunk: (MathJax.Hub.Browser.isMobile ? 10 : 50) }, 
tex2jax: { inlineMath: [ ["$", "$"], ["\\\\(","\\\\)"] ], displayMath: [ ["$$","$$"], ["\\[", "\\]"] ], processEscapes: true, ignoreClass: "tex2jax_ignore|dno" }, 
TeX: { noUndefined: { attributes: { mathcolor: "red", mathbackground: "#FFEEEE", mathsize: "90%" } }, Macros: { href: "{}" } }, 
messageStyle: "none" 
}); 
</script> 

Edit: It seems to work. I added a new header in the settings and I get this:
http://mathematics.discoursehosting.net/t/mathjax-test-sum--n-k-1-infty-a-n-2/1


(Kasper Peulen) #15

Hmm… this chatjax script give some problems.
The brackets $\{1,2,3 \}$ disappear when they are used in math expressions.
And also problems with stars. If I would write $f^*(x)=f^*(y)$ then the markdown messes up with this.

@masda70 I don’t know how I can use your script. I’m absolute noob with ruby/javscript whatever. I use paid discourse hosting. I tried to install your script using: Admin → Customize → New → Header
But it doesn’t work. Could you explain to me how I can get your script to work ?


(Michael - DiscourseHosting.com) #16

Prefixing the brackets and the stars by an extra backslash solves this in combination with the chatjax script. It’s not very pretty, but it works…

We’ve been thinking about other solutions but in that case there should be a way to disable markdown and somehow mark a certain (part of the) post as MathJax markup.


(Kasper Peulen) #17

Thanks again for this solution :smile:

This opensource markdown editor: http://benweet.github.io/stackedit/, also uses the combination of markdown and mathjax. I was thinking that it may be possible to copy the solution they use.


(Kasper Peulen) #18

I guess this is the only real solution in the end. I found one other problem when typing this:

\begin{align*}
1 + 1 &= 2  \\
2 &= 1 + 1 
\end{align*}

Luckily, this was easily fixed with adding one extra \

\begin{align*}
1 + 1 &= 2  \\\
2 &= 1 + 1 
\end{align*}

Edit: Another problem happens with isubscript, which is probably the worst of all issues, as sometimes you use subscript all the time, and having to use x\_0 instead of x_0 all the time is quite bothersome.


(Kasper Peulen) #20

I’ve made some code that is able to display mathjax in code tags. For example $a^*+b^*$ is displayed as math without code make up, if you use this version of the chatjax code. It has some downsides, but for my website it is the best solution so far.
For example:

I’m quite content with this solution. I’m only not so happy with how chatjax renders the preview. It needs to reload all the math all the time.

function startChatJax()
{
if (window.MathJax===undefined)
{
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML";
var config = 'MathJax.Hub.Config({' + 'extensions: ["tex2jax.js"],' + 'tex2jax: { inlineMath: [["$","$"],["\\\\\\\\\\\\(","\\\\\\\\\\\\)"]], displayMath: [["$$","$$"],["\\\\[","\\\\]"]], processEscapes: true,  skipTags: ["script", "noscript", "style", "textarea"] },' + 'jax: ["input/TeX","output/HTML-CSS"]' + '});' + 'MathJax.Hub.Startup.onload();';
if (window.opera)
{
script.innerHTML = config
}
else
{
script.text = config
}
document.getElementsByTagName("head")[0].appendChild(script);
(doChatJax=function(){window.setTimeout(doChatJax,1000);
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
            var spans = document.getElementsByClassName('MathJax_Preview');
            for (var i = 0; i < spans.length; i++) {
                var span_parent = spans[i].parentNode;
                var parentname = span_parent.tagName.toLowerCase();
                if (parentname == "code") {
                    spans[i].parentNode.setAttribute("style", "font: inherit;font-size: 100%;background: inherit;border: inherit;margin: 0;padding: 0;white-space: inherit;display: inline;");
                }
            }
})();
}
else
{
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
}
}
startChatJax();

(Sam Saffron) #21

see Brand new plugin interface for a rather clean solution