Показать красивую математическую формулу в Android
Грустно видеть, что науке и математике никогда не уделяется достаточно внимания на платформе Android. Может быть, это простая проблема, но я всегочувак в JavaScript, поэтому я изо всех сил пытаюсь понять, как решить эту проблему.
Что я хочу сделать, это просто:Мне просто нужно использовать математическое уравнение рендера. Это может быть MathJax или JqMath или что-то маленькое и быстрое. Если мне нужно сделать это в веб-просмотре, как я могу показать простой текст в абзаце и отформатированное уравнение в одном веб-просмотре?
(кто-нибудь выходит с другими методами, которые, очевидно, работают, я также буду рассматривать это как решение)
Что я сделал так далеко:
Я начал с использования MathJax, чтобы поместить формулу в веб-просмотр (Я не знаю, есть ли успешный случай использования jqMath там? Кто-нибудь хочет поделиться своим опытом?) Я могу воспроизвести все функции так же, как у автономногоПриложение MathJax, В этом приложении пользователь вводит строку в поле EditText, и MathJax отображает формулу в латексе, как только пользователь нажимает кнопку для подтверждения.
Мне не нужен пользователь для подтверждения. Я думал, что это должно быть проще, потому что нет взаимодействия с пользователем, но каким-то образом уравнение никогда не отображается. Я знаю, что я должен что-то упустить, потому что коды в автономном MathJax предназначены для ввода пользователем. Какую часть кода я должен изменить, чтобы напрямую отобразить уравнение из строки, скажем, \ sqrt {b ^ 2-4ac}? Вот начальный заголовок для веб-просмотра:
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","");
А вот как загружается исходное веб-представление, когда пользователь нажимает кнопку после ввода для редактирования текста:
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;
}
Я попытался заменить жестко закодированной строкой
w.loadUrl("javascript:document.getElementById('math').innerHTML='\\\\["
+doubleEscapeTeX("sample string")
+"\\\\]';");
но это не работает, текст"sample string"
даже не появится в веб-представлении.
[РЕШЕНИЕ] см. Ответ Джо
Чтобы уточнить его ответ, вот пример того, как задать предложение в виде простого текста, а затем отобразить отформатированное уравнение в форме отображения (все в одном веб-просмотре):
Заменить последнюю строку выше на
+"></script><span id='math'></span>","text/html","utf-8","");
с участием
+"></script><span id='text'>This is plain text.</span> <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("\\sqrt{b^2-4ac}") + "\\\\]';");
w.loadUrl("javascript:MathJax.Hub.Queue(['Typeset',MathJax.Hub]);");
}
});
Это установит строкуЭто простой текст обычным шрифтом и центральным дисплеем по формуле в веб-обозрение.
РЕДАКТИРОВАТЬ (выпуск Android 4.4)
Начиная с Android KitKat, вам необходимо заменить все строкиloadUrl(...)
с участиемevaluateJavascript(...)
, Но это доступно только для KitKat (API 19 или выше), поэтому сначала нужно проверить версию SDK. Например:
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);
}
ОБНОВЛЕНИЕ (КАК МАТЯКС 2.5)
Из-за изменений в папках предыдущий код не будет работать в последней версии MathJax. Кроме того, рекомендуемый способ минимизировать размер локального MathJax теперь используетхрюкать, Шаблон для уменьшения размера MathJax можно найтиВот.
Предполагая, что вы успешно уменьшили размер MathJax, и предполагая вывод HTML-CSS, вот простая версия, которая может загрузить 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: [ ['В отличие от ответа Джо, нет необходимости отделять текстовые или математические типы, MathJax просто отформатирует их соответственно.
Однако, похоже, что существует ошибка, из-за которой webview в устройствах KitKat не может отображать заглавную букву «A». Любой, кто знает способ, может предложить обходной путь для этого.
,'В отличие от ответа Джо, нет необходимости отделять текстовые или математические типы, MathJax просто отформатирует их соответственно.
Однако, похоже, что существует ошибка, из-за которой webview в устройствах KitKat не может отображать заглавную букву «A». Любой, кто знает способ, может предложить обходной путь для этого.
] ], 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);
}
}
});
}
В отличие от ответа Джо, нет необходимости отделять текстовые или математические типы, MathJax просто отформатирует их соответственно.
Однако, похоже, что существует ошибка, из-за которой webview в устройствах KitKat не может отображать заглавную букву «A». Любой, кто знает способ, может предложить обходной путь для этого.