/*****************************************************************************/ /* VNTeX.c -- Vietnamese TeX */ /* */ /* Thieu Nguyen and Hieu Tran */ /* nguyen@ics.uci.edu & tran@ics.uci.edu */ /* Department of Information & Computer Science */ /* University of California, Irvine */ /* Irvine, CA 92717 */ /* Summer 1986 */ /*****************************************************************************/ #include #include #include #include #define FALSE 0 #define TRUE 1 #define space(X) (!isalpha(X)) #define vowel(X) ((X=='a'||X=='e'||X=='i'||X=='o'||X=='u'||X=='y'|| \ X=='A'||X=='E'||X=='I'||X=='O'||X=='U'||X=='Y')) #define is_hat_breve(X) (X=='^'||X=='(') /*||X=='a')*/ #define norm_mark(X) (X=='?'||X=='.'||X=='`'||X=='~'||X=='\'') #define ismark(X) (X=='?'||X=='.'||X=='`'||X=='~'||X=='\''|| \ X=='^'||X=='(') /*||X=='a')*/ #define is_uo_mark(X) (X=='?'||X=='.'||X=='`'||X=='~'||X=='\'') #define is_dD(X,Y) ((X=='d'&&Y=='d') || (X=='D'&&Y=='D')) #define is_uo(X,Y) ((X=='u'&&Y=='u') || (X=='U'&&Y=='U') || \ (X=='o'&&Y=='o') || (X=='O'&&Y=='O')) #define is_not_oo(X) ((X=='a'||X=='e'||X=='i'||X=='u'||X=='y'|| \ X=='A'||X=='E'||X=='I'||X=='U'||X=='Y')) #define text_command(X,Y,Z) \ (X=='\\' && Y==Z && \ (Y=='d'||Y=='D'||Y=='u'||Y=='U'||Y=='o'||Y=='O')) #define quote(X, Y) ((X==Y) && ((X=='`') || (X=='\''))) #define end_mark(X) (Y=='.' || Y=='?') #define esc_end(X, Y) (X=='\\' && (Y=='.' || Y=='?' || Y=='\'')) #define MACRO_FILE "VNTEX-MACRO.tex" FILE *in_file, *out_file, *macro_file; int dealt_uo(), twelvepoint = FALSE, elevenpoint = FALSE, flag = FALSE, line = 0; char out_buf [BUFSIZ], *output, /* output string in Tex form */ Hoiup[] = "Hoiup", sac[] = "sac", huy[] = "huy", hoi[] = "hoi", nga[] = "nga", nan[] = "nan", Sac[] = "Sac", Huy[] = "Huy", Hoi[] = "Hoi", Nga[] = "Nga"; main (argc, argv) register int argc; register char **argv; { char rawfile[ BUFSIZ ], file_tex[ BUFSIZ ]; register int len, fd, findex; init_sigs(); /* catch all errors and exit nicely */ if (argc <= 1) { printf ("Usage: VNTeX [-fontsize] .vnt\n"); printf (" -fontsize = 11 or 12 (default 10)\n"); exit (1); } if (*argv[1] == '-') { /* Get point size */ if (!strcmp(argv[1], "-12")) twelvepoint = TRUE; else if (!strcmp(argv[1], "-11")) elevenpoint = TRUE; findex = 2; } else findex = 1; strcpy (rawfile, argv[findex]); /* printf("This is VNTeX, Version 1.0 for Unix\n");*/ if ( !(acceptable_filename (rawfile)) ) { printf("Sorry, file name has to be ended with \".vnt\". Bye!\n"); exit (1); } if ((in_file = fopen (rawfile, "r")) == NULL) { perror (rawfile); exit (1); } /* replace the ".vnt" with the ".tex" */ strcpy (file_tex, rawfile); len = strlen (file_tex); file_tex[len-1] = 'x'; file_tex[len-2] = 'e'; file_tex[len-3] = 't'; if ((fd = open( file_tex, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) { perror (file_tex); exit (1); } out_file = fdopen (fd, "w"); if ((macro_file = fopen (MACRO_FILE, "r")) == NULL) { macro_file = fopen (MACRO_FILE, "w"); write_macro_file (); } fclose (macro_file); process_file (); /* start the translation */ if (fclose (in_file) == -1) perror (rawfile); if (fclose (out_file) == -1) perror (file_tex); } process_file () { char buf[BUFSIZ]; register char ch1, ch2, ch3, ch4; register int i, len; fprintf (out_file, "\\input %s\n\n", MACRO_FILE); while ( fgets( buf, BUFSIZ, in_file ) != NULL ) { line++; i = 0; output = out_buf; len = strlen( buf ); while (i < len) { ch1 = buf[i]; ch2 = buf[i+1]; ch3 = buf[i+2]; ch4 = buf[i+3]; if (is_dD(ch1, ch2)) { /* see dd or DD -- convert */ dealt_dD (ch1); /* to \dd or \DD, respec. */ i += 2; } else if (is_uo(ch1, ch2)) { /* see u or o -- handle */ i += dealt_uo (ch1, ch3, ch4); /* special cases. */ } else if (vowel(ch1)) { if (ismark(ch2)) { if (flag) { *output++ = ch1; *output++ = ch2; i += 2; } else { flag = TRUE; if (ismark(ch3)) { if (is_hat_breve(ch2)) { dealt_three (ch1, ch2, ch3); i += 3; } else { dealt_two (ch1, ch2); *output++ = ch3; i += 3; } } else { dealt_two (ch1, ch2); if (esc_end(ch3, ch4)) { /* skip over '\' */ *output++ = ch4; i += 4; } else { i += 2; } } } } /* Need to check for more special cases to distinguish end marks with regular marks. */ else { *output++ = ch1; if (esc_end(ch2, ch3)) { /* skip over '\' */ *output++ = ch3; i += 3; } else i++; } } else if (quote(ch1, ch2)) { /* see `` or '' - do nothing */ *output++ = ch2; *output++ = ch2; i += 2; flag = FALSE; } else if (text_command(ch1, ch2, ch3)) {/* see \dd, \oo or \uu -- */ *output++ = ch2; /* remove '\', e.g. the */ *output++ = ch2; /* \a\ddtolength command */ i += 3; flag = FALSE; } else if (space(ch1)) { /* new word, reset flag */ flag = FALSE; *output++ = ch1; i++; } else { /* a consonant */ *output++ = ch1; i++; } } *output = '\0'; fprintf (out_file, "%s", out_buf ); /* output to file */ } } /*****************************************/ /* Input file must have ".vnt" extension */ /*****************************************/ int acceptable_filename (filename) register char *filename; { register int i; i = strlen (filename); if (i < 5) return (FALSE); filename = filename + i - 4; if (!strcmp (filename, ".vnt")) return (TRUE); else return (FALSE); } /****************************************************/ /* To convert a vowel and a da^'u into Tex command. */ /****************************************************/ dealt_two (ch, sign) register char ch, sign; { if (isupper(ch)) ucase_two_marks(sign); else lcase_two_marks(sign); /* convert da^'u appropriately */ *output++ = '{'; *output++ = ch; *output++ = '}'; } /************************************************/ /* Convert a vowel and two da^'u into TeX form. */ /************************************************/ dealt_three (ch, sign1, sign2 ) register char ch, sign1, sign2; { if (isupper(ch)) ucase_three_marks(sign2); else lcase_three_marks(sign2); *output++ = '{'; dealt_two (ch, sign1); *output++ = '}'; } /***************************/ /* Convert letter dd or DD */ /***************************/ dealt_dD (ch) register char ch; { *output++ = '\\'; *output++ = ch; *output++ = ch; *output++ = ' '; } /***************************/ /* Process letter uu or oo */ /***************************/ int dealt_uo (ch, ch2, ch3) register char ch, ch2, ch3; { register int advance = 2; if (is_uo_mark(ch2)) { flag = TRUE; advance = 3; if (isupper(ch)) ucase_three_marks (ch2); else lcase_three_marks (ch2); } else if (is_hat_breve(ch2)) error (); *output++ = '{'; *output++ = '\\'; *output++ = ch; *output++ = ch; *output++ = '}'; if (is_not_oo(ch2)) { *output++ = ch2; advance = 3; flag = TRUE; } else if (esc_end(ch2, ch3)) { *output++ = ch3; advance += 2; } return advance; } /************************************************/ /* A lowercase vowel and 1 da^'u, including the */ /* conversion of da^'u "na(.ng", and "(" to TeX */ /* command: . => \d */ /* ( => \u */ /************************************************/ lcase_two_marks (sign) register char sign; { *output++ = '\\'; if (sign == '.') *output++ = 'd'; else if (sign == '(') *output++ = 'u'; else *output++ = sign; } /**********************************/ /* An uppercase vowel and 1 da^'u */ /**********************************/ ucase_two_marks (sign) register char sign; { register char *mark; if (sign == '?') { *output++ = '\\'; mark = Hoiup; while (*mark) *output++ = *mark++; } else lcase_two_marks (sign); } /*********************************/ /* A lowercase vowel and 2 da^'u */ /*********************************/ lcase_three_marks (X) register char X; { register char *mark; *output++ = '\\'; switch (X) { case '\'' : mark = sac; break; case '`' : mark = huy; break; case '?' : mark = hoi; break; case '~' : mark = nga; break; case '.' : mark = nan; break; } while (*mark) *output++ = *mark++; } /**********************************/ /* An uppercase vowel and 2 da^'u */ /**********************************/ ucase_three_marks (X) register char X; { register char *mark; *output++ = '\\'; switch (X) { case '\'' : mark = Sac; break; case '`' : mark = Huy; break; case '?' : mark = Hoi; break; case '~' : mark = Nga; break; case '.' : mark = nan; break; } while (*mark) *output++ = *mark++; } /***********************************/ /* Write an error message and exit */ /***********************************/ error () { *output = '\0'; fprintf (out_file, "%s", out_buf ); /* dump buffer */ printf ("*** Typing error in input file at line %d *** \n", line); exit (1); /* exit */ } /************************************/ /* Catch all errors and exit nicely */ /************************************/ init_sigs() { int exit(), error(); (void) signal(SIGINT, exit); (void) signal(SIGHUP, exit); (void) signal(SIGQUIT, error); (void) signal(SIGSEGV, error); (void) signal(SIGBUS, error); (void) signal(SIGILL, error); (void) signal(SIGFPE, error); } /*********************************************/ /* Define TeX commands for diacritical marks */ /*********************************************/ write_macro_file () { if (twelvepoint) fprintf (macro_file, "\\font\\mark=cmr9\n"); else if (elevenpoint) fprintf (macro_file, "\\font\\mark=cmr8\n"); else fprintf (macro_file, "\\font\\mark=cmr8\n"); fprintf (macro_file,"\\def\\?#1{\\hbox{\\raise.5ex\\hbox{\\kern.2em\\mark\\char39}\\kern-.5em#1}}\n"); fprintf (macro_file,"\\def\\sac#1{\\hbox{\\raise.5ex\\hbox{\\kern.1em\\char19}\\kern-.6em#1}}\n"); fprintf (macro_file,"\\def\\huy#1{\\hbox{\\raise.5ex\\hbox{\\kern.1em\\char18}\\kern-.6em#1}}\n"); fprintf (macro_file,"\\def\\hoi#1{\\hbox{\\raise.8ex\\hbox{\\kern.3em\\mark\\char39}\\kern-.6em#1}}\n"); fprintf (macro_file,"\\def\\nga#1{\\hbox{\\raise.5ex\\hbox{\\char126}\\kern-.6em#1}}\n"); fprintf (macro_file,"\\def\\nan#1{\\d{#1}}\n"); fprintf (macro_file,"\n"); fprintf (macro_file,"\\def\\Hoiup#1{\\hskip.1pt\\hbox{\\raise1.1ex\\hbox{\\kern1em\\mark\\char39}\\kern-.8em#1}}\n"); fprintf (macro_file,"\\def\\Sac#1{\\hskip.1pt\\hbox{\\raise1ex\\hbox{\\kern.6em\\char19}\\kern-.9em#1}}\n"); fprintf (macro_file,"\\def\\Huy#1{\\hskip.1pt\\hbox{\\raise1ex\\hbox{\\kern.6em\\char18}\\kern-.9em#1}}\n"); fprintf (macro_file,"\\def\\Hoi#1{\\hskip.01pt\\hbox{\\raise1.3ex\\hbox{\\kern.9em\\mark\\char39}\\kern-.8em#1}}\n"); fprintf (macro_file,"\\def\\Nga#1{\\hskip.1pt\\hbox{\\raise1.1ex\\hbox{\\kern.6em\\char126}\\kern-.9em#1}}\n"); fprintf (macro_file,"\n"); fprintf (macro_file,"\\def\\dd{\\kern.1em\\hbox{d\\raise.9ex\\hbox{\\kern-.3em -}}}\n"); fprintf (macro_file,"\\def\\DD{\\hskip.1pt\\hbox{D\\raise.3ex\\hbox{\\kern-.7em\\char45}\\kern.4em}}\n"); fprintf (macro_file,"\n"); fprintf (macro_file,"\\def\\uu{\\hbox{u\\raise.1ex\\hbox{\\kern-.22em\\mark\\char39}}}\n"); fprintf (macro_file,"\\def\\UU{\\hskip.1pt\\hbox{U\\raise.45ex\\hbox{\\kern-.3em\\char39}}}\n"); fprintf (macro_file,"\n"); fprintf (macro_file,"\\def\\oo{\\hbox{o\\hbox{\\kern-.15em\\mark\\char39}}}\n"); fprintf (macro_file,"\\def\\OO{\\hskip.1pt\\hbox{O\\raise.2ex\\hbox{\\kern-0.28em\\char39}}}\n"); fprintf (macro_file,"\n"); }