javascript android math mathjax jqmath

javascript - Muestra la Fórmula matemática atractiva en Android



math mathjax (6)

El problema del "capital A" es un error de MathJax en Android WebView. Puede reemplazar los archivos de fuentes con archivos de fuentes ajustados . La solución funcionará cuando se usa la salida HTML-CSS con fuentes TeX. Además de MathJax, puedes probar KaTeX , que es menos hermoso pero más rápido.

De hecho, los he empaquetado a ambos en una vista personalizada de Android, eche un vistazo a MathView .

Es triste ver que a la ciencia y las matemáticas nunca se les presta suficiente atención en la plataforma de Android. Tal vez este es un problema fácil, pero soy un tipo total en JavaScript, así que estoy luchando para entender cómo resolver este problema.

Lo que quiero hacer es simple: solo necesito usar la ecuación matemática de renderizado. Puede ser MathJax o JqMath o cualquier cosa que sea pequeña y rápida. Si tengo que hacerlo en una vista web, ¿cómo puedo mostrar el texto sin formato en el párrafo y la ecuación formateada dentro de la misma vista web?

(Alguien sale con otros métodos que obviamente funcionan, lo consideraré también como solución)

LO QUE HE HECHO HASTA AHORA:

Comencé a usar MathJax para poner la fórmula en la vista web ( no sé si existe algún caso de uso de jqMath exitoso) ¿Alguien quiere compartir su experiencia? ) Puedo reproducir todas las funcionalidades de la misma manera que la aplicación MathJax independiente. En esa aplicación, un usuario introduce una cadena en el campo EditText y MathJax renderiza la fórmula en Latex una vez que el usuario presiona un botón para confirmar.

No necesito que el usuario confirme. Pensé que esto debería ser más fácil porque no hay interacción del usuario, pero de alguna manera la ecuación nunca se muestra. Sé que debo estar perdiendo algo porque los códigos en el MathJax independiente están destinados a la entrada del usuario. ¿Qué parte del código debo modificar para representar directamente una ecuación a partir de una cadena, por ejemplo, / sqrt {b ^ 2-4ac}? Aquí está el encabezado inicial para la vista web:

WebView w = (WebView) findViewById(R.id.webview); w.getSettings().setJavaScriptEnabled(true); w.getSettings().setBuiltInZoomControls(true); w.loadDataWithBaseURL("http://bar", "<script type=''text/x-mathjax-config''>" +"MathJax.Hub.Config({ showMathMenu: false, " +"jax: [''input/TeX'',''output/HTML-CSS''], " +"extensions: [''tex2jax.js''], " +"TeX: { extensions: [''AMSmath.js'',''AMSsymbols.js''," +"''noErrors.js'',''noUndefined.js''] } " +"});</script>" +"<script type=''text/javascript'' " +"src=''file:///android_asset/MathJax/MathJax.js''" +"></script><span id=''math''></span>","text/html","utf-8","");

Y así es como se carga la vista web original cuando el usuario presiona un botón después de la entrada para editar el texto:

WebView w = (WebView) findViewById(R.id.webview); EditText e = (EditText) findViewById(R.id.edit); w.loadUrl("javascript:document.getElementById(''math'').innerHTML=''////[" +doubleEscapeTeX(e.getText().toString()) +"////]'';"); w.loadUrl("javascript:MathJax.Hub.Queue([''Typeset'',MathJax.Hub]);"); private static String doubleEscapeTeX(String s) { String t=""; for (int i=0; i < s.length(); i++) { if (s.charAt(i) == ''/''') t += ''//'; if (s.charAt(i) != ''/n'') t += s.charAt(i); if (s.charAt(i) == ''//') t += "//"; } return t; }

Intenté reemplazar con una cuerda codificada

w.loadUrl("javascript:document.getElementById(''math'').innerHTML=''////[" +doubleEscapeTeX("sample string") +"////]'';");

pero no funciona, el texto "sample string" ni siquiera aparecerá en la vista web.

[SOLUTION] ver la respuesta de Joe

Para explicar su respuesta, este es un ejemplo sobre cómo establecer una oración en texto plano y luego mostrar una ecuación formateada en forma de visualización (todo en una sola vista web):

Reemplace la última línea arriba en

+"></script><span id=''math''></span>","text/html","utf-8","");

con

+"></script><span id=''text''>This is plain text.</span> <span id=''math''></span>", "text/html", "utf-8", "");

Luego llame

w.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); if (!url.startsWith("http://bar")) return; w.loadUrl("javascript:document.getElementById(''math'').innerHTML=''////[" +doubleEscapeTeX("//sqrt{b^2-4ac}") + "////]'';"); w.loadUrl("javascript:MathJax.Hub.Queue([''Typeset'',MathJax.Hub]);"); } });

Esto establecerá una cadena Este es texto plano en fuente normal y centro-muestra la fórmula en la vista web.

EDITAR (problema de Android 4.4)

Comenzando con Android KitKat, debes reemplazar todas las líneas loadUrl(...) con evaluateJavascript(...) . Pero esto solo está disponible para KitKat (API 19 o superior), por lo que primero debe realizar una comprobación de versión del SDK. Por ejemplo:

if (android.os.Build.VERSION.SDK_INT < 19) { w.loadUrl("javascript:MathJax.Hub.Queue([''Typeset'',MathJax.Hub]);"); } else { w.evaluateJavascript("javascript:MathJax.Hub.Queue([''Typeset'',MathJax.Hub]);",null); }

ACTUALIZACIÓN (A PARTIR DE MATHJAX 2.5)

Debido a que hay cambios en las carpetas, el código anterior no funcionará en la última versión de MathJax. Además, la forma recomendada de minimizar el tamaño de MathJax local ahora está usando Grunt . La plantilla para reducir el tamaño de MathJax se puede encontrar here .

Suponiendo que haya reducido con éxito el tamaño de MathJax, y asumiendo el resultado de HTML-CSS, aquí hay una versión simple que puede cargar MathJax:

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final WebView w = (WebView) findViewById(R.id.webview); w.getSettings().setJavaScriptEnabled(true); w.getSettings().setBuiltInZoomControls(true); String Url = "</style>" + "<script type=''text/x-mathjax-config''>" + " MathJax.Hub.Config({" + " showMathMenu: false," + " jax: [''input/TeX'',''output/HTML-CSS'', ''output/CommonHTML'']," + " extensions: [''tex2jax.js'',''MathMenu.js'',''MathZoom.js'', ''CHTML-preview.js'']," + " tex2jax: { inlineMath: [ [''$'',''$''] ], processEscapes: true }," + " TeX: {" + " extensions:[''AMSmath.js'',''AMSsymbols.js''," + " ''noUndefined.js'']" + " }" + " });" + "</script>" + "<script type=''text/javascript'' src=''file:///android_asset/MathJax/MathJax.js''>" + "</script>" + "<p style=/"line-height:1.5; padding: 16 16/" align=/"justify/">" + "<span >"; // Demo display equation url += "This is a display equation: $$P=/frac{F}{A}$$"; url += "This is also an identical display equation with different format://[P=//frac{F}{A}//]"; // equations aligned at equal sign url += "You can also put aligned equations just like Latex:"; String align = "//begin{aligned}" + "F//; &= P //times A //// " + "&= 4000 //times 0.2////" + "&= 800//; //text{N}//end{aligned}"; url += align; url += "This is an inline equation //sqrt{b^2-4ac}."; // Finally, must enclose the brackets url += "</span></p>"; mWebView.loadDataWithBaseURL("http://bar", url, "text/html", "utf-8", ""); mWebView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); if (!url.startsWith("http://bar")) return; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { view.loadUrl(JAVASCRIPT); } else { view.evaluateJavascript(JAVASCRIPT, null); } } }); }

A diferencia de la respuesta de Joes, no hay necesidad de separar los tipos de texto o matemáticos, MathJax simplemente los formateará en consecuencia.

Sin embargo, parece que hay un error que la vista web en los dispositivos KitKat no puede mostrar la letra mayúscula "A". Cualquiera que conozca una forma es bienvenido para proporcionar una solución alternativa para esto.


En lugar de utilizar javascript y librerías javascript para renderizar LaTeX del lado del cliente, ¿por qué no hacer lo siguiente?

  1. Escriba una función del lado del servidor que tome algo de la cadena LaTeX y produzca un archivo de imagen. Puede hacer esto con la herramienta de línea de comandos estándar de LaTeX "lista para usar". (Parece que esto es algo que usted es capaz de hacer, y que el problema está en hacer que el renderizado tenga lugar en el lado del cliente).

  2. Cree un punto final en su sitio / servicio web que se parezca a lo siguiente:
    GET /latex?f={image format}&s={latex string}

  3. En sus páginas web, use una simple etiqueta HTML <img/> para representar su LaTeX. Por ejemplo:
    <img src="/latex?f=jpeg&s=f%40x%41%61x%942"/>
    renderizará la ecuación f(x)=x^2 como un JPEG.

  4. (opcional) Cree un caché simple del lado del servidor para (f,s) pares (f,s) modo que solo represente una cadena LaTeX particular en la primera solicitud que alguna vez se haya realizado para esa cadena en particular (por cualquier cliente). Como primer prototipo, podría tener un directorio de servidor en el que tenga archivos denominados {hash(s)}.{f} , donde hash es solo una función hash como SHA1 .

Esto lo alivia de intentar hacer que todo funcione en el lado del cliente con javascript. Y, yo diría (aunque algunos pueden estar en desacuerdo), que esto es mucho más limpio. Todo lo que le estás enviando al cliente es:

  1. la etiqueta HTML <img/>
  2. el contenido real de la imagen cuando el navegador resuelve el atributo src

Muy ligero y rápido!


Puede usar fácilmente la fórmula matemática en Android usando el código siguiente.

public void setView(String data,WebView w){ WebSettings webSettings = w.getSettings(); webSettings.setJavaScriptEnabled(true); String path="file:///android_asset/v/"; String js="<html><head>" + "<link rel=''stylesheet'' href=''file:///android_asset/v/jqmath.css''>" + "<script src = ''file:///android_asset/v/jquery-3.0.0.min.js''></script>" + "<script src = ''file:///android_asset/v/jqmath-etc-0.4.3.min.js''></script>" + "<script src = ''http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML''></script>" + "</head><body>" + "<script>var s =''"+data+"'';M.parseMath(s);document.write(s);</script> </body>"; w.loadDataWithBaseURL("", js, "text/html", "UTF-8", ""); }


Si entiendo su problema correctamente, parece que el problema se debe a que la biblioteca MathJax no ha completado la carga (desde la llamada loadDataWithBaseURL() ) cuando llama al loadUrl() adicional para mostrar la fórmula. La solución más simple es esperar la devolución de llamada onPageFinished() para realizar la llamada.

Por ejemplo, el siguiente código parece funcionar bien en el mío:

/** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final WebView w = (WebView) findViewById(R.id.webview); w.getSettings().setJavaScriptEnabled(true); w.getSettings().setBuiltInZoomControls(true); w.loadDataWithBaseURL("http://bar", "<script type=''text/x-mathjax-config''>" + "MathJax.Hub.Config({ " + "showMathMenu: false, " + "jax: [''input/TeX'',''output/HTML-CSS''], " + "extensions: [''tex2jax.js''], " + "TeX: { extensions: [''AMSmath.js'',''AMSsymbols.js''," + "''noErrors.js'',''noUndefined.js''] } " + "});</script>" + "<script type=''text/javascript'' " + "src=''file:///android_asset/MathJax/MathJax.js''" + "></script><span id=''math''></span>", "text/html", "utf-8", ""); w.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); if (!url.startsWith("http://bar")) return; w.loadUrl("javascript:document.getElementById(''math'').innerHTML=''////[" + doubleEscapeTeX("sample string") + "////]'';"); w.loadUrl("javascript:MathJax.Hub.Queue([''Typeset'',MathJax.Hub]);"); } }); }

Actualización : para dar cabida a resultados adicionales en WebView, sugeriría agregar elementos HTML a la llamada loadDataWithBaseURL() inicial. Entonces, para el ejemplo anterior, en lugar de esta línea al final:

+ "></script><span id=''math''></span>", "text/html", "utf-8", "");

Podemos hacer algo como lo siguiente:

+ "></script><span id=''text''>Formula:</span>" + "<span id=''math''></span>", "text/html", "utf-8", "");

Además, si necesita actualizar esa parte interactivamente después, puede usar el mismo mecanismo que usamos para la parte "matemática", algo como:

w.loadUrl("javascript:document.getElementById(''text'').innerHTML=''" + newText + "'';");

También puede usar otros elementos HTML (en lugar del <span> que usamos arriba) si desea tener un estilo / formato específico.


Tarde en la fiesta, pero creo que tengo una mejor solución que la de Joe. La pregunta original fue:

¿Cómo puedo mostrar el texto plano en el párrafo y una ecuación formateada dentro de la misma vista web?

En el ejemplo original, tuvimos:

w.loadUrl("javascript:document.getElementById(''math'').innerHTML=''////[" +doubleEscapeTeX("sample string") +"////]'';");

¿Notaste el ////[ y ////] ? Esas cuatro barras inversas son interpretadas por LaTeX como una sola, y /[ y /] en LaTeX es una forma abreviada de /begin{equation}... /end{equation} que produce un bloque de las matemáticas mostradas. Si queremos un párrafo de texto con algunas ecuaciones dentro del párrafo, tenemos que deshacernos de ////[ y usar el comando LaTeX /( y /) . El código para un ejemplo con matemáticas de párrafo y matemáticas representadas sería:

w.loadUrl("javascript:document.getElementById(''math'').innerHTML=''" +doubleEscapeTeX( "This is a second degree equation //( //small ax^2+bx+c=0//) and its " +"roots are //[x=//frac{-b//pm //sqrt{b^2-4ac}}{2a}. //]" )+"'';");

El WebView se convierte en: Notas:

  • Solo necesitamos dos barras diagonales inversas en lugar de cuatro, esto es porque estamos dentro de doubleEscapeTeX() y esta función duplica las barras diagonales inversas.

  • Además, el texto fuera de los entornos matemáticos se representa con HTML (dentro de la etiqueta <span id=''math''> ).

  • La fuente LaTeX es más grande que la fuente html, por lo que agregar //small en cada entorno matemático hará que tengan aproximadamente el mismo tamaño. Aquí agregué el comando //small solo a la primera ecuación para mostrar la diferencia.


jqMath es una biblioteca de JavaScript como MathJax, pero mucho más pequeña, más simple y más rápida. Si no necesitas todo LaTeX, te puede gustar. Debería funcionar bien en Android.

Es solo una sugerencia, no tengo idea de qué errores o ventajas puede tener si usa MathJax.

MathJax es mucho más grande y más complicado que jqMath, y aproximadamente 5 veces más lento .

JSFIDDLE de trabajo: http://jsfiddle.net/sinhayash/gWWB5/1/

Para /sqrt{b^2-4ac} puede tener este código: √(b^2-4ac)

Puede usar fácilmente el manejo de cadenas en JavaScript para convertir cadenas al formato jqMath y mostrarlas fácilmente