1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
| <?php
function plugin_eq_convert()
{
$arg = rtrim(join(func_get_args(), ','), ','); // 末尾の「,」は波引数が空の場合に現れ、不要物。
return '<div class="eq">'.plugin_eq_core($arg, 'convert').'</div>';
}
function plugin_eq_inline()
{
$arg = rtrim(join(func_get_args(), ','), ','); // 末尾の「,」は波引数が空の場合に現れ、不要物。
return '<span class="eq">'.plugin_eq_core($arg, 'inline').'</span>';
}
function plugin_eq_core($arg, $mode)
{
$eq_dir = './eq/'; // 数式と数式画像のパス
$err_msg_end_phrase = 'No pages of output.'.PHP_EOL; // エラー終了を示す文字列(platexの出力依存)
$prefix_convert = 'eq-nc-'; // ブロック用ファイル衝突を避けるための接頭語
$prefix_inline = 'eq-ni-'; // インライン用ファイル衝突を避けるための接頭語
$tex_frame_convert = 'convert.tex'; // ブロック用フレームファイル名
$tex_frame_inline = 'inline.tex' ; // インライン用フレームファイル名
$eq_replace_phrase = '\input{eq}' ; // フレームファイルで数式を埋め込む部を示す文字列
$key = ($mode=='inline') ? $prefix_inline.md5($arg) : $prefix_convert.md5($arg);
$eq = $key.'.eq'; // 照合用引数出力(保存ファイル)
$img = $key.'.png'; // 数式の画像出力(保存ファイル)
$old_dir = getcwd();
chdir($eq_dir);
if (!file_exists($img) || $arg != file_get_contents($eq))
{
// 一時ファイル
$tex = $key.'.tex';
$std = $key.'.std.log'; // Tex の標準出力、エラー出力用
$dvi = $key.'.dvi';
$aux = $key.'.aux';
$log = $key.'.log';
$box = $key.'.box.png';
$face = $key.'.face.png';
$edge = $key.'.edge.png';
$bold = $key.'.bold.png';
flush(); // Timeout 対策
$tex_code = file_get_contents(($mode=='inline') ? $tex_frame_inline : $tex_frame_convert);
$tex_code = str_replace($eq_replace_phrase, $arg, $tex_code);
file_put_contents($eq ,$arg );
file_put_contents($tex ,$tex_code);
exec('platex -halt-on-error '.$tex.' > '.$std);
flush(); // Timeout 対策
if (!file_exists($dvi)) // Tex Error
{
$err_flag = false;
$err_code = "Tex Error:\n\n";
if ($log_code = fopen($std, 'r'))
{
while (!feof($log_code))
{
$tex_msg = fgets($log_code);
if ($tex_msg[0] == '!' ) {$err_flag = true ;}
else if ($tex_msg == $err_msg_end_phrase) {$err_flag = false;}
if ($err_flag) {$err_code .= $tex_msg;}
}
fclose($log_code);
}
chdir($old_dir);
return '<pre class=eq_error_title>'.$arg.'</pre><pre class=eq_error_message>'.$err_code.'</pre>';
}
exec('dvipng -D 720 -T tight --gamma 2.5 -o '.$box.' '.$dvi);
if ($mode=='inline') {
list($width, $height) = getimagesize($box);
exec('convert '.$box.' -crop '.($width-16).'x'.($height-16).'+8+8 -bordercolor #FFFFFF -threshold 50% '.$face);
} else {
exec('convert '.$box.' -bordercolor #FFFFFF -border 16x16 -threshold 50% '.$face);
}
exec('convert '.$face.' -edge 1 -negate '.$edge);
exec('composite -compose multiply '.$face.' '.$edge.' '.$bold);
exec('convert '.$bold.' -black-threshold 90% -antialias -blur 1 - | convert - -transparent #FFFFFF -antialias '.$img);
flush(); // Timeout 対策
unlink($tex );
unlink($std );
unlink($dvi );
unlink($aux );
unlink($log );
unlink($box );
unlink($face);
unlink($edge);
unlink($bold);
}
list($width, $height) = getimagesize($img);
chdir($old_dir);
return '<img widht='.round($width/7).' height='.round($height/7).' src="'.$eq_dir.$img.'" alt="eq: '.$arg.'" title="'.$arg.'">';
}
?>
|