examples angularjs mathjax

angularjs - examples - mathjax main



Logrando que MathJax se actualice después de los cambios al modelo AngularJS (10)

Aquí hay una directiva que le permite usar doble rizado dentro de la expresión (y no requiere establecer una variable de expresión en el alcance). Se basa en esta publicación del blog , excepto que solo admito MathJax, y guardo el DOM compilado, para que se actualice sobre los cambios en las variables de alcance.

Como dijo Alex Osborn, es mejor separar las no matemáticas de las matemáticas.

Uso:

<p>This is inline math: <latex>x^{ {{power}} }</latex>, and this is display math: <div latex> y^{ {{power}} } .</div></p>

En un fragmento de código:

angular.module(''app'', []) .controller(''ctrl'', function($scope) { $scope.power = "//sin(x^2)"; }) .directive(''latex'', function() { return { restrict: ''AE'', link: function(scope, element) { var newDom = element.clone(); element.replaceWith(newDom); var pre = "//(", post = "//)"; if (element[0].tagName === ''DIV'') { pre = "//["; post = "//]"; } scope.$watch(function() { return element.html(); }, function() { console.log(element); newDom.html(pre + element.html() + post); MathJax.Hub.Typeset(newDom[0]); }); } } });

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> <div ng-app="app" ng-controller="ctrl"> <p>Power: <input ng-model="power" /> </p> <p>This is the inline latex, <latex>x^{ {{power}} }</latex>, followed by some display mode latex <div latex>y^{ {{power}} } = {{power}}.</div>And that''s it! </p> </div>

Estoy tratando de usar el texto de enlace bidireccional de AngularJS que incluye ecuaciones de estilo de látex. Me gustaría llamar a MathJax para formatear las ecuaciones, pero no estoy seguro de cuál es la mejor manera de garantizar que se llame a MathJax cuando AngularJS termine de cambiar el modelo. Creo que necesito una devolución de llamada. Aquí está mi JavaScript:

var myApp = angular.module(''myApp'',[]); function MyCtrl($scope) { $scope.Update = function() { $scope.Expression = ''Evaluate: //( //frac{9}{4} //div //frac{1}{6} //)''; MathJax.Hub.Queue(["Typeset", MathJax.Hub]); } $scope.Expression = ''Evaluate: //( //frac{5}{4} //div //frac{1}{6} //)'';

}

Y aquí está mi HTML:

<div ng-controller="MyCtrl"> <button ng-click="Update()">Update</button> {{Expression}} </div>

Fiddle está aquí: http://jsfiddle.net/LukasHalim/UVjTD/1/ . Notará que en el violín la expresión original no se elimina, incluso después de hacer clic dos veces en el botón de actualización, parece un error o conflicto.


Construyo una directiva para esto ....

FIDDLE: http://jsfiddle.net/8YkUS/1/

HTML

p data-math-exp data-value = "math">

JAVASCRIPT

appFlipped.directive("mathExp", function () { return { scope: { value: "=" }, link: function (scope, el) { var domEl = el[0]; scope.$watch("value", function (newValue) { //nothing to do here if (newValue == null || window.MathJax == null)return; //update the dom with the new value and pass the hub for styling the equation domEl.innerHTML = ''`'' + newValue + ''`''; MathJax.Hub.Queue(["Typeset", MathJax.Hub, domEl]); }); } } });


Creé un simple violín expandiendo la respuesta de Ben Alpert. Aquí está el fiddle y el plunk .

Específicamente, si un texto tiene solo una parte del mismo para convertir con Mathjax, puede usar esto. Para mathjax en línea debe rodear el texto con $, y para la visualización en bloque debe rodear el bloque con $$. (Puede usar el formato que desee si crea la expresión regular correspondiente)

app.js

MathJax.Hub.Config({ skipStartupTypeset: true, messageStyle: "none", "HTML-CSS": { showMathMenu: false } }); MathJax.Hub.Configured(); var myApp = angular.module("myApp", []); myApp.directive("mathjaxBind", function() { return { restrict: "A", scope:{ text: "@mathjaxBind" }, controller: ["$scope", "$element", "$attrs", function($scope, $element, $attrs) { $scope.$watch(''text'', function(value) { var $script = angular.element("<script type=''math/tex''>") .html(value == undefined ? "" : value); $element.html(""); $element.append($script); MathJax.Hub.Queue(["Reprocess", MathJax.Hub, $element[0]]); }); }] }; }); myApp.directive(''dynamic'', function ($compile) { return { restrict: ''A'', replace: true, link: function (scope, ele, attrs) { scope.$watch(attrs.dynamic, function(html) { html = html.replace(//$/$([^$]+)/$/$/g, "<span class=/"blue/" mathjax-bind=/"$1/"></span>"); html = html.replace(//$([^$]+)/$/g, "<span class=/"red/" mathjax-bind=/"$1/"></span>"); ele.html(html); $compile(ele.contents())(scope); }); } }; }); function MyCtrl($scope, $element) { $scope.html = "A coin of is $ //frac{5}{4} $ thrown $$//frac{1}{6}$$ dfv"; }

index.html

<!DOCTYPE html> <html ng-app="myApp"> <head> <meta charset="utf-8" /> <title>AngularJS Plunker</title> <script>document.write(''<base href="'' + document.location + ''" />'');</script> <script src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML&delayStartupUntil=configured&dummy=.js"></script> <link rel="stylesheet" href="style.css" /> <script data-require="[email protected]" src="http://code.angularjs.org/1.2.7/angular.js" data-semver="1.2.7"></script> <script src="app.js"></script> </head> <body> <div ng-controller="MyCtrl"> <input type="text" ng-model="html"/><br/> <div dynamic="html"></div> </div> </body>

style.css

input[type="text"] { width: 800px; } .red{ color:red; display:inline-block; } .blue{ color:blue; display:block; }


Después de haber perdido muchos días (y quizás semanas) luchando contra MathJax, estoy muy familiarizado con sus diversas peculiaridades con la actualización de las expresiones matemáticas sobre la marcha. Soy nuevo en Angular, pero esto me dio una buena oportunidad para sumergirme y terminé con una solución que resuelve mis problemas, espero que también resuelva el tuyo.

Demostración en vivo: http://jsfiddle.net/spicyj/YpqVp/

En lugar de utilizar la interpolación simple que proporciona Angular, creé una nueva directiva basada en ng-bind llamada mathjax-bind .

Si expression es una variable que contiene código matemático, entonces en lugar de /( {{expression}} /) puede escribir:

<span mathjax-bind="expression"></span>

y todo estará compuesto y actualizado en los momentos apropiados.

El código de apoyo para la directiva es el siguiente:

myApp.directive("mathjaxBind", function() { return { restrict: "A", controller: ["$scope", "$element", "$attrs", function($scope, $element, $attrs) { $scope.$watch($attrs.mathjaxBind, function(texExpression) { var texScript = angular.element("<script type=''math/tex''>") .html(texExpression ? texExpression : ""); $element.html(""); $element.append(texScript); MathJax.Hub.Queue(["Reprocess", MathJax.Hub, $element[0]]); }); }] }; });


Echa un vistazo a http://jsfiddle.net/pz5Jc/

En su plantilla:

{{Label}} <span id="mathElement">{{Expression}}</span>

En su controlador:

$scope.Update = function() { $scope.Expression = ''//frac{9}{4} //div //frac{1}{6}''; $scope.Label = ''Updated Expression:'' var math = MathJax.Hub.getAllJax("mathElement")[0]; math.Text(''//frac{4}{4} //div //frac{2}{6}''); }

Par de puntos:

No estoy muy familiarizado con mathjax, pero:

  • Dividir la etiqueta de la expresión le permite trabajar con la expresión directamente.
  • Debe seleccionar manualmente un elemento DOM para forzar una actualización de la expresión. Lamentablemente, esta no es una forma muy "angular" de hacer las cosas, pero cuando mathjax analiza la expresión (e inserta sus propios elementos DOM), empuja esos elementos fuera de los enlaces angulares.
  • La solución aquí es seleccionar específicamente el elemento mathjax correcto y llamar a una función de cambio de texto para actualizar la expresión.

En realidad pensé en otra solución. Cuando renderizas un poco angular y matemático haces esto:

CONTROLADOR ANGULAR

$scope x = 5;

HTML

<h3> {{ ''$ Multiplication = ''+ x + '' * 2 ='' + (x*2) + ''$''}} </h3>

Matemáticas formadas resultado de Jax

Multiplicación = 5 * 2 = 10

La clave es incluir los signos de dólar dentro de los corchetes como texto. Cuando Angular los presenta, los signos de dólar aparecerán como texto sin formato, pero cuando el formato Math Jax entre en acción, reconocerá los signos de dólar y hará la magia.


Jugué un poco más con la solución de Roney. La pantalla matemática debe mostrarse en modo de pantalla; con

<script type="math/tex; mode=display">

Agregué un atributo al intervalo generado para indicar eso.

Fiddle está aquí http://jsfiddle.net/repa/aheujhfq/8/


Puede probar con mis modificaciones http://jsfiddle.net/bmma8/4/ modificar la entrada o hacer clic en el botón actualizará su expresión.

js

MathJax.Hub.Config({ extensions: ["tex2jax.js"], jax: ["input/TeX","output/HTML-CSS"], tex2jax: {inlineMath: [["$","$"],["//(","//)"]]} }); var myApp = angular.module(''myApp'',[]); function MyCtrl($scope, $log) { var QUEUE = MathJax.Hub.queue; // shorthand for the queue $scope.Update = function() { QUEUE.Push(["Text",MathJax.Hub.getAllJax("MathOutput")[0],"//displaystyle{"+ $scope.Expression+"}"]); //$scope.Expression = ''Updated Expression: //( //frac{9}{4} //div //frac{1}{6} //)''; //MathJax.Hub.Queue(["Typeset", MathJax.Hub]); } $scope.Expression = ''Original Expression: //( //frac{5}{4} //div //fra

y html:

<div ng-controller="MyCtrl"> <button ng-click="Update()">Update</button> <input ng-model="Expression" ng-change="Update()"> <div id="MathOutput"> You typed: ${}$ </div> </div>

Alexandre


Una solución simple es usar $ timeout para poner MathJax.Hub.Queue(["Typeset", MathJax.Hub]) en la cola de eventos del navegador (consulte Ejecutar una directiva después de que el DOM haya terminado de renderizarse ).

Algo como esto:

var app = angular.module(''myApp'', []); app.controller(''myController'', function ($scope, $timeout) { controller = this; $scope.Update = function () { $scope.value = " //( //frac{5}{4} //div //frac{1}{6} //)"; $timeout(controller.updateMathJax, 0); } this.updateMathJax = function () { MathJax.Hub.Queue(["Typeset", MathJax.Hub]); } });


La solución más simple, rápida y estable:

$rootScope.$watch(function(){ MathJax.Hub.Queue(["Typeset",MathJax.Hub]); return true; });

Ventajas:

  • Fácil de instalar, simplemente copie este código.
  • Todo en tu página es tipográfico.
  • Se rinde mucho más rápido que las otras soluciones . Esto se debe a que puede renderizar la página de una sola vez. Otras respuestas aquí esperan a que un elemento termine, hasta que se componga el siguiente. Eso hace que la ejecución de Veeeery sea lenta si hay, por ejemplo, varias mathjax-bind (como sugiere otra respuesta). Este punto es la razón por la que estaba buscando una respuesta diferente.
  • Aún puede excluir fácilmente elementos utilizando la opción "ignoreClass" en su configuración mathjax.

Evaluación comparativa: 100 directivas mathjax-bind tardaron 63 segundos , mientras que con este método tardaron 1,5 segundos en renderizar la página. Sé que esta función se ejecutará mucho ya que se utiliza en todos los ciclos de resumen, sin embargo, no ralentiza notablemente la página.