title: Display Good-looking Math Formula in Android
body: <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 don't know 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="nofollow 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(&quot;http://bar&quot;, &quot;&lt;script type='text/x-mathjax-config'&gt;&quot;
                          +&quot;MathJax.Hub.Config({ showMathMenu: false, &quot;
                          +&quot;jax: ['input/TeX','output/HTML-CSS'], &quot;
                          +&quot;extensions: ['tex2jax.js'], &quot; 
                          +&quot;TeX: { extensions: ['AMSmath.js','AMSsymbols.js',&quot;
                          +&quot;'noErrors.js','noUndefined.js'] } &quot;
                          +&quot;});&lt;/script&gt;&quot;
                          +&quot;&lt;script type='text/javascript' &quot;
                          +&quot;src='file:///android_asset/MathJax/MathJax.js'&quot;
                          +&quot;&gt;&lt;/script&gt;&lt;span id='math'&gt;&lt;/span&gt;&quot;,&quot;text/html&quot;,&quot;utf-8&quot;,&quot;&quot;);
  </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(&quot;javascript:document.getElementById('math').innerHTML='\\\\[&quot;
                    +doubleEscapeTeX(e.getText().toString())
                    +&quot;\\\\]';&quot;);
  w.loadUrl(&quot;javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);&quot;);
  
  private static String doubleEscapeTeX(String s) {
      String t=&quot;&quot;;
      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 += &quot;\\&quot;;
      }
      return t;
  }
  </code></pre>
  <p>I attempted to replace with a hard-coded string</p>
  <pre><code>w.loadUrl(&quot;javascript:document.getElementById('math').innerHTML='\\\\[&quot;
                    +doubleEscapeTeX(&quot;sample string&quot;)
                    +&quot;\\\\]';&quot;);
  </code></pre>
  <p>but it doesn't work, the text <code>&quot;sample string&quot;</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>+&quot;&gt;&lt;/script&gt;&lt;span id='math'&gt;&lt;/span&gt;&quot;,&quot;text/html&quot;,&quot;utf-8&quot;,&quot;&quot;);
  </code></pre>
  <p>with</p>
  <pre><code>+&quot;&gt;&lt;/script&gt;&lt;span id='text'&gt;This is plain text.&lt;/span&gt; &lt;span id='math'&gt;&lt;/span&gt;&quot;, &quot;text/html&quot;, &quot;utf-8&quot;, &quot;&quot;);
  </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(&quot;http://bar&quot;))
              return;
          w.loadUrl(&quot;javascript:document.getElementById('math').innerHTML='\\\\[&quot;
                      +doubleEscapeTeX(&quot;\\sqrt{b^2-4ac}&quot;) + &quot;\\\\]';&quot;);
          w.loadUrl(&quot;javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);&quot;);
      }
  });
  </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(&quot;javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);&quot;);
  } else {
      w.evaluateJavascript(&quot;javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);&quot;,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="nofollow noreferrer">Grunt</a>. The template to reduce size of MathJax can be found <a href="https://github.com/mathjax/MathJax-grunt-cleaner" rel="nofollow 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 = &quot;&lt;/style&gt;&quot;
                   + &quot;&lt;script type='text/x-mathjax-config'&gt;&quot;
                   + &quot;  MathJax.Hub.Config({&quot; + &quot;    showMathMenu: false,&quot;
                   + &quot;             jax: ['input/TeX','output/HTML-CSS', 'output/CommonHTML'],&quot;
                   + &quot;      extensions: ['tex2jax.js','MathMenu.js','MathZoom.js', 'CHTML-preview.js'],&quot;
                   + &quot;         tex2jax: { inlineMath: [ ['$','$'] ], processEscapes: true },&quot;
                   + &quot;             TeX: {&quot; + &quot;               extensions:['AMSmath.js','AMSsymbols.js',&quot;
                   + &quot;                           'noUndefined.js']&quot; + &quot;             }&quot;
                   + &quot;  });&quot;
                   + &quot;&lt;/script&gt;&quot;
                   + &quot;&lt;script type='text/javascript' src='file:///android_asset/MathJax/MathJax.js'&gt;&quot;
                   + &quot;&lt;/script&gt;&quot;
                   + &quot;&lt;p style=\&quot;line-height:1.5; padding: 16 16\&quot; align=\&quot;justify\&quot;&gt;&quot;
                   + &quot;&lt;span &gt;&quot;;
  
      // Demo display equation
      url += &quot;This is a display equation: $$P=\frac{F}{A}$$&quot;;
  
      url += &quot;This is also an identical display equation with different format:\\[P=\\frac{F}{A}\\]&quot;;
  
      // equations aligned at equal sign
      url += &quot;You can also put aligned equations just like Latex:&quot;;
      String align = &quot;\\begin{aligned}&quot;
                  + &quot;F\\; &amp;= P \\times A \\\\ &quot;
                  + &quot;&amp;= 4000 \\times 0.2\\\\&quot;
                  + &quot;&amp;= 800\\; \\text{N}\\end{aligned}&quot;; 
      url += align;
  
      url += &quot;This is an inline equation \\sqrt{b^2-4ac}.&quot;;
  
      // Finally, must enclose the brackets
      url += &quot;&lt;/span&gt;&lt;/p&gt;&quot;;
  
      mWebView.loadDataWithBaseURL(&quot;http://bar&quot;, url, &quot;text/html&quot;, &quot;utf-8&quot;, &quot;&quot;);
      mWebView.setWebViewClient(new WebViewClient() {
          @Override
          public void onPageFinished(WebView view, String url) {
              super.onPageFinished(view, url);
              if (!url.startsWith(&quot;http://bar&quot;)) 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 &quot;A&quot;. Anyone who knows a way is welcome to provide a workaround for this.</p>