TeX → HTML

連分数について書いていたら、数式を書くのが大変でやってられなくなった。
例えば、

anm+1

とHTMLで表示させるには、

<var>a</var><sub><var>n</var></sub><sup><var>m</var>+1</sup>

と書かなければならない。上付きと下付きの処理をして、変数をTimes New Romanのイタリックにしている。こんな簡単な式でも大変だし、合っているのかもなかなかわからない。ちなみに、タグの変換(< → &lt;, > → &gt;)は秀丸のマクロを使っている。これは10年以上前に書いたものらしい。
mimeTeXなら、

a_n^{m+1}

と書けて、簡単かつ見やすい。しかし、画像になるのには抵抗がありHTMLで書けるものまでそうするのはできれば避けたい。
そこで、TeXのように書いて秀丸のマクロで変換すればいいのではないかと思いついた。なんでも秀丸で書く人間なので、これがあると便利なはず。
変換したい部分を選択し、マクロを走らせる。秀丸のマクロを書くのは本当に大変だ。今のところうまく動いているが、どうだろう。



#y1 = seltopy;
#y2 = selendy;
cut;
beginclipboardread;

#i = #y1;
while(#i <= #y2) {
$s_tex = getclipboard;
#len = strlen($s_tex);
$s_tex2 = "";
#k = 0;
#mode = 0;
while(#k < #len) {
$c = midstr($s_tex, #k, 1);
if(#mode == 0) {
if($c == "^" || $c == "_") {
#mode = 1;
}
$s_tex2 = $s_tex2 + $c;
}
else if(#mode == 1) {
if($c != "{") {
$s_tex2 = $s_tex2 + "{" + $c + "}";
}
else {
$s_tex2 = $s_tex2 + $c;
}
#mode = 0;
}
#k = #k + 1;
}

$s_html = "";
#len = strlen($s_tex2);
#stack_tail = -1;
#k = 0;
while(#k < #len) {
$c = midstr($s_tex2, #k, 1);
if($c == "^") {
$s_html = $s_html + "<sup>";
call push "sup";
}
else if($c == "_") {
$s_html = $s_html + "<sub>";
call push "sub";
}
else if($c == "}") {
call pop;
$tag = $$return;
$s_html = $s_html + "</" + $tag + ">";
}
else if($c != "{") {
call is_isolated_lower $s_tex2, #k;
if(##return)
$s_html = $s_html + "<var>" + $c + "</var>";
else
$s_html = $s_html + $c;
}
#k = #k + 1;
}
insert $s_html;
#i = #i + 1;
}

endmacro;

pop:
$$tag = $stack[#stack_tail];
#stack_tail = #stack_tail - 1;
return $$tag;

push:
$$tag = $$1;
#stack_tail = #stack_tail + 1;
$stack[#stack_tail] = $$tag;
return;

is_lower_case:
$$c = $$1;
##code = ascii($$c);
if(ascii("a") <= ##code && ##code <= ascii("z"))
return 1;
else
return 0;

is_isolated:
$$s = $$1;
##k = ##2;
if(##k == 0) {
if(strlen($$s) == 1) {
return 1;
}
else {
call is_lower_case midstr($$s, 1, 1);
if(##return)
return 0;
else
return 1;
}
}
else if(##k == strlen($$s) - 1) {
call is_lower_case midstr($$s, ##k - 1, 1);
if(##return)
return 0;
else
return 1;
}
else {
call is_lower_case midstr($$s, ##k - 1, 1);
if(##return) {
return 0;
}
else {
call is_lower_case midstr($$s, ##k + 1, 1);
if(##return)
return 0;
else
return 1;
}
}

is_isolated_lower:
$$s = $$1;
##k = ##2;
call is_lower_case midstr($$s, ##k, 1);
if(##return) {
call is_isolated $$s, ##k;
return ##return;
}
else {
return 0;
}