*【編集中】 [#ref92ed9] #contents * 方針 [#d8342a00] - コードで画像を出力したい。 - 特定用途なら専用言語で良い。 - 汎用用途ならコーディングし易さを考慮した汎用言語が良い。svg のタグ打ちはコーダーに優しくない。 * 仕様 [#j59f5d78] - [[blockdiag>http://blockdiag.com/ja/index.html]]という便利な作図ツールが作られている。 -- http://blockdiag.com/ja/index.html - Python で実装されているため、プラグイン扱いで拡張する。 - blockdiag、seqdiag、actdiag、nwdiag、packetdiag とコマンド名が分かれているが、コードから判別可能のため、プラグインは diag に統一。 - 出力は HTML と親和性の高い SVG 直埋め込みとする。ただ、IE8など非対応ブラウザには png で出すべし。 * 実装 [#gb40f8e7] - plugin/diag.inc.php を新規作成。 ### <?php function plugin_diag_convert() { $arg = rtrim(join(func_get_args(), ','), ','); // 末尾の「,」は波引数が空の場合に現れ、不要物。 return '<div class="diag">'.plugin_diag_core($arg, 'convert').'</div>'; } function plugin_diag_inline() { $arg = rtrim(join(func_get_args(), ','), ','); // 末尾の「,」は波引数が空の場合に現れ、不要物。 return '<span class="diag">'.plugin_diag_core($arg, 'inline').'</span>'; } function plugin_diag_core($arg, $mode) { $diag_dir = './diag/'; // 数式と数式画像のパス $err_msg_end_phrase = 'No pages of output.'.PHP_EOL; // エラー終了を示す文字列(platexの出力依存) $prefix_convert = 'diag-nc-'; // ブロック用ファイル衝突を避けるための接頭語 $prefix_inline = 'diag-ni-'; // インライン用ファイル衝突を避けるための接頭語 $key = ($mode=='inline') ? $prefix_inline.md5($arg) : $prefix_convert.md5($arg); $diag_euc = $key.'.euc.diag'; // 照合用引数出力(保存ファイル) $diag_utf = $key.'.utf.diag'; // コンパイル出力(保存ファイル) $img = $key.'.svg'; // 数式の画像出力(保存ファイル) $old_dir = getcwd(); chdir($diag_dir); if (!file_exists($img) || $arg != file_get_contents($diag_euc)) { $std = $key.'.std.log'; // Tex の標準出力、エラー出力用 $euc = $key.'.std.log'; // Tex の標準出力、エラー出力用 flush(); // Timeout 対策 //$arg = "diag {\n" . $arg . "\n}"; // コード補完 //$arg = mb_convert_encoding($arg, 'utf8-win'); $command = "blockdiag "; //$command = str_replace(";", ";\n", $command); if (preg_match( '/^\s*seqdiag\b/', $arg)) {$command = "seqdiag ";} if (preg_match( '/^\s*actdiag\b/', $arg)) {$command = "actdiag ";} if (preg_match( '/^\s*nwdiag\b/', $arg)) {$command = "nwdiag ";} if (preg_match( '/^\s*rackdiag\b/', $arg)) {$command = "rackdiag ";} if (preg_match('/^\s*packetdiag\b/', $arg)) {$command = "packetdiag ";} //$arg = mb_convert_encoding($arg, 'SJIS-WIN', 'UTF-8'); //$arg = mb_convert_encoding(mb_convert_encoding($arg, 'sjis-win', 'eucJP-win'), 'UTF-8', 'sjis-win'); file_put_contents($diag_euc, $arg); exec('nkf -w '.$diag_euc.' > '.$diag_utf); exec($command . $diag_utf.' -f %windir%\fonts\msgothic.ttc -Tsvg -o '. $img . ' 2> ' . $std ); exec('nkf -e --overwrite '.$img); flush(); // Timeout 対策 if (!file_exists($img)) // Tex Error { $err_flag = false; $err_code = "diag Error:\n\n"; if ($log_code = fopen($std, 'r')) { while (!feof($log_code)) { $msg = fgets($log_code); $err_code .= $msg; } fclose($log_code); } chdir($old_dir); return '<pre class=diag_error_title>'.$arg.'</pre><pre class=diag_error_message>'.$err_code.'</pre>'; } flush(); // Timeout 対策 } $xml = file($img); array_shift($xml); array_shift($xml); $match = array(); preg_match('/^<svg[^>]+viewBox\s*=\s*\"\s*\d+\s*\d+\s*(\d+)\s*(\d+)\s*\"/', $xml[0], $matches); $width = $matches[1]; $height = $matches[2]; $svg = implode($xml); $agent = getenv('HTTP_USER_AGENT'); chdir($old_dir); // return '<img style="width:'.$width.'em; height:'.$height.'em; vertical-align:'.$depth.'em;". src="'.$diag_dir.$img.'" alt="$$'.$arg.'$$" title="'.$arg.'">'; // return '<img src="'.$diag_dir.$img.'" alt="'.htmlspecialchars ($arg).'" title="'.htmlspecialchars ($arg).'">'; // return '<object type="image/svg+xml" data="'.$diag_dir.$img.'" style="width:'.$width.'; height:'.$height.';" alt="'.htmlspecialchars ($arg).'" title="'.htmlspecialchars ($arg).'"></object>'; // return $svg.'<pre>'.htmlspecialchars(print_r($matches, TRUE)).'</pre>'; return '<div style="width: '.$width.'px;" >'.$svg.'</div>'; } ?> ### * 開発メモ [#n362f009] *** 文字コード変換 [#z22d52cc] - 日本語を扱うため、EUC ⇒ UTF8 ⇒ EUC と変換する必要がある -- 流用した PukiWiki が EUC ベースなため、プラグイン引数は EUC -- diag 達の標準エンコーディングは UTF8なため、コンパイル前に変換する必要がある。 -- PukiWiki で出力される HTML に直埋め込みするため、再度 EUC に変換する必要がある。 - 訳分からんが、PHP の mb 関数は変換してくれない。 -- http://www.asp-edita.jp/doda/one/doda5728_15.html - とりあえず、nkf というツールがあるので、それで仮実装。 - とりあえず、nkf というツールがあったので、それで仮実装。 -- Tex にあった。 *** svg 非対応ブラウザ [#u0259b28] - ブラウザ情報を解析して、png で出すべし。 - 技術的に実現可能と分かっているが、検証できそうにないので先延ばし… -- ブラウザ情報を表示するページでも用意し、他力本願で報告フォームを使おうか? |