tate.c

縦書きのウェブページを作成するために、これをつくりました。もとになるテキストはもちろん、横書きで書くのですが、すべて全角文字で、一行20文字(全角)に整えておかなければなりません。文字コードは Linux 標準の EUC-JP にします。MS Windows で作った文書には EOF コード(0x1A) が含まれて、不都合がありましたので、プログラムにこれをチェックする部分をつけくわえました。以下、順を追って解説します。

/*

tate.c

tategaki html generater

*/

#include <stdio.h>

#define YES 1
#define NO  0

char data[20][40], list[8][5], kigo[8][5];

最後の行は、グローバル変数です。data には、横書き文書の 20行分を格納します。一行が全角20文字、半角で40文字なので data[20][40] となっています。

list と kigo は対になっている変数で、横書きから縦書きに変換した時に正しく表示されない記号類を変換させるものです。list[3] にある文字は kigo[3] にある文字に変換されるようになっています。鈎括弧などは罫線記号などで代用していますので、こうしたものは左右にシフトさせないとそれらしく見えないので、文字の両側を半角スペースではさんで、左右のシフトを実現し、あわせて、縦書きの行間にしています。プログラムリストの最後にある mk_checklist() を見ていただければ、何をしているか分かっていただけると思います。

main()
{

/* page start */

fprintf(stdout, "<html>\n");
fprintf(stdout, "<head>\n");
fprintf(stdout, "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=euc-jp\">\n");
fprintf(stdout, "<title>Tategaki Document</title>\n");
fprintf(stdout, "</head>\n");
fprintf(stdout, "<body>\n");
fprintf(stdout, "<center>\n");

while(1){
    if(mk_data()==1){
        print_page();
        break;
        }
    print_page();
    }

/* page end */

fprintf(stdout, "</center>\n");
fprintf(stdout, "</body>\n");
fprintf(stdout, "</html>\n");
}

main() はいたってシンプルです。入出力は標準入出力を使いますので、コマンドラインから tate < inputfile > outputfile と入力します。mk_data() で一行20文字に整形された文書を data に格納して、それを print_page() で 20行づつ縦書きに書き込んでいくだけです。mk_data() が返す価は、ファイルの終わりに達したら 1 を、そうでなければ 0 になります。

/* page start */ や /* page end */ には、HTML ファイルの内容を自由に記述できます。

mk_data()
{
int  i, j;
char buf[40];

for(i=0; i<20; i++){
    if(fgets(buf, 40, stdin)==NULL){
        page_end(i);
        return 1;
        }
    for(j=0; j<40; j++){
        if(buf[j]=='\n' || buf[j]=='\x1A'){
            line_end(i*100+j);
            break;
            }
        else
            data[i][j]=buf[j];
        }
    }
return 0;
}

page_end(int i)
{
int  j;

for(; i<20; i++)
    for(j=0; j<40; j++)
        data[i][j]='\xA1';
}

line_end(int n)
{
int  i, j;

i=n/100;
j=n%100;

for(; j<40; j++)
    data[i][j]='\xA1';
}

mk_data() でやっていることは行が途中で改行されたら、残りの部分を全角スペース(0xA1A1) で埋めるという作業です。ページの途中で行が終った場合も残りの行を全部全角スペースで埋めています。このしたごしらえをしておけば、横のものを縦にするのは簡単です。

print_page()
{
int  i, j, n;
char mozi[5], string[81];

fprintf(stdour, "<hr>");
fprintf(stdout, "<PRE><TT STYLE=\"font-size:14px; line-height:15px;\">\n");

mk_checklist();

for(i=0; i<20; i++){
    strcpy(string, "");
    for(j=0; j<20; j++){
        sprintf(mozi, " %c%c ", data[19-j][i*2], data[19-j][i*2+1]);
        n=check(mozi);
        if(n>=0)
            strcat(string, kigo[n]);
        else
            strcat(string, mozi);
        }
    fprintf(stdout, "%s\n", string);
    }
fprintf(stdout, "</FONT></TT></PRE>\n");
}

ここでしていることは、図であらわすと次のようになります。最初の図は、横書きの文字データの並びです。

 

これを縦書きにするには、第一行目を横書きの 5A, 4A ... 1A の順で繋げ、二行目を 5B, 4B ... 1B というふうに繋げてプリントすればいいのです。次の表は縦書きの場合の表です。

 

sprintf(mozi, " %c%c ", data[19-j][i*2], data[19-j][i*2+1]); の部分が、表の入れ換えをしている部分です。ここでは、文字を半角スペースで挟んで、行間をつくり出すとともに、記号のシフトにそなえています。

check(char *mozi)
{
int  i, key;

key=NO;
for(i=0; i<8; i++){
    if(strcmp(mozi, list[i])==0){
        key=YES;
        break;
        }
    }
if(key==YES)
    return i;
else
    return -1;
}

mk_checklist()
{
strcpy(list[0], " 、 ");
strcpy(kigo[0], "  `");

strcpy(list[1], " 。 ");
strcpy(kigo[1], "  ゜");

strcpy(list[2], " ー ");
strcpy(kigo[2], " l ");


strcpy(list[3], " − ");
strcpy(kigo[3], " | ");

strcpy(list[4], " ( ");
strcpy(kigo[4], " ∧ ");

strcpy(list[5], " ) ");
strcpy(kigo[5], " ∨ ");

strcpy(list[6], " 「 ");
strcpy(kigo[6], "  ┐");

strcpy(list[7], " 」 ");
strcpy(kigo[7], "└  ");
}

最後の部分は文字の変換プログラムです。長音(ー)はダッシュと区別するために小文字の「l」を使いましたが、他に良い方法があるかもしれません。「…」や「‥」などは「・・・」などのように中点を使って表わすようにします。このプログラムは横書き用のフォントで縦書きをあらわそうとしているので、無理があります。こまかいところは原稿の段階で工夫するしかなさそうです。

このプログラムで縦書き HTML を作ったのですが、不注意にも、もとになるテキストファイルを消してしまいました。それで縦書き HTML から、もとのテキストを取りだす yoko.c を書かざるを得なくなりました。よろしかったらご覧ください。

[目次にもどる]