Note that there are some explanatory texts on larger screens.

plurals
  1. PODisplay Good-looking Math Formula in Android
    primarykey
    data
    text
    <p>It is sad to see that science and math is never given enough attention in Android platform. Maybe this is an easy problem, but I'm a total <em>dude</em> in javascript so I'm struggling to understand how to solve this problem.</p> <p>What I want to do is simple: <strong>I just need to use render mathematic equation. It can be MathJax or JqMath or anything that is small and fast. If I have to do it in a webview, how can I show plain text in paragraph and formatted equation within the same webview?</strong></p> <p>(anyone comes out with other methods which obviously works, I'll consider that as solution also)</p> <p>WHAT I'VE DONE SO FAR:</p> <p>I started with using MathJax to put formula into webview (<em>I dunno if there is any successful jqMath use case out there? Anyone care to share their experience?</em>) I can reproduce all the functionalities just like that of the standalone <a href="http://cs.jsu.edu/wordpress/?p=498" rel="noreferrer">MathJax App</a>. In that app, a user keys in a string into EditText field and MathJax will render the formula in Latex once user presses a button to confirm.</p> <p>I don't need user to confirm. I thought this should be easier because there is no user-interaction, but somehow the equation never gets displayed. I know I must be missing something because the codes in the standalone MathJax is meant for user input. Which part of the code should I modify to directly render an equation from a string, say, \sqrt{b^2-4ac} ? Here is the initial header for webview:</p> <pre><code>WebView w = (WebView) findViewById(R.id.webview); w.getSettings().setJavaScriptEnabled(true); w.getSettings().setBuiltInZoomControls(true); w.loadDataWithBaseURL("http://bar", "&lt;script type='text/x-mathjax-config'&gt;" +"MathJax.Hub.Config({ showMathMenu: false, " +"jax: ['input/TeX','output/HTML-CSS'], " +"extensions: ['tex2jax.js'], " +"TeX: { extensions: ['AMSmath.js','AMSsymbols.js'," +"'noErrors.js','noUndefined.js'] } " +"});&lt;/script&gt;" +"&lt;script type='text/javascript' " +"src='file:///android_asset/MathJax/MathJax.js'" +"&gt;&lt;/script&gt;&lt;span id='math'&gt;&lt;/span&gt;","text/html","utf-8",""); </code></pre> <p>And here is how the original webview loads when user presses a button after input to edittext:</p> <pre><code>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 &lt; s.length(); i++) { if (s.charAt(i) == '\'') t += '\\'; if (s.charAt(i) != '\n') t += s.charAt(i); if (s.charAt(i) == '\\') t += "\\"; } return t; } </code></pre> <p>I attempted to replace with a hard-coded string </p> <pre><code>w.loadUrl("javascript:document.getElementById('math').innerHTML='\\\\[" +doubleEscapeTeX("sample string") +"\\\\]';"); </code></pre> <p>but it doesn't work, the text <code>"sample string"</code> won't even show up in the webview.</p> <p><strong>[SOLUTION] see Joe's Answer</strong> </p> <p>To elaborate on his answer, this is an example on how to set a sentence in plain text and then display a formatted equation in display form (all in a single webview):</p> <p>Replace the last line above at</p> <pre><code>+"&gt;&lt;/script&gt;&lt;span id='math'&gt;&lt;/span&gt;","text/html","utf-8",""); </code></pre> <p>with</p> <pre><code>+"&gt;&lt;/script&gt;&lt;span id='text'&gt;This is plain text.&lt;/span&gt; &lt;span id='math'&gt;&lt;/span&gt;", "text/html", "utf-8", ""); </code></pre> <p>Then call</p> <pre><code>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]);"); } }); </code></pre> <p>This will set a string <em>This is plain text</em> in normal font and center-display the formula <img src="https://chart.googleapis.com/chart?cht=tx&amp;chl=%5Csqrt%7Bb%5E2-4ac%7D" alt="foo+bar"> in webview.</p> <p><strong>EDIT (Android 4.4 issue)</strong></p> <p>Starting with Android KitKat, you have to replace all the lines <code>loadUrl(...)</code> with <code>evaluateJavascript(...)</code>. But this is only available for KitKat (API 19 or above), so you need to do an SDK version check first. For example:</p> <pre><code>if (android.os.Build.VERSION.SDK_INT &lt; 19) { w.loadUrl("javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);"); } else { w.evaluateJavascript("javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);",null); } </code></pre> <p><strong>UPDATE (AS OF MATHJAX 2.5)</strong></p> <p>Because there are folders changes, previous code won't work on latest version of MathJax. Besides, the recommended way to minimalize the size of local MathJax is now using <a href="http://gruntjs.com/getting-started" rel="noreferrer">Grunt</a>. The template to reduce size of MathJax can be found <a href="https://github.com/mathjax/MathJax-grunt-cleaner" rel="noreferrer">here</a>.</p> <p>Assuming you have successfully reduced the size of MathJax, and assuming output of HTML-CSS, here is a simple version that can load MathJax:</p> <pre><code>@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 = "&lt;/style&gt;" + "&lt;script type='text/x-mathjax-config'&gt;" + " 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']" + " }" + " });" + "&lt;/script&gt;" + "&lt;script type='text/javascript' src='file:///android_asset/MathJax/MathJax.js'&gt;" + "&lt;/script&gt;" + "&lt;p style=\"line-height:1.5; padding: 16 16\" align=\"justify\"&gt;" + "&lt;span &gt;"; // 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\\; &amp;= P \\times A \\\\ " + "&amp;= 4000 \\times 0.2\\\\" + "&amp;= 800\\; \\text{N}\\end{aligned}"; url += align; url += "This is an inline equation \\sqrt{b^2-4ac}."; // Finally, must enclose the brackets url += "&lt;/span&gt;&lt;/p&gt;"; 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 &lt; Build.VERSION_CODES.KITKAT) { view.loadUrl(JAVASCRIPT); } else { view.evaluateJavascript(JAVASCRIPT, null); } } }); } </code></pre> <p>Unlike Joes's answer, there is no need to separate text or math types, MathJax will just format them accordingly.</p> <p>However, it appears that there is a bug that webview in KitKat devices cannot render capital letter "A". Anyone who knows a way is welcome to provide a workaround for this.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload