Mostrar una buena fórmula de matemáticas en Android

Es triste ver que la ciencia y las matemáticas nunca reciben suficiente atención en la plataforma Android. Tal vez este es un problema fácil, pero soy un tipo total en javascript por lo que estoy luchando para entender cómo resolver este problema.

Lo que quiero hacer es simple: sólo necesito usar la ecuación matemática render. 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 webview?

(Cualquiera sale con otros métodos que obviamente funciona, voy a considerar que como solución también)

LO QUE HE HECHO HASTA AHORA:

Comencé con el uso de MathJax para poner la fórmula en la webview ( no sé si hay algún caso de uso exitoso jqMath por ahí? ¿Alguien quiere compartir su experiencia? ) Puedo reproducir todas las funcionalidades como la de la aplicación independiente MathJax . En esa aplicación, un usuario teclea en una cadena en el campo EditText y MathJax renderizará la fórmula en Latex una vez que el usuario presione 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 extrañando algo porque los códigos en el MathJax independiente se significan para la entrada del usuario. ¿Qué parte del código debo modificar para renderizar directamente una ecuación de una cadena, digamos, \ sqrt {b ^ 2-4ac}? Aquí está el encabezado inicial para webview:

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 aquí es cómo se carga la vista web original cuando el usuario presiona un botón después de ingresar a edittext:

 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 cadena 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.

[SOLUCIÓN] vea la respuesta de Joe

Para elaborar su respuesta, este es un ejemplo de cómo establecer una oración en texto sin formato 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 un texto normal en la fuente normal y el centro de la pantalla de la fórmula Foo + bar En la vista web.

EDIT (edición de Android 4.4)

Comenzando con Android KitKat, tienes que reemplazar todas las líneas loadUrl(...) con evaluateJavascript(...) . Pero esto sólo está disponible para KitKat (API 19 o superior), por lo que necesita realizar una comprobación de la versión de SDK primero. 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)

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

Suponiendo que ha reducido con éxito el tamaño de MathJax, y asumiendo la salida de HTML-CSS, aquí hay una versión sencilla 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áticas, MathJax simplemente los formateará en consecuencia.

Sin embargo, parece que hay un error que la webview en dispositivos KitKat no puede hacer mayúscula "A". Cualquier persona que conozca una manera es bienvenido para proporcionar una solución para esto.

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() s adicional para mostrar la fórmula. La solución más sencilla 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 acomodar la salida adicional en el WebView, sugeriría agregar elementos HTML a la llamada loadDataWithBaseURL() inicial. Por lo tanto, 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 de forma interactiva después, puede utilizar el mismo mecanismo que utilizamos para la parte de "matemáticas", algo así como:

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

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

En lugar de utilizar javascript y bibliotecas javascript para procesar el cliente LaTeX lado, ¿por qué no hacer lo siguiente?

  1. Escribe una función del lado del servidor que toma una cadena LaTeX y produce un archivo de imagen. Puede hacerlo con la herramienta de línea de comandos estándar LaTeX "out of the box". (Parece que esto es algo que eres capaz de hacer, y que el problema es conseguir que el render se lleve a cabo en el lado del cliente.)

  2. Cree un punto final en su sitio web / servicio que tenga el siguiente aspecto:
    GET /latex?f={image format}&s={latex string}

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

  4. (Opcional) Cree una caché simple en el lado del servidor para pares (f,s) modo que sólo renderice una cadena LaTeX en particular en la primera petición hecha para esa cadena en particular (por cualquier cliente). Como un primer prototipo, sólo podría tener un directorio de servidor en el que tenga archivos denominados {hash(s)}.{f} , donde hash es sólo una función hash como SHA1 .

Esto le alivia de intentar hacer todo el trabajo cliente-lado con javascript. Y, yo diría (aunque algunos pueden estar en desacuerdo), que esto es mucho más limpio. Todo lo que está 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!

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

En realidad los he empacado en una vista personalizada de Android, eche un vistazo a MathView .

A última hora de la fiesta, pero creo que tengo una solución mejor que la de Joe. La pregunta original fue:

¿Cómo puedo mostrar el texto sin formato en el párrafo y una ecuación formateada dentro de la misma webview?

En el ejemplo original que teníamos:

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

¿Te das cuenta del \\\\[ y \\\\] ? Estas cuatro barras inversas son interpretadas por LaTeX como una sola y \[ y \] en LaTeX es una abreviatura de \begin{equation}... \end{equation} que produce un bloque de matemáticas visualizadas. Si queremos un párrafo de texto con algunas ecuaciones dentro del párrafo necesitamos deshacernos del \\\\[ y usar el comando LaTeX \( y \) . El código para un ejemplo con matemáticas de párrafo y matemáticas mostradas 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: Introduzca aquí la descripción de la imagen Notas:

  • Sólo necesitamos dos barras invertidas en lugar de cuatro, esto se debe a que estamos dentro de doubleEscapeTeX() y esta función duplica las barras invertidas.

  • También 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 un \\small en cada entorno matemático hará que tengan aproximadamente el mismo tamaño. Aquí he añadido el comando \\small sólo 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 todos los LaTeX, te puede gustar. Debe funcionar bien en Android.

Es sólo una sugerencia, no tengo idea de los errores o ventajas que podría tener si utiliza MathJax.

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

Trabajo JSFIDDLE: http://jsfiddle.net/sinhayash/gWWB5/1/

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

Puede utilizar fácilmente la manipulación de cadenas en javascript para convertir cadenas al formato jqMath y visualizarlo fácilmente

Usted puede utilizar fácilmente la fórmula matemática en android usando código debajo.

 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", ""); } 
  • ¿Cómo mostrar fórmulas matemáticas en mi aplicación Android?
  • Mover la mano Minuto en el reloj de Android
  • ¿Multiplicar dobles en java?
  • Android: ¿Cómo obtener sólo dos dígitos después del punto en el valor decimal? no quiere trunc el valor
  • 1000 * 60 * 60 * 24 * 30 resultados en un número negativo
  • La mejor práctica para calcular la velocidad media de las coordenadas GPS
  • Parallax XY y cálculo de la rotación
  • Calcular el ángulo del punto tocado y rotarlo en Android
  • Latitud / Longitud y metros
  • ¿Cómo determino qué triángulo tocó el usuario en este rectángulo?
  • Problema básico de conversión imperial
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.