5
votes

I want to display equations in LaTeX and render them clientside. Those equations have variables that must be changed. So far, I've only found MathJax but it doesn't update values when they change. There are examples like http://plnkr.co/edit/FLduwmtHfkCN5XPfzMsA?p=preview where it does change live, but that's from Angular2 and has thing weird line in it MathJax.Hub.Queue(["Typeset",MathJax.Hub, this.el.nativeElement]); that leaves me with an error (because I can't find the MathJax variable). ng-katex doesn't work either because it doesn't show up in my ng-modules folder and it has weird output.

MathJax itself works perfectly, except when you change something in the DOM

E.g:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-test',
  template: '
  <button (click)="decrDenumerator()">-</button>
  Frac: {{frac}}
  <button (click)="incrDenumerator()">+</button>',
  styleUrls: ['./test.component.sass']
})
export class TestComponent implements OnInit {
  denumerator = 1;
  frac = '$\\frac{1}{' + this.denumerator + '}$';

  constructor() {
  }

  ngOnInit() {
  }
  incrDenumerator() {
    this.denumerator = Math.min(10, this.denumerator + 1);
    this.frac = '$\\frac{1}{' + this.denumerator + '}$';
  }

  decrDenumerator() {
    this.denumerator = Math.max(1, this.denumerator - 1);
    this.frac = '$\\frac{1}{' + this.denumerator + '}$';
  }
}

When clicking on one of those buttons, it will only show it as text, while the first generated output from MathJax will be next to it.

How can I make MathJax notice these changes and act accordingly? Thank you very much.

1
You might want to add a sample of what you've tried. Asking for someone to hand you a solution is not a good fit for Stackoverflow.Peter Krautzberger
@PeterKrautzberger I added some example codeAlbêr

1 Answers

3
votes

After trying a lot, I've found the answer.

I had to import MathJax types. npm install --save @types/mathjax

and then import them in the tsconfig.app.json file with "types": ["mathjax"].

I then created the following directive

import {Directive, ElementRef, Input} from '@angular/core';

@Directive({
  selector: '[tex]'
})
export class TexDirective {
  @Input('tex') tex = '';
  constructor(private element: ElementRef) {}

  ngOnInit() {
    this.update();
  }

  ngOnChanges() {
    this.update();
  }

  update() {
    this.element.nativeElement.innerHTML = '$' + this.tex + '$';
    MathJax.Hub.Queue(['Typeset', MathJax.Hub, this.element.nativeElement]);
  }
}

I works perfectly.