summaryrefslogtreecommitdiff
path: root/language/gurmukhi/singh/gurmukhi.c
diff options
context:
space:
mode:
Diffstat (limited to 'language/gurmukhi/singh/gurmukhi.c')
-rw-r--r--language/gurmukhi/singh/gurmukhi.c948
1 files changed, 948 insertions, 0 deletions
diff --git a/language/gurmukhi/singh/gurmukhi.c b/language/gurmukhi/singh/gurmukhi.c
new file mode 100644
index 0000000000..1d0319d605
--- /dev/null
+++ b/language/gurmukhi/singh/gurmukhi.c
@@ -0,0 +1,948 @@
+/* gurmukhi.c
+ Preprocessor for TeX for text containing Gurmukhi characters.
+
+ Author: Amarjit Singh
+ E-mail: asingh@evolving.com
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 1, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdio.h>
+#include <ctype.h>
+#define TRUE 1
+#define FALSE 0
+#define ILL_CHAR 29
+#define DUMMY 30
+#define END_OF_FILE 30
+#define END_OF_LINE 31
+#define N_NOLIGS 40
+/* ch_typ values */
+#define ILLEGAL 0
+#define CMR 1
+#define CONTROL 2
+#define GM 3
+#define NUMERAL 4
+/* ch_subtyp values */
+#define LO_VOWEL 0
+#define HI_VOWEL 1
+#define CONSONANT 2
+#define SPECIAL 3
+
+#define LBRACE 273
+#define RBRACE 264
+#define RE 263
+#define RN 265
+#define RS 256
+
+#define INBUF_LEN 133
+
+/* GLOBAL VARIABLES */
+FILE *f_in,*f_out,*fopen();
+
+short buf_length;
+short syll[30]; /* offset of syll is in chr_ptr or cons_ptr */
+short cons_ptr, chr_ptr;
+short cons_code;
+
+char *strchr();
+char wrong[10];
+char *p_in,*p_out,*s_ptr,*o_ptr;
+char infil[80], outfil[80];
+char inbuf[INBUF_LEN], outbuf[133];
+char word[500];
+
+unsigned char gm_mode, dollar_mode, cmr_mode;
+unsigned char d_found, no_gm, buf_ptr, wait_syl, lin_obey;
+unsigned char error, cons_seen, vow_seen;
+
+struct char_def {
+ short ch_typ, ch_subtyp, ch_code, ch_subcode;
+};
+
+struct char_def table[127] = {
+ {ILLEGAL,SPECIAL,0,0}, /* 1 not used */
+ {GM,CONSONANT,'\126',1}, /* 2 .t */
+ {GM,CONSONANT,'\130',2}, /* 3 .d */
+ {GM,SPECIAL,'\72',0}, /* 4 .o */
+ {GM,CONSONANT,'\132',3}, /* 5 .n */
+ {GM,CONSONANT,'\13',4}, /* 6 .g */
+ {GM,SPECIAL,'\24',0}, /* 7 .. */
+ {GM,CONSONANT,'\14',5}, /* 8 .K */
+ {GM,CONSONANT,'\127',6}, /* 9 .T */
+ {GM,CONSONANT,'\131',7}, /* 10 .D */
+ {GM,SPECIAL,'\54',0}, /* 11 .m */
+ {ILLEGAL,SPECIAL,0,0}, /* 12 not used */
+ {ILLEGAL,SPECIAL,0,0}, /* 13 not used */
+ {ILLEGAL,SPECIAL,0,0}, /* 14 not used */
+ {ILLEGAL,SPECIAL,0,0}, /* 15 not used */
+ {ILLEGAL,SPECIAL,0,0}, /* 16 not used */
+ {ILLEGAL,SPECIAL,0,0}, /* 17 not used */
+ {GM,CONSONANT,'\122',8}, /* 18 "n */
+ {GM,CONSONANT,'\146',9}, /* 19 "s */
+ {ILLEGAL,SPECIAL,0,0}, /* 20 not used */
+ {GM,CONSONANT,'\32', 10}, /* 21 ~n */
+ {GM,SPECIAL,'\137',0}, /* 22 ~a */
+ {ILLEGAL,SPECIAL,0,0}, /* 23 not used */
+ {ILLEGAL,SPECIAL,0,0}, /* 24 not used */
+ {GM,HI_VOWEL,275,'\106'}, /* 25 ii */
+ {GM,LO_VOWEL,274,1}, /* 26 uu */
+ {GM,HI_VOWEL,260,'\117'}, /* 27 oo */
+ {ILLEGAL,SPECIAL,0,0}, /* 28 not used */
+ {ILLEGAL,SPECIAL,0,0}, /* 29 not used */
+ {CONTROL,SPECIAL,0,0}, /* 30 DUMMY */
+ {CONTROL,SPECIAL,0,0}, /* 31 END_OF_LINE */
+ {CONTROL,SPECIAL,0,0}, /* 32 space */
+ {CMR,SPECIAL,0,0}, /* ! */
+ {ILLEGAL,SPECIAL,0,0}, /* " */
+ {ILLEGAL,SPECIAL,0,0}, /* # */
+ {ILLEGAL,SPECIAL,0,0}, /* $ */
+ {ILLEGAL,SPECIAL,0,0}, /* % */
+ {ILLEGAL,SPECIAL,0,0}, /* & */
+ {CMR,SPECIAL,0,0}, /* ' to - */
+ {CMR,SPECIAL,0,0}, /* ' to - */
+ {CMR,SPECIAL,0,0}, /* ' to - */
+ {CMR,SPECIAL,0,0}, /* ' to - */
+ {CMR,SPECIAL,0,0}, /* ' to - */
+ {CMR,SPECIAL,0,0}, /* ' to - */
+ {CMR,SPECIAL,0,0}, /* ' to - */
+ {ILLEGAL,SPECIAL,0,0}, /* . */
+ {GM,SPECIAL,'\40',0}, /* / */
+ {NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
+ {NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
+ {NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
+ {NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
+ {NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
+ {NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
+ {NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
+ {NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
+ {NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
+ {NUMERAL,SPECIAL,0,0}, /* 0 to 9 */
+ {CMR,SPECIAL,0,0}, /* : and ; */
+ {CMR,SPECIAL,0,0}, /* : and ; */
+ {ILLEGAL,SPECIAL,0,0}, /* < */
+ {CMR,SPECIAL,0,0}, /* = */
+ {ILLEGAL,SPECIAL,0,0}, /* > */
+ {CMR,SPECIAL,0,0}, /* ? */
+ {GM,SPECIAL,'\177',0}, /* @ */
+ {GM,HI_VOWEL,258,'\101'}, /* A */
+ {GM,CONSONANT,'\102',11}, /* B */
+ {GM,CONSONANT,'\103',12}, /* C */
+ {GM,CONSONANT,'\104',13}, /* D */
+ {GM,HI_VOWEL,259,'\173'}, /* E */
+ {ILLEGAL,SPECIAL,0,0}, /* F */
+ {GM,CONSONANT,'\107',14}, /* G */
+ {GM,SPECIAL,'\54',0}, /* H */
+ {GM,HI_VOWEL,267,'\106'}, /* I */
+ {GM,CONSONANT,'\112',15}, /* J */
+ {GM,CONSONANT,'\113',16}, /* K */
+ {ILLEGAL,SPECIAL,0,0}, /* L not used */
+ {GM,SPECIAL,'\54',0}, /* M */
+ {GM,SPECIAL,'\134',0}, /* N */
+ {GM,HI_VOWEL,261,'\117'}, /* O */
+ {GM,CONSONANT,'\120',17}, /* P */
+ {ILLEGAL,SPECIAL,0,0}, /* Q */
+ {GM,CONSONANT,'\167',18}, /* R */
+ {GM,CONSONANT,'\146',9}, /* S */
+ {GM,CONSONANT,'\124',19}, /* T */
+ {GM,LO_VOWEL,276,1}, /* U */
+ {ILLEGAL,SPECIAL,0,0}, /* V to Z */
+ {ILLEGAL,SPECIAL,0,0}, /* V to Z */
+ {ILLEGAL,SPECIAL,0,0}, /* V to Z */
+ {ILLEGAL,SPECIAL,0,0}, /* V to Z */
+ {ILLEGAL,SPECIAL,0,0}, /* V to Z */
+ {CMR,SPECIAL,0,0}, /* [ */
+ {CONTROL,SPECIAL,0,0}, /* \ */
+ {CMR,SPECIAL,0,0}, /* ] */
+ {ILLEGAL,SPECIAL,0,0}, /* ^ */
+ {ILLEGAL,SPECIAL,0,0}, /* _ */
+ {CMR,SPECIAL,0,0}, /* ` */
+ {GM,HI_VOWEL,'\141',257}, /* a */
+ {GM,CONSONANT,'\142',20}, /* b */
+ {GM,CONSONANT,'\143',21}, /* c */
+ {GM,CONSONANT,'\144',22}, /* d */
+ {GM,HI_VOWEL,262,3}, /* e */
+ {GM,CONSONANT,'\47',23}, /* f */
+ {GM,CONSONANT,'\147',24}, /* g */
+ {GM,CONSONANT,'\150',25}, /* h */
+ {GM,HI_VOWEL,'\151','\105'}, /* i */
+ {GM,CONSONANT,'\152',26}, /* j */
+ {GM,CONSONANT,'\153',27}, /* k */
+ {GM,CONSONANT,'\154',28}, /* l */
+ {GM,CONSONANT,'\155',29}, /* m */
+ {GM,CONSONANT,'\156',30}, /* n */
+ {GM,HI_VOWEL,'\33','\157'}, /* o */
+ {GM,CONSONANT,'\160',31}, /* p */
+ {ILLEGAL,SPECIAL,0,0}, /* not used */
+ {GM,CONSONANT,'\162',32}, /* r */
+ {GM,CONSONANT,'\163',33}, /* s */
+ {GM,CONSONANT,'\164',34}, /* t */
+ {GM,LO_VOWEL,'\165',0}, /* u */
+ {GM,CONSONANT,'\166',35}, /* v */
+ {ILLEGAL,SPECIAL,0,0}, /* not used */
+ {ILLEGAL,SPECIAL,0,0}, /* not used */
+ {GM,CONSONANT,'\171',36}, /* y */
+ {GM,CONSONANT,'\51',37}, /* z */
+ {CONTROL,SPECIAL,0,0}, /* left brace */
+ {GM,SPECIAL,'\56',0}, /* | */
+ {CONTROL,SPECIAL,0,0}, /* right brace */
+ {ILLEGAL,SPECIAL,0,0}, /* ~ */
+ {ILLEGAL,SPECIAL,0,0} /* del */
+};
+
+char chset1[12]= {'k','t','d','o','n','g','.','K','T','D','m',' '};/* . */
+char chset4[10]= {'k','g','c','j','t','d','p','b','s',' '}; /* h */
+char chset3[3] = {'n','s',' '}; /* " */
+char chset6[3] = {'n','a',' '}; /* ~ */
+char chset2[3] = {'a','i',' '}; /* a */
+char chset5[2] = {'A','E'}; /* result of aa and ai */
+
+char out_string[277][7] = {
+ "\\7{","\\8{","\\9{","\\?","\\<","^^E","^^F",
+ "^^G","^^H","^^I","^^J","^^K","^^L","\\0",
+ "\\qx{","^^O","^^P","^^Q","^^R",
+ "^^S","^^T","^^U","^^V","^^W","^^X",
+ "^^Y","^^Z","^^[","^^\\","^^]",
+ "^^^","\\qy{","\\1","!","\"","\\#","\\$",
+ "\\%","\\&","\'","(",")","*","+",",","-",".","/","0","1","2",
+ "3","4","5","6","7","8","9",":",";","<","=",">","?","@",
+ "A","B","C","D","E","F","G","H","I","J","K","L","M","N",
+ "O","P","Q","R","S","T","U","V","W","X","Y","Z","[","\\2",
+ "]","\\qq{","\\35Fw","`","a","b","c","d","e","f","g","h","i","j",
+ "k","l","m","n","o","p","q","r","s","t","u","v","w","x",
+ "y","z","\\4","\\qz{","\\5","\\6{","^^?",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","","","","",
+ "","","{\\rs ","","aA","a\\4",
+ "ao","aO","a\\?","\\re}","}","\\rn{",
+ "{\\rdt}","iF","{\\qva}","{\\qvb}","{\\qvc}",
+ "\\qa{","\\qb{","{", "\\7{u}","Ei", "\\8{u}"
+};
+
+/* strstr : to make it portable */
+char *st_find(s,q)
+char *s, *q;
+{
+ short i,j,k,l;
+ j = strlen(s);
+ k = strlen(q);
+ for (i=0; i <= j-k; i++) {
+ if (s[i]==q[0]) {
+ for (l = 1; (s[i + l] == q[l]) && (q[l] != '\0'); l++) ;
+ if (q[l] == '\0') return(&s[i]);
+ }
+ }
+ return(NULL);
+}
+
+/* strchr : to make it portable */
+char *ch_find(s,q)
+char *s;
+char q;
+{
+ short i,j;
+ j = strlen(s);
+ for (i=0; i < j; i++)
+ if (s[i]==q) return(&s[i]);
+ return(NULL);
+}
+
+err_ill(str)
+char *str;
+{
+ printf("Error: illegal character(s): %s\n",str);
+ puts(inbuf);
+ getchar();
+ error = TRUE;
+}
+
+/* Find {\gm in inbuf, copy everything till {\gm to outbuf */
+/* and modify rest of it back to inbuf */
+/* RETURN : TRUE if inbuf is valid */
+/* FALSE otherwise */
+/* other ouputs : no_gm */
+/* d_found */
+char find_gm()
+{
+ char *d_ptr;
+ char *gm_ptr;
+ char *svbuf;
+ char again;
+
+ d_found = FALSE;
+ svbuf = inbuf;
+ do {
+ again = FALSE;
+ gm_ptr = st_find(svbuf,"{\\gm");
+ if (gm_ptr != NULL) {
+ again = isalpha(gm_ptr[4]);
+ svbuf = gm_ptr + 4;
+ }
+ } while(again);
+
+ if (dollar_mode) {
+ d_ptr = ch_find(inbuf,'$');
+ if ((d_ptr != NULL) && ((gm_ptr == NULL) || (d_ptr < gm_ptr))) {
+ d_found = TRUE;
+ gm_ptr = d_ptr;
+ }
+ }
+
+ if (gm_ptr == NULL)
+ return(FALSE);
+ strncat(outbuf,inbuf,gm_ptr-inbuf);
+ no_gm = FALSE;
+ if (!d_found) {
+ if (gm_ptr[4] == '#') {
+ no_gm = TRUE;
+ gm_ptr += 1;
+ } else {
+ strcat(outbuf,"{\\gm");
+ }
+ gm_ptr += 4;
+ } else {
+ switch(dollar_mode) {
+ case 1: strcat(outbuf,"{\\gm ");
+ break;
+ case 2: strcat(outbuf,"\\pgm ");
+ case 3: no_gm = TRUE;
+ }
+ gm_ptr += 1;
+ }
+ strcpy(inbuf,gm_ptr);
+ return(TRUE);
+}
+
+/* Returns one char from "inbuf" at "buf_ptr" */
+/* if inbuf is at END_OF_LINE then refills it from "f_in" */
+/* other inputs : p_in */
+/* other outputs: p_in, buf_length */
+char inp_ch()
+{
+ char ch, ch_out;
+ ch = inbuf[buf_ptr++];
+ if (ch == '\n') {
+ if (p_in == 0)
+ ch_out = END_OF_FILE;
+ else {
+ p_in = fgets(inbuf,INBUF_LEN,f_in);
+ buf_ptr = 0;
+ buf_length = strlen(inbuf);
+ ch_out = END_OF_LINE;
+ }
+ } else {
+ if (ch < 32)
+ ch_out = ILL_CHAR;
+ else
+ ch_out = ch;
+ }
+ return(ch_out);
+}
+
+put_macro(macro)
+short macro;
+{
+ char tmp[5];
+ int l, i;
+ if (syll[chr_ptr-1] == '\175') {
+ syll[chr_ptr+1] = '\175';
+ syll[chr_ptr] = RBRACE;
+ syll[chr_ptr-1] = syll[chr_ptr-2];
+ syll[chr_ptr-2] = macro;
+ chr_ptr += 2;
+ } else if (syll[chr_ptr-1]==RBRACE) {
+ syll[chr_ptr-3] = 271;
+ syll[chr_ptr] = LBRACE;
+ sprintf(tmp,"%d",macro);
+ l = strlen(tmp);
+ chr_ptr += 1;
+ for (i = 0; i < l; i++)
+ syll[chr_ptr+i] = tmp[i];
+ chr_ptr += l;
+ syll[chr_ptr] = RBRACE;
+ chr_ptr += 1;
+ } else {
+ syll[chr_ptr] = syll[chr_ptr-1];
+ syll[chr_ptr-1] = macro;
+ syll[chr_ptr+1] = RBRACE;
+ chr_ptr = chr_ptr +2;
+ }
+}
+
+/* find out string corresponding to chars in syll */
+/* and then move to word. */
+/* Reset related flags */
+put_syll()
+{
+ short i;
+ for (i = 0; i <= (chr_ptr-1); i++)
+ strcat(word,&out_string[syll[i]][0]);
+ chr_ptr = 0;
+ cons_seen =FALSE;
+ vow_seen =FALSE;
+ wait_syl = FALSE;
+}
+
+/* puts out string for one code ( or char ) in word */
+put_sym(code)
+short code;
+{
+ strcat(word,&out_string[code][0]);
+}
+
+/* move word to outbuf */
+/* if not lin_obey then
+ put outnuf in f_out
+ keep moving word to outbuf to f_out till
+ len of word is bigger than 80
+ At end of this routine outbuf may have a valid string
+*/
+put_word()
+{
+ short lw,lb;
+ lw = strlen(word);
+ lb = strlen(outbuf);
+ if (((lb + lw) > 80) && !lin_obey)
+ {
+ if (lb > 1)
+ {
+ if (outbuf[lb-1] != ' ')
+ strcat(outbuf,"%\n");
+ else
+ outbuf[lb-1] = '\n';
+ fputs(outbuf,f_out);
+ }
+ while (lw > 80)
+ {
+ strncpy(outbuf,word,79);
+ outbuf[79] = '\0';
+ strcat(outbuf,"%\n");
+ fputs(outbuf,f_out);
+ strcpy(word,&word[79]);
+ lw = strlen(word);
+ }
+ strcpy(outbuf,word);
+ }
+ else
+ strcat(outbuf,word);
+ strcpy(word,"");
+}
+
+/* copies c to word and */
+/* if c is space then outputs a word */
+sendchar(c)
+char c;
+{
+ char cstr[2];
+ cstr[0] = c;
+ cstr[1] = '\0';
+ strcat(word,cstr);
+ if (isspace(c))
+ put_word();
+}
+
+put_ch(code)
+short code;
+{
+ struct char_def *c_ptr;
+ short i;
+
+ c_ptr = &table[code-1];
+ switch(c_ptr->ch_typ) {
+ case GM:
+ if (cmr_mode) {
+ cmr_mode = FALSE;
+ put_sym(RE);
+ }
+ switch(c_ptr->ch_subtyp) {
+ case HI_VOWEL:
+ if (wait_syl)
+ put_syll();
+ if (cons_seen) {
+ if (code == 'i') {
+ for (i = chr_ptr; i>= (cons_ptr+1); i--)
+ syll[i] = syll[i-1];
+ syll[cons_ptr] = c_ptr->ch_subcode;
+ } else {
+ syll[chr_ptr] = c_ptr->ch_subcode;
+ if ((code != 'A') && (code != 'a'))
+ vow_seen = TRUE;
+ }
+ } else
+ syll[chr_ptr] = c_ptr->ch_code;
+ chr_ptr = chr_ptr + 1;
+ wait_syl = TRUE;
+ cons_seen = FALSE;
+ break;
+ case LO_VOWEL:
+ if (wait_syl)
+ put_syll();
+ if (cons_seen)
+ {
+ put_macro(c_ptr->ch_subcode);
+ chr_ptr = chr_ptr - 1;
+ }
+ else
+ syll[chr_ptr] = c_ptr->ch_code;
+ chr_ptr = chr_ptr + 1;
+ wait_syl = TRUE;
+ cons_seen = FALSE;
+ break;
+ case CONSONANT:
+ if (wait_syl)
+ put_syll();
+ if (!cons_seen) {
+ cons_seen = TRUE;
+ cons_ptr = chr_ptr;
+ cons_code = c_ptr->ch_subcode;
+ syll[chr_ptr] = c_ptr->ch_code;
+ chr_ptr += 1;
+ } else {
+ if (code == 'r') {
+ syll[chr_ptr] = '\175';
+ chr_ptr = chr_ptr + 1;
+ cons_code = 0;
+ } else if (code == 'h') {
+ syll[chr_ptr] = '\110';
+ chr_ptr = chr_ptr + 1;
+ cons_code = 0;
+ } else if (code == 'v') {
+ syll[chr_ptr] = '\46';
+ chr_ptr = chr_ptr + 1;
+ cons_code = 0;
+ } else {
+ cons_code = c_ptr->ch_subcode;
+ syll[chr_ptr] = c_ptr->ch_code;
+ chr_ptr += 1;
+ }
+ }
+ break;
+
+ case SPECIAL:
+ put_syll();
+ put_sym(c_ptr->ch_code);
+ }
+ break;
+
+ case ILLEGAL:
+ wrong[0] = code; wrong[1] = '\0';
+ err_ill(wrong);
+ break;
+
+ case CONTROL:
+ if (cmr_mode) {
+ cmr_mode = FALSE;
+ put_sym(RE);
+ } else {
+ put_syll();
+ }
+ if (code == END_OF_LINE) {
+ put_word();
+ strcat(outbuf,"\n");
+ fputs(outbuf,f_out);
+ strcpy(outbuf,"");
+ if (!lin_obey)
+ fputs("\n",f_out);
+ } else if (code != DUMMY)
+ sendchar(code);
+ break;
+
+ case CMR:
+ if (cmr_mode)
+ sendchar(code);
+ else {
+ cmr_mode = TRUE;
+ put_syll();
+ put_sym(RS);
+ sendchar(code);
+ }
+ break;
+
+ case NUMERAL:
+ sendchar(code);
+ break;
+ } /* end of switch on ch_typ */
+}
+
+/* This routine resolves the combination of charaters */
+/* used to symbolize font characters */
+/* i.e. it cooks set of input chars to one offset in "table" */
+gmproc(symbol)
+char symbol;
+{
+ unsigned char saved,gmready;
+ short brace_lev;
+ char savchr;
+ short i;
+
+ brace_lev = 1;
+ saved = FALSE;
+ gmready = FALSE;
+ do {
+ switch(symbol) {
+ case '.':
+ savchr = inp_ch();
+ i = 0;
+ do {
+ i++;
+ } while ((i != 12) && (chset1[i-1] != savchr));
+ if (i == 12) {
+ wrong[0] = '.';
+ wrong[1] = savchr;
+ wrong[2] = '\0';
+ err_ill(wrong);
+ } else if (i < 4) {
+ savchr = inp_ch();
+ if (savchr == 'h')
+ i = i+7;
+ else {
+ saved = TRUE;
+ if (i == 1)
+ err_ill(".k");
+ }
+ }
+ if (!error) {
+ if (i == 11)
+ put_ch('M');
+ else
+ put_ch(i);
+ }
+ break;
+ case 'i':
+ savchr = inp_ch();
+ if (savchr == 'i')
+ put_ch(25);
+ else {
+ put_ch(symbol);
+ saved = TRUE;
+ }
+ break;
+ case 'u':
+ savchr = inp_ch();
+ if (savchr == 'u')
+ put_ch(26);
+ else {
+ put_ch(symbol);
+ saved = TRUE;
+ }
+ break;
+ case 'o':
+ savchr = inp_ch();
+ if (savchr == 'o')
+ put_ch(27);
+ else {
+ put_ch(symbol);
+ saved = TRUE;
+ }
+ break;
+ case 'a':
+ savchr = inp_ch();
+ i = 0;
+ do {
+ i++;
+ } while ((i != 3) && (chset2[i-1] != savchr));
+ if (i == 3)
+ {
+ put_ch(symbol);
+ saved = TRUE;
+ } else
+ put_ch(chset5[i-1]);
+ break;
+
+ case '\"':
+ savchr = inp_ch();
+ i = 0;
+ do {
+ i++;
+ } while ((i != 3) && (chset3[i-1] != savchr));
+ if (i == 3) {
+ wrong[0] = '~';
+ wrong[1] = savchr;
+ wrong[2] = '\0';
+ err_ill(wrong);
+ } else
+ put_ch(i+17);
+ break;
+
+ case '~':
+ savchr = inp_ch();
+ i = 0;
+ do {
+ i++;
+ } while ((i != 3) && (chset6[i-1] != savchr));
+ if (i == 3) {
+ wrong[0] = '~';
+ wrong[1] = savchr;
+ wrong[2] = '\0';
+ err_ill(wrong);
+ } else
+ put_ch(i+20);
+ break;
+
+ case END_OF_LINE:
+ if (lin_obey) {
+ put_ch(END_OF_LINE);
+ put_ch(END_OF_LINE);
+ } else {
+ do {
+ savchr = inp_ch();
+ } while (savchr == ' ');
+ if (savchr == END_OF_LINE)
+ put_ch(END_OF_LINE);
+ else {
+ put_ch(' ');
+ saved = TRUE;
+ }
+ }
+ break;
+
+ case '$':
+ if (!dollar_mode)
+ put_ch(symbol);
+ else {
+ if (no_gm)
+ put_ch(DUMMY);
+ else
+ put_ch('}');
+ gmready= TRUE;
+ put_word();
+ strcpy(inbuf,&inbuf[buf_ptr]);
+ }
+ break;
+
+ case '}':
+ brace_lev = brace_lev-1;
+ if ((brace_lev == 0) && !d_found) {
+ if (no_gm)
+ put_ch(DUMMY);
+ else
+ put_ch(symbol);
+ gmready= TRUE;
+ put_word();
+ strcpy(inbuf,&inbuf[buf_ptr]);
+ } else
+ put_ch(symbol);
+ break;
+
+ case '{':
+ put_ch(symbol);
+ brace_lev = brace_lev+1;
+ break;
+
+ case '%': do
+ symbol = inp_ch();
+ while(symbol != END_OF_LINE);
+ break;
+
+ case '\\':
+ put_ch(symbol);
+ symbol = inp_ch();
+ if (symbol == END_OF_LINE) {
+ put_word();
+ strcat(outbuf,"\n");
+ fputs(outbuf,f_out);
+ strcpy(outbuf,"");
+ } else {
+ if (!isalnum(symbol))
+ sendchar(symbol);
+ else {
+ do {
+ sendchar(symbol);
+ symbol = inp_ch();
+ } while (isalnum(symbol));
+ savchr = symbol;
+ saved = TRUE;
+ }
+ }
+ break;
+
+ case ILL_CHAR: err_ill('\0');
+ break;
+
+ case END_OF_FILE:
+ puts("error: missing }");
+ error = TRUE;
+ break;
+
+ default:
+ i = 0;
+ do {
+ i++;
+ } while ((i != 10) && (chset4[i-1] != symbol));
+ if (i == 10)
+ put_ch(symbol);
+ else {
+ savchr = inp_ch();
+ if (savchr == 'h') {
+ put_ch(symbol-32);
+ } else {
+ put_ch(symbol);
+ saved = TRUE;
+ }
+ }
+ break;
+ } /* end of switch */
+ if (saved) {
+ symbol = savchr;
+ saved = FALSE;
+ } else if ((!error) && (!gmready)) {
+ symbol = inp_ch();
+ }
+ } while (!error && !gmready);
+}
+
+main(argc,argv)
+int argc;
+char *argv[];
+{
+ unsigned char gm_yes;
+ /* get file specifications */
+
+ if (argc == 3) {
+ strcpy(infil,argv[1]);
+ strcpy(outfil,argv[2]);
+ } else if (argc == 2) {
+ strcpy(infil,argv[1]);
+ strcpy(outfil,"");
+ } else {
+ do {
+ printf("input file: ");
+ gets(infil);
+ } while (strlen(infil) == 0);
+ printf("output file: ");
+ gets(outfil);
+ }
+ s_ptr = strchr(infil,'.');
+ if (strlen(outfil) == 0) {
+ strcpy(outfil,infil);
+ o_ptr = strchr(outfil,'.');
+ if (o_ptr != 0)
+ *o_ptr = '\0';
+ }
+ if (s_ptr == 0)
+ strcat(infil,".gm");
+ o_ptr = strchr(outfil,'.');
+ if (o_ptr == 0)
+ strcat(outfil,".tex");
+
+ /* open files */
+
+ if ((f_in = fopen(infil,"r")) == NULL) {
+ printf("cannot open file %s\n",infil);
+ exit(1);
+ }
+ if ((f_out = fopen(outfil,"w")) == NULL) {
+ printf("cannot open file %s\n",infil);
+ exit(1);
+ }
+
+ /* initialization */
+
+ error = FALSE;
+ cons_seen = FALSE;
+ vow_seen = FALSE;
+ wait_syl = FALSE;
+
+ cmr_mode = FALSE;
+ gm_mode = TRUE;
+ lin_obey = FALSE;
+ dollar_mode = 0;
+
+ chr_ptr = 0;
+ strcpy(word,"");
+ strcpy(outbuf,"");
+
+ /* read preprocessor commands */
+
+ while (TRUE) {
+ strcpy(inbuf,"");
+ p_in = fgets(inbuf,INBUF_LEN,f_in);
+ if (inbuf[0] != '@')
+ break;
+ while (TRUE) {
+ if (st_find(inbuf,"dollars") == &inbuf[1]) {
+ dollar_mode = 1;
+ break;
+ }
+ if (st_find(inbuf,"punjabi") == &inbuf[1]) {
+ /* reserved for hindi & pujabi merger */
+ break;
+ }
+ if (st_find(inbuf,"obeylines") == &inbuf[1]) {
+ lin_obey = TRUE;
+ break;
+ }
+ if (st_find(inbuf,"dolmode1") == &inbuf[1]) {
+ dollar_mode = 1;
+ break;
+ }
+ if (st_find(inbuf,"dolmode2") == &inbuf[1]) {
+ dollar_mode = 2;
+ break;
+ }
+ if (st_find(inbuf,"dolmode3") == &inbuf[1]) {
+ dollar_mode = 3;
+ break;
+ }
+ printf("Error: illegal preprocessor command\n");
+ puts(inbuf);
+ getchar();
+ break;
+ }
+ }
+
+ /* main loop */
+
+ do {
+ if (!find_gm())
+ fputs(inbuf,f_out);
+ else {
+ do {
+ buf_length = strlen(inbuf);
+ buf_ptr = 0;
+ gmproc(inp_ch());
+ if (!error)
+ gm_yes = find_gm();
+ if (!gm_yes) {
+ strcat(outbuf,inbuf);
+ fputs(outbuf,f_out);
+ }
+ } while (gm_yes && !error);
+ }
+ strcpy(inbuf,"");
+ p_in = fgets(inbuf,INBUF_LEN,f_in);
+ strcpy(outbuf,"");
+ } while ((p_in != NULL) && !error);
+ fclose(f_in);
+ fclose(f_out);
+}