cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
stigler
Community Member

Best way to add LaTeX equations

Jump to solution

I'm a newbie to Canvas. I have found the equation editor, which works fine. But I have pages with many equations. Is there a way to include the LaTeX code in a page, and then have Canvas automatically render the equation? Thanks - this would be a big time saver.

1 Solution

Accepted Solutions
rgerritsen
Community Member

I also had trouble with adding equations to Canvas pages. Even if you use the equations editor, there is no easy way of adding equation numbers or references to equations. To workaround this I made a LaTeX to plain HTML converter. You put in a LaTeX article and it spits out basic HTML that can be read by the HTML editor of a Canvas page. I'll add a picture of how it can look and if you want to check out the converter visit GitHub.

View solution in original post

31 Replies
kona
Community Coach
Community Coach

 @stigler , I’m not sure if the answer to this question, but I’m going to share it with the https://community.canvaslms.com/groups/canvas-developers?sr=search&searchId=c6bd43d6-a278-4486-8a88-...‌ group in the Community to see if they can help. 

James
Community Champion

 @stigler ,

There is no short, easy way to do this.

That said, here are some things you might consider.

Embed the page (user level)

If the web page is housed on a secure server (https vs http), you can embed the page into Canvas through an iframe. It's not native to Canvas, but you can do all those things that Canvas' security model won't let you do like including the JavaScript necessary to render the LaTeX.

This approach doesn't do what you asked (have Canvas render it).

Add external JavaScript to process (admin level)

There currently is no support within Canvas for recognizing LaTeX triggers like $ or \[ \] and converting what is inside of it on the fly. To do so would require that your Canvas admin add custom JavaScript to invoke MathJax or KaTeX. That can have some accessibility issues, but I sure do like the ability to zoom with MathJax better than what I get out of Canvas' equation editor.

The custom JavaScript needs done at an account or sub-account level, you cannot add it at the course level and it may not work well with mobile apps. There have been several lengthy discussions and some feature requests about changing the way that math is handled with Canvas.

Your included library would be rendering it, not Canvas, but it would be similar.

Convert it to Canvas form

It is possible to take (most of) the equations on a page and convert them to Canvas format if you or someone you know has some programming skills. The Equation Editor returns an image that is built off of the LaTeX that went into it.

For example, let's say that I wanted to create the fundamental theorem of calculus and had this equation

264202_pastedImage_2.png

What I typed into the advanced view was this

\frac{d}{dx}\left[\int_a^xf(t)dt\right]=f(x)‍

What Canvas inserted as HTML was this (line breaks are mine):

<img 
class="equation_image"
title="\frac{d}{dx}\left[\int_a^xf(t)dt\right]=f(x)"
src="/equation_images/%255Cfrac%257Bd%257D%257Bdx%257D%255Cleft%255B%255Cint_a%255Exf(t)dt%255Cright%255D%253Df(x)"
alt="LaTeX: \frac{d}{dx}\left[\int_a^xf(t)dt\right]=f(x)"
data-equation-content="\frac{d}{dx}\left[\int_a^xf(t)dt\right]=f(x)"
/>‍‍‍‍‍‍‍

It should be fairly obvious? where all but the src attribute on line 4 came from. The "/equation_images/" portion is clear, its the rest of it that is confusing.

Since that src is really a URI, it has to be encoded. It turns out that it's double URI encoded (URI encoding of the URI encoding). There's a note in the source code that says it's stored in the database double escaped. If it wasn't, then a / in the equation would be unescaped once and treated as part of the path rather than part of the equation.

In JavaScript, this is done with the encodeURIComponent function. Note that I had to double escape the \ to get it to work.

var latex='\\frac{d}{dx}\\left[\\int_a^xf(t)dt\\right]=f(x)';
var single=encodeURIComponent(latex);
var double=encodeURIComponent(single);
console.log('LaTeX : ' + latex);
console.log('Single: ' + single);
console.log('Double: ' + double);

Other languages have support for URI encoding, but they are normally greedier than the JavaScript version. By that, I mean they tend to encode all reserved characters like the ( and ). The JavaScript encodeURIComponent does not adhere strictly to the RFC3986 standard in that it does not escape these characters while most of the other implementations will. 

A-Z a-z 0-9 - _ . ! ~ * ' ( )

The standard would also say to escape ! * ' ( ). But there is a note that says you don't have to escape them if they won't be used as delimiters, so we're okay. It just means that whatever implementation we find in a library will probably go ahead and escape them. However, the support for regular expressions and the ease of use (over command line JavaScript) may mean that you want to use a different language


Note that for PERL, which has excellent text processing and regular expression support, there is the URI::Escape::XS module that supports encodeURIComponent. Here is some PERL code to do the conversion.

use URI::Escape::XS;
my $latex   = '\frac{d}{dx}\left[\int_a^xf(t)dt\right]=f(x)';
my $single  = encodeURIComponent($latex);
my $double  = encodeURIComponent($single);
print "$latex\n";
print "$single\n";
print "$double\n";

Ahh -- we're almost there now. We need a way to recognize the LaTeX delimiters, pull out the inside, and convert it. Consider this block. Here's I'm taking a paragraph that contains two LaTeX values:

<p>Consider a function $f$ whose domain is $(-\infty,\infty)$</p>

I'm going to convert it to Canvas format, using a subroutine I called canvexify (you could rename it to cantexify or cantex or latex2canvas if you like). In this case, it only looks for items with a single $ delimiter.

#!/usr/bin/perl

use strict;
use diagnostics;
use warnings;
use URI::Escape::XS;

my $t = q|<p>Consider a function $f$ whose domain is $(-\infty,\infty)$</p>|;

$t =~ s{\$(.*?)\$}{canvexify($1)}xmsge;
print "$t\n";

sub canvexify {
  my $tex = shift || return '';
  my $src = encodeURIComponent( encodeURIComponent($tex) );
  my $img =
q{<img class="equation_image" title="%s" src="/equation_images/%s" alt="LaTeX: %s" data-equation-content="%s" />};
  my $t = sprintf( $img, $tex, $src, $tex, $tex );
  return $t;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The code is relatively simple and doesn't trap for things like newlines within the LaTeX code (it will work if they're present, but not remove them, so the title attribute contains a newline). If there was a quote in the code, you may need to do something special -- luckily, we don't use double quotes in LaTeX, but use two apostrophes instead.

When you run the code, you get this (I manually added the line breaks:

<p>
Consider a function
<img class="equation_image" title="f" src="/equation_images/f" alt="LaTeX: f" data-equation-content="f" />
whose domain is
<img class="equation_image" title="(-\infty,\infty)" src="/equation_images/(-%255Cinfty%252C%255Cinfty)" alt="LaTeX: (-\infty,\infty)" data-equation-content="(-\infty,\infty)" />
</p>

You could take and paste that into Canvas in the HTML editor view. When I do that and then save it, I get this in Canvas

264204_pastedImage_12.png

Now that we know it's working, you could create a function that invokes it so it looked cleaner.  You could replace lines 10 and 11 of the code with this:

print latex2canvas($t) . "\n";

sub latex2canvas {
  my $t = shift;
  $t =~ s{\$(.*?)\$}{canvexify($1)}xmsge;
  return $t;
}

Now the task is to modify the code to read the input from a file so that you don't have to hard-code it into the program itself. That gets a little bit more complicated since you don't want to copy/paste the entire document, you only need the portion within the <body> </body> elements.

There may be someone out there who has already written a solution, I just threw this code together while writing this response so you could get a sense of what would be involved.

mhegg1
Community Participant

Thanks for the tips! It would be nice if there was a more seamless option, though.

stigler
Community Member

James,

Thanks for all this. It really is something that Canvas should fix. Meanwhile, though, I have found a solution that works for me. I write my content in markdown, and just include the $$ delimited equations in the markdown. I then go to a really useful website: Upmath: Markdown & LaTeX Online Editor . I paste my markdown on the left, and it renders a preview on the right. If you click the HTML button, it displays the complete HTML code on the right, which I can copy/paste into Canvas. It works beautifully. It actually is transforming the equations into images using Tex Live. It does all this automatically, stores them on their server (somewhere), and embeds the image calls into the HTML. The integration is beautiful

Jim

James
Community Champion

I doubt that Canvas is going to fix it any time soon. There's just not enough demand for it and there are bigger things to work on that will impact more people. Math and science people have been long frustrated by the lack of support within quizzes.

The solution you found looks interesting and I love that allowed for Tikz graphs, which just isn't available in Canvas at all. If I want to use those now, I convert my LaTeX document to PDF and then let people open the PDF file. When I was younger, I used to spend hours converting things all of my PDFs to HTML to display on the web and now that I'm older and find it harder to get thing done, I just make the PDF available to people to download. Since Canvas offers inline previewing of PDFs and browsers have built-in support for displaying PDFs, it's easier for the user to see the content than it used to be.

One thing your solution (and my conversion to a PDF) falls a little short on is accessibility. It marks up the alt attribute with the LaTeX as does Canvas, but Canvas also adds a prefix of "LaTeX: " to the alt tag so people knows that's what it is. Canvas also uses the LaTeX for the title property so that when you mouse over the image, it displays. Finally, Canvas converts the LaTeX into MathML so that the screen readers can read the MathML.

Accessibility may not be high on your list of criteria, especially given the difficulty in obtaining with mathematical content in the first place. I mention this because it is high on Canvas' list and because someone asked me just today how Canvas handled accessibility with math and so the answer was fresh in my mind.

James
Community Champion

I explored the possibility of taking the code I wrote and creating a web page that would do the conversion for you. That is, you could just take the HTML code you already had, copy and paste it into a textbox, and it would go through and convert it to the Canvasized format that you could copy/paste into Canvas.

A few things stopped me, but that doesn't mean that a less-function version still wouldn't be helpful. I especially thought about it with all of the wiki pages I have with statistics notes that would have been nice to convert into Canvas pages.

Ideally, I would like to add a button to the editor that would take everything that is in the RCE textbox, look for valid math nestled between $ or other other delimiters and replace it with you having to do anything else. In this way, you could just type the content in the RCE, add something really quick like $\frac{2}{3}$ and keep going, then click the button.

I read a lot about inserting content but didn't find anything that would allow you take the existing content and edit it short of a TinyMCE plugin. I've done some work trying to modify the TinyMCE plugin and shared that in other places, but I consider it highly experimental and very likely to break something else.

Then I thought about adding a separate button to the page, through a UserScript manager like Tampermonkey. That may still be a viable solution, I just haven't made time to explore it further.

Writing a web page that people could copy/paste into and from is probably the quickest way, but it's not as friendly.

The quickest way to develop it is also the least friendly. That would be to write some code that would take the contents of the RCE and scan for the math content and replace it. But you would have to paste it into the browser's console to run whenever you wanted to.

Another option, and probably the one I would ultimately use if I was to go, would be to write a script that would download the contents of a web page from Canvas, make the modifications, and then re-upload the page back. I've already got scripts written that would do all of that except for the LaTeX portion, but it would require that people be familiar with coding to use it, so it's not something I would publish for mass consumption.

Mixed into all of that automatic conversion thing is the possibility that you have invalid LaTeX markup -- at least as far as Canvas knows -- and what to do with it. Canvas doesn't load some packages that I use regularly, so I might forget that I can't do something in Canvas that I can while directly editing LaTeX or other packages like my Differential Equations wiki where I've loaded the rsfs package to get my script L for the Laplace transform symbol.

stigler
Community Member

James,

Another approach that would be user friendly would be to write a Chrome Extension. You could be in the RCE, then click a button on your Chrome toolbar to go through and replace all the $$...$$ stuff with the proper Canvas equation format.

Jim

Shar
Community Champion

Hi  @stigler ‌

Great solution with that Upmath!

I'm going to toss my old-school solution in the ring as well... I usually make pictures of LaTeX or other non-native HTML font stuffs, and put those in where they belong in the Canvas page/quiz.

The quadratic equation. All you ever need for solving polynomials.

The beauty of this solution is that I can also include alt text. And if I name my images cleverly enough, I can swap them out easy enough from the files section if the instructor makes a change or there was an error I did not catch.

Oh and if it's on a quiz, don't worry I do not give away the answer with the alt text. I call it something like QuizImage01 (in the alt-text and filename) and so forth. Smiley Wink

Cheers - Shar

a1184615
Community Member

About three years ago I could paste \parbox{box-width}{LaTeX source} into the "Advanced Maths Mode" in Canvas and it would typeset the LaTeX source beautifully.  However, some Canvas bureaucrat then disabled \parbox and refused to restore it, much to my annoyance. 

One way to still proceed is to manually put in the line breaks yourself.  For example, paste into Advanced Maths Mode the following

\text{not a minimiser of $f(\vec{x})$, and $-\nabla f(\vec{x})$}\\
\text{is perpendicular to the nonempty set $S(\vec{x})$ }

and it will get typeset by Canvas much the same as if these two LaTeX lines are within the following in a LaTeX document (which is of course how I prepare the info)

\(\begin{array}{l}
...
\end{array}\)

(Curiously, the preview in Canvas centers each of the lines, but the eventual actual display is left-aligned---at least for our installation.)