/* This program transforms a plain text file into a DVI file. The font used for ASCII characters is CMTT10 at 10pt whose default width is equal to 5.249958pt. Author: Zhang Linbo. */ typedef unsigned char byte; #define ASCII_FONT_NAME "cmtt10" /* name of the ASCII font used */ #define ASCII_FONT_DS 10.0 /* design size */ #define HALF_CHAR_WIDTH 5.249958 /* width of the characters */ #define CC_SIZE 9.636 /* width of Chinese characters in pt */ #define LINE_SPACING 12 /* line spacing */ #define FOOTSKIP ((long)(2.0*LINE_SPACING*65536.0+0.5)) #define FOOTHEIGHT ((long)(1.0*LINE_SPACING*65536.0+0.5)) #define DVI_ID 2 /* DVI id byte */ #define NUM 25400000l /* DVI numerator */ #define DEN 473628672l /* DVI denominator */ #define MAG 1000l /* magnification */ int chars_per_line; /* # of chars/line */ int lines_per_page; /* # of lines/page */ int ziti; /* style */ #include #include #include #include byte s_in[256], s_out[256+4]; FILE *f_in,*f_out; int posx,posy; long hsize,vsize,vsize1; long h,v; /* current position */ long w,x,y; /* w=half char width, x=2*w-CC_SIZE, y=line spacing */ int pageno0,np,pageno_flag,fontno,bop_flag,ascii_flag,cc_flag; long ll,loc; void put_ascii_char(byte ch); void write_dvi_number(unsigned long value, int len, FILE *f_dvi) /* write a number of 'len' bytes (len<=4) to dvi file */ { byte buffer[4]; register int i; for (i=0; ivsize) eop(); /* start a new page */ } void put_ascii_char(byte ch) /* output an ASCII char */ { if (!bop_flag) bop(); if (!ascii_flag) ascii_font_def(); if ((h+w)>hsize) advance_line(); if (!bop_flag) bop(); if (ch!=' ') { if (fontno) set_font(0); fputc(ch,f_out); /* set_char command */ } else { fputc(147,f_out); /* w0 command */ } h+=w; } void put_cc_char(byte ch1,byte ch2) /* output an ASCII char */ { if (!bop_flag) bop(); if (!cc_flag) cc_font_def(0); if ((h+w+w)>hsize) advance_line(); if (!bop_flag) bop(); if (fontno!=1) set_font(1); fputc(ch1-128,f_out); /* set_char command */ fputc(ch2-128,f_out); /* set_char command */ fputc(152,f_out); /* x0 command */ h+=w+w; } void *sp2a(long dim,byte s[]) /* transform a dimension in sp to cm in string form */ { long d=32768l*7227l; long mod,l; register int i,j,k,n; /* compute dim*127/d */ n=(int)(127l*(dim/d)); mod=dim%d; l=mod; for (i=1;i<127;i++) { mod+=l; if (mod>=d) {n++; mod-=d;} } sprintf(s,"%d.",n); k=strlen(s); strcat(s,"0000"); for (j=0;j<4;j++) { n=0; mod=mod+mod; if (mod>=d) {n+=5; mod-=d;} l=mod+mod; if (l>=d) {n+=2; l-=d;} l+=l; if (l>=d) {n++; l-=d;} mod+=l; if (mod>=d) {n++; mod-=d;} s[k++]+=n; } return(s); } void usage(void) { fprintf(stderr, "Usage: text2dvi [options] inputfile [outputfile.dvi]\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, " -c#\tnumber of chars/line (default 80).\n"); fprintf(stderr, " -l#\tnumber of lines/page (default 58).\n"); fprintf(stderr, " -z#\tziti (0=songti, 1=heiti, 2=kaishu, 3=fangsong).\n"); fprintf(stderr, " -p \tdon't add page numbers.\n"); fprintf(stderr, " -n#\tfirst page number (default 1).\n"); exit(0); } int main(int argc,byte *argv[]) { register int i,n; int k; byte *p,s[256]; printf("TEXT2DVI V1.1, Dec. 1999. Author: Zhang Linbo\n"); printf("This program transforms a plain text file to DVI format.\n"); f_in=f_out=NULL; s_in[0]=s_out[0]='\0'; chars_per_line=80; lines_per_page=58; ziti=0; pageno_flag=1; pageno0=0; for (i=1; i=4) goto opt_err; break; case 'P': pageno_flag=0; break; case 'N': pageno0=atoi(argv[i]+2)-1; break; default: fprintf(stderr, "Invalid option \"-%c\".\n", argv[i][1]); usage(); } else { if (s_in[0]=='\0') { strncpy(s_in, argv[i], sizeof(s_in)-1); s_in[sizeof(s_in)-1]='\0'; } else if (s_out[0]=='\0') { strncpy(s_out, argv[i], sizeof(s_out)-1); s_out[sizeof(s_out)-1]='\0'; } else { fprintf(stderr, "Error: third filename specified (%s).\n", argv[i]); usage(); } } } if (s_in[0]=='\0') usage(); if ((f_in=fopen(s_in,"rt"))==NULL) { printf("Cannot open input file \"%s\"!\n",s_in); goto fin; } if (s_out[0]=='\0') { strcpy(s_out,s_in); i=strlen(s_out)-1; if (i<0) goto fin; for (;i>=0 && s_out[i]!='.';i--); if (i>=0 && s_out[i+1]!='\\') s_out[i]='\0'; strcat(s_out,".dvi"); } if (!strcmp(s_in,s_out)) { printf("Input & output file names are the same!\n"); goto fin; } if ((f_out=fopen(s_out,"w+b"))==NULL) { printf("Cannot open output file \"%s\"!\n",s_out); goto fin; } if (setvbuf(f_out,NULL,_IOFBF,30*1024)) { printf("Cannot allocate output buffer!\n"); goto fin; } w=(long)(HALF_CHAR_WIDTH*65536.0+0.5); x=w+w-(long)(CC_SIZE*65536.0+0.5); y=(long)(LINE_SPACING*65536.0+0.5); hsize=w*chars_per_line; vsize=y*lines_per_page+y; vsize1=vsize+FOOTHEIGHT; printf("Transforming %s ==> %s...\n",s_in,s_out); printf("Page width=%scm, Page height=%scm\n", sp2a(hsize,s),sp2a(pageno_flag ? vsize1:vsize,s+128)); /* create DVI preamble */ fputc(247,f_out); /* pre command */ fputc(DVI_ID,f_out); /* DVI id. */ write_dvi_number(NUM, 4, f_out); /* num */ write_dvi_number(DEN, 4, f_out); /* den */ write_dvi_number(MAG, 4, f_out); /* mag */ p=" TEXT2DVI V1.0"; i=strlen(p); fputc(i,f_out); fwrite(p,1,i,f_out); /* comments */ loc=0xffffffffl; bop_flag=ascii_flag=cc_flag=0; np=0; n=0; k=0; /* processing pages */ do { i=fgetc(f_in); if (i==EOF || i==0x1a) break; if (i==13) continue; cont: if (i>=32 && i<=127) { put_ascii_char(i); /* ASCII char */ n++; } else if (i>=161 && i<=254) { byte ch; ch=i; i=fgetc(f_in); if (i==EOF || i==0x1a) break; if (i<161 || i>254) { printf("\nIncomplete Chinese character code ignored, line %d\n",k+1); goto cont; } put_cc_char(ch,i); /* Chinese char */ n+=2; } else if (i=='\t') { do put_ascii_char(' '); while ((++n)&7); } else if (i==12) { eop(); /* new page */ n=0; } else if (i=='\n') { advance_line(); /* new line */ n=0; k++; } else { printf("\nInvalid character (%d) ignored at line %d\n",i,k+1); } } while (1); if (bop_flag) eop(); /* create the postamble */ ll=loc; loc=ftell(f_out); fputc(248,f_out); /* post command */ write_dvi_number(ll, 4, f_out); /* last page loc. */ write_dvi_number(NUM, 4, f_out); /* num */ write_dvi_number(DEN, 4, f_out); /* den */ write_dvi_number(MAG, 4, f_out); /* mag */ ll=pageno_flag ? vsize1:vsize; write_dvi_number(ll, 4, f_out); /* maxi. page height */ ll=hsize; write_dvi_number(ll, 4, f_out); /* maxi. page width */ write_dvi_number(1, 2, f_out); /* stack depth */ write_dvi_number(np, 2, f_out); /* # of pages */ if (ascii_flag) ascii_font_def(); /* ASCII font definition */ if (cc_flag) cc_font_def(1); /* Chinese font definition */ /* the post-post command */ fputc(249,f_out); /* post-post command */ write_dvi_number(loc, 4, f_out); /* loc. of the postamble */ fputc(DVI_ID,f_out); /* DVI id */ for (i=0;i<4;i++) fputc(223,f_out); /* adjust file length to multiple of 4 */ loc=ftell(f_out); n=(int)(loc&(4l-1)); if (n) { n=4-n; for (i=0;i