Afficher une bonne formule mathématique dans Android

Il est triste de voir que la science et les mathématiques ne reçoivent jamais suffisamment d'attention sur la plate-forme Android. Peut-être que c'est un problème facile, mais je suis un type total en javascript, alors je me moque de comprendre comment résoudre ce problème.

Ce que je veux faire est simple: je dois simplement utiliser l'équation mathématique de rendu. Cela peut être MathJax ou JqMath ou tout ce qui est petit et rapide. Si je dois le faire dans une vision du Web, comment puis-je afficher le texte brut dans le paragraphe et l'équation formatée dans la même vision du Web?

(N'importe qui sort avec d'autres méthodes qui évidemment fonctionne, je considérerai cela comme une solution aussi)

QU'EST-CE QUE CEU FAIT:

J'ai commencé avec l'utilisation de MathJax pour mettre la formule dans la visualisation web ( je ne sais pas s'il y a un cas d'utilisation de jqMath réussi là-bas? Quelqu'un se soucie de partager leur expérience? ) Je peux reproduire toutes les fonctionnalités comme celle de l'application MathJax autonome. Dans cette application, un utilisateur saisit une chaîne dans le champ EditText et MathJax rend la formule dans Latex une fois que l'utilisateur appuie sur un bouton pour confirmer.

Je n'ai pas besoin de l'utilisateur pour confirmer. Je pensais que cela devrait être plus facile car il n'y a pas d'interaction avec l'utilisateur, mais d'une manière ou d'une autre l'équation ne s'affiche jamais. Je sais que je dois manquer quelque chose parce que les codes dans le MathJax autonome sont destinés à la saisie des utilisateurs. Quelle partie du code dois-je modifier pour rendre directement une équation à partir d'une chaîne, par exemple, \ sqrt {b ^ 2-4ac}? Voici l'en-tête initial pour la visualisation 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",""); 

Et voici comment la vue web d'origine se charge lorsque l'utilisateur appuie sur un bouton après avoir entré dans 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; } 

J'ai tenté de remplacer par une chaîne codée

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

Mais cela ne fonctionne pas, le texte "sample string" n'apparaîtra même pas sur le Webview.

[SOLUTION] voir la réponse de Joe

Pour expliquer sa réponse, il s'agit d'un exemple sur la façon de définir une phrase en texte brut, puis d'afficher une équation formatée sous forme d'affichage (toutes dans une seule vision du Web):

Remplacez la dernière ligne ci-dessus à

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

avec

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

Ensuite appeler

 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]);"); } }); 

Cela définira une chaîne Ce texte est simple dans la police normale et affichez la formule au centre Foo + bar Dans la visualisation web.

EDIT (problème Android 4.4)

À partir de Android KitKat, vous devez remplacer toutes les lignes loadUrl(...) avec loadUrl(...) evaluateJavascript(...) . Mais cela n'est disponible que pour KitKat (API 19 ou plus), vous devez d'abord effectuer un contrôle de version SDK. Par exemple:

 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); } 

MISE À JOUR (EN MATHJAX 2.5)

Parce qu'il y a des modifications de dossiers, le code précédent ne fonctionnera pas sur la dernière version de MathJax. En outre, la façon recommandée de minimiser la taille de MathJax local est maintenant en utilisant Grunt . Le modèle pour réduire la taille de MathJax peut être trouvé ici .

En supposant que vous avez réussi à réduire la taille de MathJax et, en supposant la sortie de HTML-CSS, voici une version simple qui peut charger 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); } } }); } 

Contrairement à la réponse de Joes, il n'est pas nécessaire de séparer les types de texte ou de mathématiques, MathJax vient de les formater en conséquence.

Cependant, il semble qu'il y ait un bug que la vision du Web dans les dispositifs KitKat ne peut pas rendre la lettre majuscule "A". Quiconque connaît un chemin est invité à fournir une solution de contournement pour cela.

Si je comprends correctement votre problème, il semble que le problème est dû au fait que la bibliothèque MathJax n'a pas terminé le chargement (à partir de l'appel loadDataWithBaseURL() ) lorsque vous appelez le loadUrl() s supplémentaire pour afficher la formule. La solution la plus simple est d'attendre le onPageFinished() l' onPageFinished() pour effectuer l'appel.

Par exemple, le code suivant semble fonctionner bien sur le mien:

 /** 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]);"); } }); } 

Mise à jour : pour tenir compte de la sortie supplémentaire dans le WebView, je suggérerais d'ajouter des éléments HTML à l'appel initial loadDataWithBaseURL() . Donc pour l'exemple ci-dessus, au lieu de cette ligne à la fin:

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

Nous pouvons faire quelque chose comme suit:

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

En outre, si vous devez mettre cette partie en mode interactivement par la suite, vous pouvez utiliser le même mécanisme que nous avons utilisé pour la partie "mathématiques", quelque chose comme:

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

Vous pouvez également utiliser d'autres éléments HTML (au lieu de <span> que nous utilisons ci-dessus) si vous souhaitez avoir un style / formatage spécifique.

Au lieu d'utiliser les bibliothèques javascript et javascript pour rendre le côté client LaTeX, pourquoi ne pas faire ce qui suit?

  1. Écrivez une fonction côté serveur qui prend une chaîne LaTeX et produit un fichier image. Vous pouvez le faire avec l'outil de ligne de commande LaTeX standard "hors de la boîte". (Il semble que c'est quelque chose que vous êtes capable de faire, et que le problème consiste à faire en sorte que le rendu se fasse côté client).

  2. Créez un point d'extrémité sur votre site Web / service qui ressemble à ce qui suit:
    GET /latex?f={image format}&s={latex string}

  3. Sur vos pages Web, utilisez une simple étiquette HTML <img/> pour rendre votre LaTeX. Par exemple:
    <img src="/latex?f=jpeg&s=f%40x%41%61x%942"/>
    Rendra l'équation f(x)=x^2 comme JPEG.

  4. (Facultatif) Créez un cache serveur simple pour les paires (f,s) afin que vous ne produisiez qu'une chaîne LaTeX particulière sur la première requête jamais faite pour cette chaîne particulière (par un client). En tant que premier prototype, vous pouvez simplement avoir un répertoire de serveur dans lequel vous avez des fichiers appelés {hash(s)}.{f} , où hash est juste une fonction hash comme SHA1 .

Cela vous empêche d'essayer de faire fonctionner tout le client avec javascript. Et, je dirais (même si certains peuvent être en désaccord), cela est beaucoup plus propre. Tout ce que vous envoyez au client est:

  1. L'étiquette HTML <img/>
  2. Le contenu de l'image réelle lorsque le navigateur résout l'attribut src

Très léger et rapide!

Le problème de "capitale A" est un bogue de MathJax sur Android WebView. Vous pouvez remplacer les fichiers de police par des fichiers de police modifiés . La correction fonctionnera lors de l'utilisation de la sortie HTML-CSS avec les polices TeX. Outre MathJax, vous pouvez essayer KaTeX , ce qui est moins beau mais plus rapide.

En fait, je les ai emballés tous les deux dans une vue personnalisée sur Android, regardez MathView .

À la fin de la fête, mais je pense que j'ai une meilleure solution que celle de Joe. La question initiale posée:

Comment puis-je afficher le texte brut dans le paragraphe et une équation formatée dans la même vision du Web?

Dans l'exemple original, nous avions:

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

Vous remarquez le \\\\[ et \\\\] ? Ces quatre barres obliques sont interprétées par LaTeX comme une seule, et \[ et \] dans LaTeX est une sténographie pour \begin{equation}... \end{equation} qui produit un bloc de mathématiques affichées. Si nous voulons un paragraphe de texte avec quelques équations dans le paragraphe, nous devons nous débarrasser du \\\\[ et utiliser la commande LaTeX \( et \) . Le code pour un exemple avec le paragraphe mathématique et les mathématiques affichées serait:

 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}. \\]" )+"';"); 

L'affichage Web devient: Entrez la description de l'image ici Remarques:

  • Nous n'avons besoin que de deux barres obliques au lieu de quatre, c'est parce que nous sommes dans doubleEscapeTeX() et cette fonction double les barres obliques.

  • De même, le texte en dehors des environnements mathématiques est rendu avec HTML (dans la <span id='math'> ).

  • La police LaTeX est plus grande que la police html, donc l'ajout d'un \\small dans chaque environnement mathématique les rendra à peu près la même taille. Ici, j'ai ajouté la \\small commande uniquement à la première équation pour montrer la différence.

JqMath est une bibliothèque JavaScript comme MathJax, mais beaucoup plus petite, plus simple et plus rapide. Si vous n'avez pas besoin de tout LaTeX, vous pourriez l'aimer. Il devrait fonctionner correctement sur Android.

C'est juste une suggestion, je n'ai aucune idée des erreurs ou des avantages que vous pourriez avoir si vous utilisez MathJax.

MathJax est beaucoup plus grand et plus compliqué que jqMath, et environ 5 fois plus lent .

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

Pour \sqrt{b^2-4ac} vous pouvez avoir ce code: √(b^2-4ac)

Vous pouvez utiliser facilement la gestion des chaînes dans javascript pour convertir les chaînes au format jqMath et l'afficher facilement

Vous pouvez facilement utiliser la formule mathématique dans Android en utilisant le code ci-dessous.

 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", ""); }