29

Android プラットフォームで科学と数学が十分に注目されていないのは悲しいことです。これは簡単な問題かもしれませんが、私はJavaScriptが苦手なので、この問題を解決する方法を理解するのに苦労しています。

私がやりたいことは単純です。レンダリングの数式を使用するだけです。MathJax や JqMath など、小さくて速いものなら何でも構いません。Webビューでそれを行う必要がある場合、同じWebビュー内で段落とフォーマットされた数式にプレーンテキストを表示するにはどうすればよいですか?

(誰もが明らかに機能する他の方法を思いついたので、それも解決策と見なします)

これまでに行ったこと:

私は MathJax を使用して式を webview に入れることから始めました (成功した jqMath の使用例があるかどうかはわかりません。経験を共有したい人はいますか? ) スタンドアロンのMathJax Appと同じように、すべての機能を再現できます。そのアプリでは、ユーザーが EditText フィールドに文字列を入力すると、ユーザーが確認のためにボタンを押すと、MathJax が Latex で数式をレンダリングします。

ユーザーが確認する必要はありません。ユーザーの操作がないため、これは簡単だと思いましたが、どういうわけか方程式が表示されません。スタンドアロンの MathJax のコードはユーザー入力用であるため、何かが足りないことはわかっています。\sqrt{b^2-4ac} など、文字列から方程式を直接レンダリングするには、コードのどの部分を変更する必要がありますか? 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","");

edittext への入力後にユーザーがボタンを押したときに、元の webview がどのように読み込まれるかを次に示します。

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"はwebviewにも表示されません.

[解決策] ジョーの回答を参照

彼の答えを詳しく説明するために、これは文をプレーンテキストで設定し、フォーマットされた方程式を表示形式で表示する方法の例です (すべて単一の Web ビューで)。

上記の最後の行を次の場所に置き換えます

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

これにより、文字列が設定されます。これは通常のフォントのプレーン テキストフー+バーであり、webviewの中央に式が表示されます。

編集 (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);
}

更新 (MATHJAX 2.5 の時点)

フォルダーの変更があるため、以前のコードは最新バージョンの MathJax では機能しません。さらに、ローカルの MathJax のサイズを最小化するための推奨される方法は、現在Gruntを使用しています。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: [ ['$','$'] ], 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はそれに応じてフォーマットします.

ただし、KitKat デバイスの webview が大文字の「A」をレンダリングできないというバグがあるようです。方法を知っている人なら誰でも、これに対する回避策を提供できます。

4

6 に答える 6

2

「大文字 A」の問題は、Android WebView での MathJax の既知のバグです。フォント ファイルを微調整したフォント ファイルに置き換えることができます。この修正は、TeX フォントで HTML-CSS 出力を使用する場合に機能します。MathJax の他に、美しくはないが高速なKaTeXを試すことができます。

実際には、両方を Android カスタム ビューにまとめましたMathView

于 2015-12-02T10:29:04.053 に答える
1

パーティーに遅れましたが、私はジョーよりも良い解決策を持っていると思います. 元の質問は次のとおりです。

段落内のプレーン テキストと書式設定された数式を同じ Web ビュー内で表示するにはどうすればよいですか?

元の例では、次のことがありました。

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

\\\\[とに気づきました\\\\]か?これらの 4 つのバックスラッシュは、 LaTeXによって 1 つのみとして解釈されます。LaTeX では、and\[は、表示される数学のブロックを生成するの省略形です。段落内に数式を含むテキストの段落が必要な場合は、 を削除して LaTeX コマンドとを使用する必要があります。段落数学と表示された数学を含む例のコードは次のようになります。\] \begin{equation}... \end{equation}\\\\[\(\)

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

WebView は次のようになります ここに画像の説明を入力

  • 必要なバックスラッシュは 4 つではなく 2 つだけです。これは、内部にdoubleEscapeTeX()あり、この関数がバックスラッシュを複製するためです。

  • また、数学環境外のテキストは HTML でレンダリングされます (<span id='math'>タグ内)。

  • LaTeX フォントは html フォントよりも大きいため\\small、各数学環境に を追加すると、ほぼ同じサイズになります。\\smallここでは、違いを示すために、最初の式だけにコマンドを追加しました。

于 2014-04-13T12:55:23.470 に答える