yoko.c

縦書きのウェブページを作るために tate.c を書きました。その後、tate.c に改良を加え、全角で一行二十文字、一段十八行の HTML を作りました。われながらうまくいったと自画自賛して、あれこれやっている間に、もとになるテキストファイルを消してしまいました。それで縦書き HTML から、もとのテキストを取りだす yoko.c を書かざるを得なくなりました。何の役にも立たないプログラムですが、一応お目にかけます。

/*

yoko.c

get original text from TATE-HTML

*/

#include <stdio.h>
#define YES  1
#define NO   0
#define LN   18
#define SIZE 20

char data[SIZE][80], kigo[200], list[200];

上の #define の LN は一段の行数、SIZE は一行の文字数をあらわします。縦書きのさいの記号の変換リストの格納を配列から文字列に変えましたので、kigo と list は一次配列になっています。

main()
{
int  n;
char buf[400];

mk_checklist();

n=0;
while(fgets(buf, 400, stdin)!=NULL){
    if(n%SIZE==0 && n>0){
        convert();
        n=0;
        }
    else if(buf[0]!='<'){
        strcpy(data[n], buf);
        n++;
        }
    }
}

main でやっていることは三つあります。ひとつは、縦書きのデータ部分だけ読みこむことです。データ部分以外はすべて HTML のタグ記号で始まっていますので、'<' が行頭にくるものは data に収めないようにしています。ふたつめは、data は 20行あるので(縦書きだと18行になるが、データの並びは、縦書きの一行の文字数とおなじ20行になる)そこで句切りをつけること、そして三つめに縦書きデータを横書きに変換して書き出すルーチン convert を呼び出すことです。

convert()
{
int  i, j, n, k;
char mozi[5], line[80];

for(j=LN-1; j>=0; j--){
    strcpy(line, "");
    for(i=0; i<SIZE; i++){
        if(data[i][j*4])
            sprintf(mozi, "%c%c%c%c", data[i][j*4], data[i][j*4+1], data[i][j*4+2], data[i][j*4+3]);
        n=check(mozi);
        if(n>=0)
            sprintf(mozi, "%c%c", list[n+1], list[n+2]);
        else
            sprintf(mozi, "%c%c", mozi[1], mozi[2]);
        strcat(line, mozi);
        }
    for(k=strlen(line)-2; k>=0; k-=2){
        if(line[k]=='\xA1' && line[k+1]=='\xA1')
            ;
        else
            break;
            }
    line[k+2]='\0';
    fprintf(stdout, "%s\n", line);
    }
}

ここでは、横書きを縦書きになおしたのと逆の操作をしています。check() は後で出て来る記号変換ルーチンです。行末の空白を取り除くために、横書きにした一行分をひとまず line に格納して、うしろからそれを読んでいき、空白以外の文字が来たらそこでストップするようにしました。それが以下の部分です。

    for(k=strlen(line)-2; k>=0; k-=2){
        if(line[k]=='\xA1' && line[k+1]=='\xA1')
            ;
        else
            break;
            }
    line[k+2]='\0';
この部分は全部空白で先頭部分まで戻った時は -2 を返しますので、line[k+2] のところは line[0] となり、空の行からも空白記号を取り除いてくれます。

check(char *mozi)
{
int  i, key;
char buf[5];

key=NO;
for(i=0; i<strlen(list); i+=4){
    sprintf(buf, "%c%c%c%c", kigo[i], kigo[i+1], kigo[i+2], kigo[i+3]);
    if(strcmp(mozi, buf)==0){
        key=YES;
        break;
        }
    }
if(key==YES)
    return i;
else
    return -1;
}

mk_checklist()
{
int i;

strcpy(list, " 、 ");
strcpy(kigo, "  `");

strcat(list, " 。 ");
strcat(kigo, "  ゜");

strcat(list, " ー ");
strcat(kigo, " l ");

strcat(list, " − ");
strcat(kigo, " | ");

strcat(list, " … ");
strcat(kigo, " : ");

strcat(list, " ( ");
strcat(kigo, " ∧ ");

strcat(list, " ) ");
strcat(kigo, " ∨ ");

strcat(list, " < ");
strcat(kigo, " ∧ ");

strcat(list, " > ");
strcat(kigo, " ∨ ");

strcat(list, " 「 ");
strcat(kigo, "  ┐");

strcat(list, " 」 ");
strcat(kigo, "└  ");

strcat(list, " “ ");
strcat(kigo, "  〃");

strcat(list, " ” ");
strcat(kigo, "〃  ");
}

変換リストは文字列に収めることにしました。このほうがリストに付け加える時に、配列の番号を記入する必要がなく楽だからです。記号の変換リストは tate.c のものと変わっていますので、ご注意ください。

[目次にもどる]