PHPでTeXを表示する

(1/1)
PHP で mimeTeX を使い、複雑な数式などを表現できる TeX を画面上に表示するプログラムを作る。

(2021 年 9 月 22 日)PHP8 対応,リファラ・チェック改良,等

サンプル・プログラムの実行例

PHPでTeXを表示する

サンプル・プログラム

圧縮ファイルの内容
mimetex.phpサンプル・プログラム本体。
mimetex.zipmimeTeXのソースコード、Windows実行プログラムなど。

TeX と mimeTeX

TeX は、Mac や Windows 上で動作する WYSIWYG なワープロが普及する以前、複雑な数式やグラフを組版するための手段として考案されたソフトウェアである。
これにマクロパッケージを組み込み、さらに組版処理を手軽にしたものが LaTeX である。
たとえば、二次方程式の解の公式  mimetex  は、LaTeX では以下のように記述する。
\frac{-b\pm\sqrt{b^2-4ac}}{2a}
mimeTeX は、LaTeX のサブセットを画像表示するためのソフトウェアである。
mimeTeX は単独の小さな実行ファイルであり、Web との相性もよい。

mimeTeX のインストール

mimeTeX は、圧縮ファイルに同行しているソースを gcc でコンパイルする。Windows版は実行型プログラムが同梱してある。

SSH が利用できない環境であれば、PHP を介して gcc を起動すればいいだろう。
ダウンロードしたソースをアップロードし、同じディレクトリに以下のような PHP スクリプトを配置し、CGI モードで実行すればよい。
#!/usr/local/bin/php
system("gcc -DAA mimetex.c gifsave.c -lm -o mimetex.cgi");
print "*** Compile finished ***\n"
コンパイルできた mimetex.cgi(Windows では mimetex.exe)は、実行可能なディレクトリに設置する。
ただし、Windows の場合は、ディレクトリ名にスペースが含まれていると関数  system  で実行できないことがあるので、"Program Files" 以下や、"Apache Group" 以下には配置しない方がいいだろう。

サンプル・プログラムの流れ

PHPでTeXを表示する
プログラムは 1 本の PHP スクリプトである。
HTML FORM で入力した TeX 文を読み取り、ラジオボタンによって、後述する 2 つの処理へ分岐する。

解説:初期化処理

0011: // 初期化処理 ================================================================
0012: define('INTERNAL_ENCODING', 'UTF-8');
0013: mb_internal_encoding(INTERNAL_ENCODING);
0014: mb_regex_encoding(INTERNAL_ENCODING);
0015: define('MYSELF', basename($_SERVER['SCRIPT_NAME']));
0016: define('REFERENCE', 'https://www.pahoo.org/e-soul/webtech/phpgd/phpgd-10-01.shtm');
0017: 
0018: //TeXのHTML
0019: define('TeX', 'T<span style="text-transform: uppercase; margin-left: -0.1667em; vertical-align: -0.5ex; line-height: 0; margin-right: -0.125em">e</span>X');

mimeTeX のインストール情報を定数 EXECMimeTeX に代入する。

処理選択は配列変数 $SelectFuncs に記述している。この要素を書き換えることで、処理の追加/削除ができる。

解説:画像表示処理

0170: /**
0171:  * mimeTeX実行処理
0172:  * @param   string $tex TeX文
0173:  * @return  string 実行結果
0174: */
0175: function exec_mimetex($tex) {
0176:     //コマンドライン
0177:     $cmd = EXECMimeTeX . " \"{$tex}\" -e";
0178: 
0179:     //実行結果取得(バイナリ)
0180:     $data = '';
0181:     $fp = popen($cmd, 'rb');
0182:     while (! feof($fp)) {
0183:         $data .= fread($fp, 1024);
0184:     }
0185:     pclose($fp);
0186: 
0187:     return $data;
0188: }

ユーザー関数 exec_mimetex によって mimeTeX の実行と結果取得を行う。プロセス実行は  popen  関数によって行い、結果をバイナリで取り出す。

解説:画像表示処理

0260: /**
0261:  * 画面表示処理(imgタグ生成)
0262:  * @param   string $tex TeX文
0263:  * @return  string 表示HTML
0264: */
0265: function display($tex) {
0266:     global $HtmlHeader$HtmlFooter;
0267: 
0268:     //mimeTeX実行
0269:     $data = exec_mimetex($tex);
0270:     //BASE64化
0271:     $data = 'data:image/gif;base64,' . base64_encode($data);
0272: 
0273:     $html = "<img src=\"{$data}\" />";
0274:     $body = makeCommonBody($tex$html);
0275: 
0276:     return($HtmlHeader . $body . $HtmlFooter);
0277: }

ユーザー関数 display は、exec_mimetex の結果を、img タグを用いて画面に表示する。
結果はバイナリの GIF データであるため、これを  base64_encode  関数を使って BASE64 コード化し、img の src 属性にセットする。

次に、makeCommonBody 関数を呼び出し、入力やヘルプに関わる HTML タグを追加する。

解説:ダウンロード処理

0279: /**
0280:  * ダウンロード処理
0281:  * @param   string $tex TeX文
0282:  * @return  なし
0283: */
0284: function download($tex) {
0285:     $fname = DOWNLOAD_FNAME;
0286: 
0287:     //mimeTeX実行
0288:     $data = exec_mimetex($tex);
0289: 
0290:     //ダウンロード出力
0291:     header("Content-Type: image/gif");
0292:     header("Content-Disposition: attachment; filename={$fname}");
0293:     echo $data;
0294: }

ユーザー関数 download は、exec_mimetex の結果を、ブラウザを介してクライアントにダウンロードできるようにする。TeX 画像をローカルで利用したいような場合を想定し、この機能を用意した。

ダウンロード出力の際、関数  header  を使って必要な http ヘッダを送信するようにした。

解説:処理の分岐

0056:  * 処理選択肢
0057:  * @global array $SelectFuncs
0058: */
0059: $SelectFuncs = array(
0060:     //関数名               タイトル             ラジオボタンcheked
0061:     'display'  => array('title'=>'画面表示',     'checked'=>'checked'),
0062:     'download' => array('title'=>'ダウンロード', 'checked'=>''),
0063: );

0142: /**
0143:  * checkedされている処理を検索する
0144:  * @return  string 選択された関数名/FALSE=checkedされている処理がない
0145: */
0146: function getSelectFunc() {
0147:     global $SelectFuncs;
0148: 
0149:     foreach ($SelectFuncs as $key=>$val) {
0150:         if ($val['checked'] == 'checked')  return $key;
0151:     }
0152:     return FALSE;
0153: }

0155: /**
0156:  * 処理をchekedする
0157:  * @param   string $func 処理関数名
0158:  * @return  bool TRUE/FALSE
0159: */
0160: function setSelectFunc($func) {
0161:     global $SelectFuncs;
0162: 
0163:     $old = getSelectFunc();
0164:     if ($func != FALSE)      $SelectFuncs[$old]['checked'] = '';
0165:     $SelectFuncs[$func]['checked'] = 'checked';
0166: 
0167:     return TRUE;
0168: }

0300: echo $func($tex);        //選択した処理を実行する
0301: 

分岐処理は、変数 $SelectFuncs にテーブルとして用意している。この項目を増やして、対応する関数を増やせば、機能を拡張できるようになっている。

処理の分岐は、可変関数を使っている。つまり、変数 $func に代入された関数名にしたがって処理を分岐するようになっている。

参考サイト

(この項おわり)
header