TeX → HTML(2)

http://d.hatena.ne.jp/inamori/20100122/p2
前回、上付き下付きを処理する秀丸のマクロを書いたが、それは2バイト文字が混じるとうまく動かなかった。秀丸のマクロは2バイト文字は2文字として扱うからだ。それを回避するには、まず1文字を取ってそれを$cとする。そのとき、2バイト文字のときはascii($c)>=256となるので、2文字取る。こうすればうまく動く。

#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(ascii($c) >= 256)
            $c = midstr($s_tex, #k, 2);
        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 + strlen($c);
    }
    
    $s_html = "";
    #len = strlen($s_tex2);
    #stack_tail = -1;
    #k = 0;
    while(#k < #len) {
        $c = midstr($s_tex2, #k, 1);
        if(ascii($c) >= 256)
            $c = midstr($s_tex2, #k, 2);
        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 + strlen($c);
    }
    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;
    }