Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Evaluating Latex Math in Javascript

I am working on a html-based calculator, and I want to render an expression, then evaluate it, and all of this must be done in Javascript. I would prefer for the expression to be written in LaTeX, and for it to be possible to edit the rendered expression interactively, but other languages could work.

What I've tried before is to render the expression, interactively, with MathQuill, and then evaluate it with MathJS. This works, to some extent, however, since the two packages are designed with different goals (MathQuill renders LaTeX, while MathJS has a custom math syntax), it doesn't work perfectly well (e.g. if a user types in \frac{5}{17*x} and assumes that it is the correct syntax, then evaluates it and gets an error from MathJS).

Currently, I see three ways to proceed:

  • Continue with what I have (or maybe switch to MathJax- which is better? ).
  • Find a tool that does both rendering and evaluating (whether it is in latex or some other language)
  • Find two tools for rendering and evaluating with close (if not the same) syntax
  • Write my own rendering and evaluating tool, as recommended here. I would prefer not to do this, because it seems kind of tedious, and I don't want to reinvent the wheel.

What is the bast way to do this?

Update 1: After looking through the list of alternative languages available at altJS, I think I could use Python, Ruby, or Basic as a language for user input. If I did do that, it would open up so many possibilities for rendering it (technically, it's not "rendering," but just think about how many syntax highlighters there are out there). However, I don't want users to have access to the more advanced elements of these languages, because it would add confusion to my users, and it could also be unsafe (like using eval). I only want users to be able to use math operations, variables (only those that I specify that they can, and also user-created), and functions (only those that I specify that they can, and also user-defined). Is there a way to restrict the subset of the language that can be used?

Update 2: I looked around some more on the altJS page, and realized that almost all of the languages were designed to compile language XYZ to JavaScript, then run the JavaScript on the page, instead of running language XYZ on the page. I haven't looked into each and every single one, but most of them seem to be like this. Others, like Brython, seem to be designed to run language XYZ in the browser, but as a replacement/complement to JavaScript instead of as an input language for the user. Is there some workaround so I can use these methods as input?

Update 3: Thank you to @SpaceDog for that information, and for pointing out that I haven't been specific in what users should be able to achieve. So, here is the functionality that I want to be achieved:

  1. Basic Operations (addition, subtraction, multiplication, division/fractions, exponentiation, roots, modulus)
  2. Functions (trigonometric functions, logs, etc.)
  3. Constants (e, pi, etc.)
  4. Variables (assignment, reassignment, and using them)
  5. User defined functions

LaTeXCalc seems to meet all of these requirements, except for the last one. Also, it doesn't appear to be in Javascript.

This brings me to another idea I've thought of: use something like MathJax for presentation, then use Wolfram Alpha API to actually handle the computation. The benefits are that it would have much more advanced options for both input and output. However, the application would be rendered useless (why not just use wolframalpha.com, if the calculator is practically just a clone?), it costs money, and the app wouldn't work offline (it is a desktop app, written in HTML/CSS/JS). Thoughts on that?

like image 222
hkk Avatar asked Nov 15 '13 03:11

hkk


People also ask

How do you evaluate an expression in JavaScript?

eval() returns the completion value of statements. For if , it would be the last expression or statement evaluated. The following example uses eval() to evaluate the string str . This string consists of JavaScript statements that assigns z a value of 42 if x is five, and assigns 0 to z otherwise.

How do I get math in JavaScript?

Math. js can be installed using various package managers like npm, or by just downloading the library from the website: https://mathjs.org/download.html.

Does Mathjs use eval?

Mathjs versions 4 and newer does not use JavaScript's eval under the hood. Version 3 and older did use eval for the compile step. This is not directly a security issue but results in a larger possible attack surface.

Can latex do calculations?

This package introduces several new instructions that allow you to do several calculations with integer and decimal numbers using LATEX. Apart from add, multiply or divide, we can calculate powers, square roots, logarithms, trigonometric and hyperbolic functions . . .


1 Answers

It seems you want to do two separate things, nicely display the equation and evaluate it. So you need a tool that does both. Latex is more focus on presentation rather than evaluation, although it is possible to evaluate it (see this answer: Is there a calculator with LaTeX-syntax?) at least for a subset.

A lot of this depends on how complex you want to make the calculator -- what operations you want to allow. If you're using a small subset (and it sounds like you are) it'd be pretty easy to write the converter by hand. I would look into MathML which has both presentational and semantic markup -- and many available tools. However it may not be the easiest for your users to grasp.

If users are familiar with latex, and the subset of included symbols is small then it'd be easy enough to parse latex into a format that can be directly evaluated.

I think you need to define exactly what you're allowing the user to access in order for anyone to provide a better example as to what is 'best'.

EDIT -- in response to your update

Well, you're dangerously close to writing a full programming language (all you need are conditions and loops -- or labels). So reinventing the wheel doesn't sound like a great idea. In this case I definitely don't think you want LaTeX as your input language, ideally you want something more familiar to your users.

What follows is what I would do and where I would start if I were going to do this, it's not a definitive answer and I would do a lot more research before starting to make sure I'm not duplicating effort.

I'd build a parser that takes a subset of JavaScript, this parser would do two things (or there would be two parsers) one would be to translate the code to LaTeX or MathML and the second would be to evaluate / execute the code.

Doing this offline, in C, I'd turn to Lex and Yacc (or Flex and Bison, etc) and a quick Google reveals there's a Javascript equivalent: Jison. That'll give you the backbone of the parser for the language and you can amend it.

Alternatively start with an existing JS parser might help, try this answer: JavaScript parser in JavaScript. T

Once you have the parse backbone you can keep it simple at first -- translating to a displayable language should be fairly easy and for evaluating you could risk just using eval -- because the parser will have already ensured that the input is only using what you're allowing. However I would advise against that in a production version (it's fine for test) and it doesn't take much extra work to map the tokens to internal functions.

After that you might want to look at improving the displayed output, perhaps you want to try and simplify input or reorder it to make more sense. That would require taking the internal representation from your parser and doing some clever stuff on it. But get the first steps working first.

You want this to work offline, so my other idea of a server hosting some of the other example programs you cite isn't going to work (and using Wolfram Alpha or Google is a good option there -- but, as you say, what's the point of the program then). But you might also consider if you'd get a better head start writing this in a different base language -- although I'm guessing you want the portability of HTML/JS/CSS.

The other things you link are all other possible ideas, I just think you'll get more benefit having your own parser internally rather than relying on 3rd party code for each application. With your own parser you can easily add functionality or language features later on.

Final thought, you're not necessarily restricting to Javascript as the input with this method. If you think your users will cope with Reverse Polish Notation then it's easy to write a parser by hand for -- but you will have to do some work on formatting it nicely for output.

like image 156
SpaceDog Avatar answered Sep 29 '22 18:09

SpaceDog