xref: /plan9/sys/src/cmd/deroff.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
43e12c5d1SDavid du Colombier 
53e12c5d1SDavid du Colombier /*
63e12c5d1SDavid du Colombier  * Deroff command -- strip troff, eqn, and tbl sequences from
73e12c5d1SDavid du Colombier  * a file.  Has three flags argument, -w, to cause output one word per line
83e12c5d1SDavid du Colombier  * rather than in the original format.
93e12c5d1SDavid du Colombier  * -mm (or -ms) causes the corresponding macro's to be interpreted
103e12c5d1SDavid du Colombier  * so that just sentences are output
113e12c5d1SDavid du Colombier  * -ml  also gets rid of lists.
123e12c5d1SDavid du Colombier  * -i causes deroff to ignore .so and .nx commands.
133e12c5d1SDavid du Colombier  * Deroff follows .so and .nx commands, removes contents of macro
143e12c5d1SDavid du Colombier  * definitions, equations (both .EQ ... .EN and $...$),
153e12c5d1SDavid du Colombier  * Tbl command sequences, and Troff backslash vconstructions.
163e12c5d1SDavid du Colombier  *
173e12c5d1SDavid du Colombier  * All input is through the C macro; the most recently read character is in c.
183e12c5d1SDavid du Colombier  */
193e12c5d1SDavid du Colombier 
203e12c5d1SDavid du Colombier #define	C	((c = Bgetrune(infile)) < 0?\
213e12c5d1SDavid du Colombier 			eof():\
223e12c5d1SDavid du Colombier 			((c == ldelim) && (filesp == files)?\
233e12c5d1SDavid du Colombier 				skeqn():\
243e12c5d1SDavid du Colombier 				(c == '\n'?\
253e12c5d1SDavid du Colombier 					(linect++,c):\
263e12c5d1SDavid du Colombier 						c)))
273e12c5d1SDavid du Colombier #define	C1	((c = Bgetrune(infile)) == Beof?\
283e12c5d1SDavid du Colombier 			eof():\
293e12c5d1SDavid du Colombier 			(c == '\n'?\
303e12c5d1SDavid du Colombier 				(linect++,c):\
313e12c5d1SDavid du Colombier 				c))
323e12c5d1SDavid du Colombier #define	SKIP	while(C != '\n')
333e12c5d1SDavid du Colombier #define SKIP1	while(C1 != '\n')
343e12c5d1SDavid du Colombier #define SKIP_TO_COM		SKIP;\
353e12c5d1SDavid du Colombier 				SKIP;\
363e12c5d1SDavid du Colombier 				pc=c;\
373e12c5d1SDavid du Colombier 				while(C != '.' || pc != '\n' || C > 'Z')\
383e12c5d1SDavid du Colombier 						pc=c
393e12c5d1SDavid du Colombier 
403e12c5d1SDavid du Colombier #define YES		1
413e12c5d1SDavid du Colombier #define NO		0
423e12c5d1SDavid du Colombier #define MS		0
433e12c5d1SDavid du Colombier #define MM		1
443e12c5d1SDavid du Colombier #define ONE		1
453e12c5d1SDavid du Colombier #define TWO		2
463e12c5d1SDavid du Colombier 
473e12c5d1SDavid du Colombier #define NOCHAR		-2
483e12c5d1SDavid du Colombier #define	EXTENDED	-1		/* All runes above 0x7F */
493e12c5d1SDavid du Colombier #define SPECIAL		0
503e12c5d1SDavid du Colombier #define APOS		1
513e12c5d1SDavid du Colombier #define PUNCT		2
523e12c5d1SDavid du Colombier #define DIGIT		3
533e12c5d1SDavid du Colombier #define LETTER		4
543e12c5d1SDavid du Colombier 
553e12c5d1SDavid du Colombier 
563e12c5d1SDavid du Colombier int	linect	= 0;
573e12c5d1SDavid du Colombier int	wordflag= NO;
583e12c5d1SDavid du Colombier int	msflag	= NO;
593e12c5d1SDavid du Colombier int	iflag	= NO;
603e12c5d1SDavid du Colombier int	mac	= MM;
613e12c5d1SDavid du Colombier int	disp	= 0;
623e12c5d1SDavid du Colombier int	inmacro	= NO;
633e12c5d1SDavid du Colombier int	intable	= NO;
643e12c5d1SDavid du Colombier int	eqnflag	= 0;
653e12c5d1SDavid du Colombier 
663e12c5d1SDavid du Colombier #define	MAX_ASCII	0X80
673e12c5d1SDavid du Colombier #define	CHARCLASS(c)	((c) >= MAX_ASCII ? EXTENDED : chars[(c)])
683e12c5d1SDavid du Colombier 
693e12c5d1SDavid du Colombier char	chars[MAX_ASCII];	/* SPECIAL, PUNCT, APOS, DIGIT, or LETTER */
703e12c5d1SDavid du Colombier 
71bd389b36SDavid du Colombier Rune	line[4096];
723e12c5d1SDavid du Colombier Rune*	lp;
733e12c5d1SDavid du Colombier 
743e12c5d1SDavid du Colombier long	c;
753e12c5d1SDavid du Colombier long	pc;
763e12c5d1SDavid du Colombier int	ldelim	= NOCHAR;
773e12c5d1SDavid du Colombier int	rdelim	= NOCHAR;
783e12c5d1SDavid du Colombier 
793e12c5d1SDavid du Colombier 
803e12c5d1SDavid du Colombier char**	argv;
813e12c5d1SDavid du Colombier 
823e12c5d1SDavid du Colombier char	fname[50];
833e12c5d1SDavid du Colombier Biobuf*	files[15];
843e12c5d1SDavid du Colombier Biobuf**filesp;
853e12c5d1SDavid du Colombier Biobuf*	infile;
863e12c5d1SDavid du Colombier char*	devnull	= "/dev/null";
873e12c5d1SDavid du Colombier Biobuf	*infile;
883e12c5d1SDavid du Colombier Biobuf	bout;
893e12c5d1SDavid du Colombier 
903e12c5d1SDavid du Colombier long	skeqn(void);
913e12c5d1SDavid du Colombier Biobuf*	opn(char *p);
923e12c5d1SDavid du Colombier int	eof(void);
933e12c5d1SDavid du Colombier void	getfname(void);
943e12c5d1SDavid du Colombier void	fatal(char *s, char *p);
953e12c5d1SDavid du Colombier void	usage(void);
963e12c5d1SDavid du Colombier void	work(void);
973e12c5d1SDavid du Colombier void	putmac(Rune *rp, int vconst);
983e12c5d1SDavid du Colombier void	regline(int macline, int vconst);
993e12c5d1SDavid du Colombier void	putwords(void);
1003e12c5d1SDavid du Colombier void	comline(void);
1013e12c5d1SDavid du Colombier void	macro(void);
1023e12c5d1SDavid du Colombier void	eqn(void);
1033e12c5d1SDavid du Colombier void	tbl(void);
1043e12c5d1SDavid du Colombier void	stbl(void);
1053e12c5d1SDavid du Colombier void	sdis(char a1, char a2);
1063e12c5d1SDavid du Colombier void	sce(void);
1073e12c5d1SDavid du Colombier void	backsl(void);
1083e12c5d1SDavid du Colombier char*	copys(char *s);
1093e12c5d1SDavid du Colombier void	refer(int c1);
1103e12c5d1SDavid du Colombier void	inpic(void);
1113e12c5d1SDavid du Colombier 
1123e12c5d1SDavid du Colombier void
1133e12c5d1SDavid du Colombier main(int argc, char *av[])
1143e12c5d1SDavid du Colombier {
1153e12c5d1SDavid du Colombier 	int i;
1163e12c5d1SDavid du Colombier 	char *f;
1173e12c5d1SDavid du Colombier 
1183e12c5d1SDavid du Colombier 	argv = av;
1193e12c5d1SDavid du Colombier 	Binit(&bout, 1, OWRITE);
1203e12c5d1SDavid du Colombier 	ARGBEGIN{
1213e12c5d1SDavid du Colombier 	case 'w':
1223e12c5d1SDavid du Colombier 		wordflag = YES;
1233e12c5d1SDavid du Colombier 		break;
1243e12c5d1SDavid du Colombier 	case 'm':
1253e12c5d1SDavid du Colombier 		msflag = YES;
1263e12c5d1SDavid du Colombier 		if(f = ARGF())
1273e12c5d1SDavid du Colombier 			switch(*f)
1283e12c5d1SDavid du Colombier 			{
1293e12c5d1SDavid du Colombier 			case 'm':	mac = MM; break;
1303e12c5d1SDavid du Colombier 			case 's':	mac = MS; break;
1313e12c5d1SDavid du Colombier 			case 'l':	disp = 1; break;
1323e12c5d1SDavid du Colombier 			default:	usage();
1333e12c5d1SDavid du Colombier 			}
1343e12c5d1SDavid du Colombier 		else
1353e12c5d1SDavid du Colombier 			usage();
1363e12c5d1SDavid du Colombier 		break;
1373e12c5d1SDavid du Colombier 	case 'i':
1383e12c5d1SDavid du Colombier 		iflag = YES;
1393e12c5d1SDavid du Colombier 		break;
1403e12c5d1SDavid du Colombier 	default:
1413e12c5d1SDavid du Colombier 		usage();
1423e12c5d1SDavid du Colombier 	}ARGEND
1433e12c5d1SDavid du Colombier 	if(*argv)
1443e12c5d1SDavid du Colombier 		infile = opn(*argv++);
1453e12c5d1SDavid du Colombier 	else{
1463e12c5d1SDavid du Colombier 		infile = malloc(sizeof(Biobuf));
1473e12c5d1SDavid du Colombier 		Binit(infile, 0, OREAD);
1483e12c5d1SDavid du Colombier 	}
1493e12c5d1SDavid du Colombier 	files[0] = infile;
1503e12c5d1SDavid du Colombier 	filesp = &files[0];
1513e12c5d1SDavid du Colombier 
1523e12c5d1SDavid du Colombier 	for(i='a'; i<='z' ; ++i)
1533e12c5d1SDavid du Colombier 		chars[i] = LETTER;
1543e12c5d1SDavid du Colombier 	for(i='A'; i<='Z'; ++i)
1553e12c5d1SDavid du Colombier 		chars[i] = LETTER;
1563e12c5d1SDavid du Colombier 	for(i='0'; i<='9'; ++i)
1573e12c5d1SDavid du Colombier 		chars[i] = DIGIT;
1583e12c5d1SDavid du Colombier 	chars['\''] = APOS;
1593e12c5d1SDavid du Colombier 	chars['&'] = APOS;
1603e12c5d1SDavid du Colombier 	chars['\b'] = APOS;
1613e12c5d1SDavid du Colombier 	chars['.'] = PUNCT;
1623e12c5d1SDavid du Colombier 	chars[','] = PUNCT;
1633e12c5d1SDavid du Colombier 	chars[';'] = PUNCT;
1643e12c5d1SDavid du Colombier 	chars['?'] = PUNCT;
1653e12c5d1SDavid du Colombier 	chars[':'] = PUNCT;
1663e12c5d1SDavid du Colombier 	work();
1673e12c5d1SDavid du Colombier }
1683e12c5d1SDavid du Colombier 
1693e12c5d1SDavid du Colombier long
1703e12c5d1SDavid du Colombier skeqn(void)
1713e12c5d1SDavid du Colombier {
1723e12c5d1SDavid du Colombier 	while(C1 != rdelim)
1733e12c5d1SDavid du Colombier 		if(c == '\\')
1743e12c5d1SDavid du Colombier 			c = C1;
1753e12c5d1SDavid du Colombier 		else if(c == '"')
1763e12c5d1SDavid du Colombier 			while(C1 != '"')
1773e12c5d1SDavid du Colombier 				if(c == '\\')
1783e12c5d1SDavid du Colombier 					C1;
1793e12c5d1SDavid du Colombier 	if (msflag)
1803e12c5d1SDavid du Colombier 		eqnflag = 1;
1813e12c5d1SDavid du Colombier 	return(c = ' ');
1823e12c5d1SDavid du Colombier }
1833e12c5d1SDavid du Colombier 
1843e12c5d1SDavid du Colombier Biobuf*
1853e12c5d1SDavid du Colombier opn(char *p)
1863e12c5d1SDavid du Colombier {
1873e12c5d1SDavid du Colombier 	Biobuf *fd;
1883e12c5d1SDavid du Colombier 
1893e12c5d1SDavid du Colombier 	while ((fd = Bopen(p, OREAD)) == 0) {
1903e12c5d1SDavid du Colombier 		if(msflag || p == devnull)
1913e12c5d1SDavid du Colombier 			fatal("Cannot open file %s - quitting\n", p);
1923e12c5d1SDavid du Colombier 		else {
1933e12c5d1SDavid du Colombier 			fprint(2, "Deroff: Cannot open file %s - continuing\n", p);
1943e12c5d1SDavid du Colombier 			p = devnull;
1953e12c5d1SDavid du Colombier 		}
1963e12c5d1SDavid du Colombier 	}
1973e12c5d1SDavid du Colombier 	linect = 0;
1983e12c5d1SDavid du Colombier 	return(fd);
1993e12c5d1SDavid du Colombier }
2003e12c5d1SDavid du Colombier 
2013e12c5d1SDavid du Colombier int
2023e12c5d1SDavid du Colombier eof(void)
2033e12c5d1SDavid du Colombier {
2043e12c5d1SDavid du Colombier 	if(Bfildes(infile) != 0)
205*219b2ee8SDavid du Colombier 		Bterm(infile);
2063e12c5d1SDavid du Colombier 	if(filesp > files)
2073e12c5d1SDavid du Colombier 		infile = *--filesp;
2083e12c5d1SDavid du Colombier 	else
2093e12c5d1SDavid du Colombier 	if(*argv)
2103e12c5d1SDavid du Colombier 		infile = opn(*argv++);
2113e12c5d1SDavid du Colombier 	else
2123e12c5d1SDavid du Colombier 		exits(0);
2133e12c5d1SDavid du Colombier 	return(C);
2143e12c5d1SDavid du Colombier }
2153e12c5d1SDavid du Colombier 
2163e12c5d1SDavid du Colombier void
2173e12c5d1SDavid du Colombier getfname(void)
2183e12c5d1SDavid du Colombier {
2193e12c5d1SDavid du Colombier 	char *p;
2203e12c5d1SDavid du Colombier 	Rune r;
2213e12c5d1SDavid du Colombier 	Dir dir;
2223e12c5d1SDavid du Colombier 	struct chain
2233e12c5d1SDavid du Colombier 	{
2243e12c5d1SDavid du Colombier 		struct	chain*	nextp;
2253e12c5d1SDavid du Colombier 		char*	datap;
2263e12c5d1SDavid du Colombier 	} *q;
2273e12c5d1SDavid du Colombier 
2283e12c5d1SDavid du Colombier 	static struct chain *namechain= 0;
2293e12c5d1SDavid du Colombier 
2303e12c5d1SDavid du Colombier 	while(C == ' ')
2313e12c5d1SDavid du Colombier 		;
2323e12c5d1SDavid du Colombier 	for(p = fname; (r=c) != '\n' && r != ' ' && r != '\t' && r != '\\'; C)
2333e12c5d1SDavid du Colombier 		p += runetochar(p, &r);
2343e12c5d1SDavid du Colombier 	*p = '\0';
2353e12c5d1SDavid du Colombier 	while(c != '\n')
2363e12c5d1SDavid du Colombier 		C;
2373e12c5d1SDavid du Colombier 	if(!strcmp(fname, "/sys/lib/tmac/tmac.cs")
2383e12c5d1SDavid du Colombier 			|| !strcmp(fname, "/sys/lib/tmac/tmac.s")) {
2393e12c5d1SDavid du Colombier 		fname[0] = '\0';
2403e12c5d1SDavid du Colombier 		return;
2413e12c5d1SDavid du Colombier 	}
2423e12c5d1SDavid du Colombier 	if(dirstat(fname, &dir) >= 0 && ((dir.mode & CHDIR) || dir.type != 'M')) {
2433e12c5d1SDavid du Colombier 		fname[0] = '\0';
2443e12c5d1SDavid du Colombier 		return;
2453e12c5d1SDavid du Colombier 	}
2463e12c5d1SDavid du Colombier 	/*
2473e12c5d1SDavid du Colombier 	 * see if this name has already been used
2483e12c5d1SDavid du Colombier 	 */
2493e12c5d1SDavid du Colombier 
2503e12c5d1SDavid du Colombier 	for(q = namechain; q; q = q->nextp)
2513e12c5d1SDavid du Colombier 		if( !strcmp(fname, q->datap)) {
2523e12c5d1SDavid du Colombier 			fname[0] = '\0';
2533e12c5d1SDavid du Colombier 			return;
2543e12c5d1SDavid du Colombier 		}
2553e12c5d1SDavid du Colombier 	q = (struct chain*)malloc(sizeof(struct chain));
2563e12c5d1SDavid du Colombier 	q->nextp = namechain;
2573e12c5d1SDavid du Colombier 	q->datap = copys(fname);
2583e12c5d1SDavid du Colombier 	namechain = q;
2593e12c5d1SDavid du Colombier }
2603e12c5d1SDavid du Colombier 
2613e12c5d1SDavid du Colombier void
2623e12c5d1SDavid du Colombier usage(void)
2633e12c5d1SDavid du Colombier {
2643e12c5d1SDavid du Colombier 	fprint(2,"usage: deroff [-nwpi] [-m (m s l)] [file ...] \n");
2653e12c5d1SDavid du Colombier 	exits("usage");
2663e12c5d1SDavid du Colombier }
2673e12c5d1SDavid du Colombier 
2683e12c5d1SDavid du Colombier void
2693e12c5d1SDavid du Colombier fatal(char *s, char *p)
2703e12c5d1SDavid du Colombier {
2713e12c5d1SDavid du Colombier 	fprint(2, "deroff: ");
2723e12c5d1SDavid du Colombier 	fprint(2, s, p);
2733e12c5d1SDavid du Colombier 	exits(s);
2743e12c5d1SDavid du Colombier }
2753e12c5d1SDavid du Colombier 
2763e12c5d1SDavid du Colombier void
2773e12c5d1SDavid du Colombier work(void)
2783e12c5d1SDavid du Colombier {
2793e12c5d1SDavid du Colombier 
2803e12c5d1SDavid du Colombier 	for(;;) {
2813e12c5d1SDavid du Colombier 		eqnflag = 0;
2823e12c5d1SDavid du Colombier 		if(C == '.'  ||  c == '\'')
2833e12c5d1SDavid du Colombier 			comline();
2843e12c5d1SDavid du Colombier 		else
2853e12c5d1SDavid du Colombier 			regline(NO, TWO);
2863e12c5d1SDavid du Colombier 	}
2873e12c5d1SDavid du Colombier }
2883e12c5d1SDavid du Colombier 
2893e12c5d1SDavid du Colombier void
2903e12c5d1SDavid du Colombier regline(int macline, int vconst)
2913e12c5d1SDavid du Colombier {
2923e12c5d1SDavid du Colombier 	line[0] = c;
2933e12c5d1SDavid du Colombier 	lp = line;
2943e12c5d1SDavid du Colombier 	for(;;) {
2953e12c5d1SDavid du Colombier 		if(c == '\\') {
2963e12c5d1SDavid du Colombier 			*lp = ' ';
2973e12c5d1SDavid du Colombier 			backsl();
2983e12c5d1SDavid du Colombier 			if(c == '%')	/* no blank for hyphenation char */
2993e12c5d1SDavid du Colombier 				lp--;
3003e12c5d1SDavid du Colombier 		}
3013e12c5d1SDavid du Colombier 		if(c == '\n')
3023e12c5d1SDavid du Colombier 			break;
3033e12c5d1SDavid du Colombier 		if(intable && c=='T') {
3043e12c5d1SDavid du Colombier 			*++lp = C;
3053e12c5d1SDavid du Colombier 			if(c=='{' || c=='}') {
3063e12c5d1SDavid du Colombier 				lp[-1] = ' ';
3073e12c5d1SDavid du Colombier 				*lp = C;
3083e12c5d1SDavid du Colombier 			}
3093e12c5d1SDavid du Colombier 		} else {
3103e12c5d1SDavid du Colombier 			if(msflag == 1 && eqnflag == 1) {
3113e12c5d1SDavid du Colombier 				eqnflag = 0;
3123e12c5d1SDavid du Colombier 				*++lp = 'x';
3133e12c5d1SDavid du Colombier 			}
3143e12c5d1SDavid du Colombier 			*++lp = C;
3153e12c5d1SDavid du Colombier 		}
3163e12c5d1SDavid du Colombier 	}
3173e12c5d1SDavid du Colombier 	*lp = '\0';
3183e12c5d1SDavid du Colombier 	if(lp != line) {
3193e12c5d1SDavid du Colombier 		if(wordflag)
3203e12c5d1SDavid du Colombier 			putwords();
3213e12c5d1SDavid du Colombier 		else
3223e12c5d1SDavid du Colombier 		if(macline)
3233e12c5d1SDavid du Colombier 			putmac(line,vconst);
3243e12c5d1SDavid du Colombier 		else
3253e12c5d1SDavid du Colombier 			Bprint(&bout, "%S\n", line);
3263e12c5d1SDavid du Colombier 	}
3273e12c5d1SDavid du Colombier }
3283e12c5d1SDavid du Colombier 
3293e12c5d1SDavid du Colombier void
3303e12c5d1SDavid du Colombier putmac(Rune *rp, int vconst)
3313e12c5d1SDavid du Colombier {
3323e12c5d1SDavid du Colombier 	Rune *t;
3333e12c5d1SDavid du Colombier 	int found;
3343e12c5d1SDavid du Colombier 	Rune last;
3353e12c5d1SDavid du Colombier 
3363e12c5d1SDavid du Colombier 	found = 0;
3373e12c5d1SDavid du Colombier 	last = 0;
3383e12c5d1SDavid du Colombier 	while(*rp) {
3393e12c5d1SDavid du Colombier 		while(*rp == ' ' || *rp == '\t')
3403e12c5d1SDavid du Colombier 			Bputrune(&bout, *rp++);
3413e12c5d1SDavid du Colombier 		for(t = rp; *t != ' ' && *t != '\t' && *t != '\0'; t++)
3423e12c5d1SDavid du Colombier 			;
3433e12c5d1SDavid du Colombier 		if(*rp == '\"')
3443e12c5d1SDavid du Colombier 			rp++;
3453e12c5d1SDavid du Colombier 		if(t > rp+vconst && CHARCLASS(*rp) == LETTER
3463e12c5d1SDavid du Colombier 				&& CHARCLASS(rp[1]) == LETTER) {
3473e12c5d1SDavid du Colombier 			while(rp < t)
3483e12c5d1SDavid du Colombier 				if(*rp == '\"')
3493e12c5d1SDavid du Colombier 					rp++;
3503e12c5d1SDavid du Colombier 				else
3513e12c5d1SDavid du Colombier 					Bputrune(&bout, *rp++);
3523e12c5d1SDavid du Colombier 			last = t[-1];
3533e12c5d1SDavid du Colombier 			found++;
3543e12c5d1SDavid du Colombier 		} else
3553e12c5d1SDavid du Colombier 		if(found && CHARCLASS(*rp) == PUNCT && rp[1] == '\0')
3563e12c5d1SDavid du Colombier 			Bputrune(&bout, *rp++);
3573e12c5d1SDavid du Colombier 		else {
3583e12c5d1SDavid du Colombier 			last = t[-1];
3593e12c5d1SDavid du Colombier 			rp = t;
3603e12c5d1SDavid du Colombier 		}
3613e12c5d1SDavid du Colombier 	}
3623e12c5d1SDavid du Colombier 	Bputc(&bout, '\n');
3633e12c5d1SDavid du Colombier 	if(msflag && CHARCLASS(last) == PUNCT)
3643e12c5d1SDavid du Colombier 		Bprint(&bout, " %C\n", last);
3653e12c5d1SDavid du Colombier }
3663e12c5d1SDavid du Colombier 
3673e12c5d1SDavid du Colombier /*
3683e12c5d1SDavid du Colombier  * break into words for -w option
3693e12c5d1SDavid du Colombier  */
3703e12c5d1SDavid du Colombier void
3713e12c5d1SDavid du Colombier putwords(void)
3723e12c5d1SDavid du Colombier {
3733e12c5d1SDavid du Colombier 	Rune *p, *p1;
3743e12c5d1SDavid du Colombier 	int i, nlet;
3753e12c5d1SDavid du Colombier 
3763e12c5d1SDavid du Colombier 
3773e12c5d1SDavid du Colombier 	for(p1 = line;;) {
3783e12c5d1SDavid du Colombier 		/*
3793e12c5d1SDavid du Colombier 		 * skip initial specials ampersands and apostrophes
3803e12c5d1SDavid du Colombier 		 */
3813e12c5d1SDavid du Colombier 		while((i = CHARCLASS(*p1)) != EXTENDED && i < DIGIT)
3823e12c5d1SDavid du Colombier 			if(*p1++ == '\0')
3833e12c5d1SDavid du Colombier 				return;
3843e12c5d1SDavid du Colombier 		nlet = 0;
3853e12c5d1SDavid du Colombier 		for(p = p1; (i = CHARCLASS(*p)) != SPECIAL; p++)
3863e12c5d1SDavid du Colombier 			if(i == LETTER)
3873e12c5d1SDavid du Colombier 				nlet++;
3883e12c5d1SDavid du Colombier 		/*
3893e12c5d1SDavid du Colombier 		 * MDM definition of word
3903e12c5d1SDavid du Colombier 		 */
3913e12c5d1SDavid du Colombier 		if(nlet > 1) {
3923e12c5d1SDavid du Colombier 			/*
3933e12c5d1SDavid du Colombier 			 * delete trailing ampersands and apostrophes
3943e12c5d1SDavid du Colombier 			 */
3953e12c5d1SDavid du Colombier 			while(*--p == '\'' || *p == '&'
3963e12c5d1SDavid du Colombier 					   || CHARCLASS(*p) == PUNCT)
3973e12c5d1SDavid du Colombier 				;
3983e12c5d1SDavid du Colombier 			while(p1 <= p)
3993e12c5d1SDavid du Colombier 				Bputrune(&bout, *p1++);
4003e12c5d1SDavid du Colombier 			Bputc(&bout, '\n');
4013e12c5d1SDavid du Colombier 		} else
4023e12c5d1SDavid du Colombier 			p1 = p;
4033e12c5d1SDavid du Colombier 	}
4043e12c5d1SDavid du Colombier }
4053e12c5d1SDavid du Colombier 
4063e12c5d1SDavid du Colombier void
4073e12c5d1SDavid du Colombier comline(void)
4083e12c5d1SDavid du Colombier {
4093e12c5d1SDavid du Colombier 	long c1, c2;
4103e12c5d1SDavid du Colombier 
4113e12c5d1SDavid du Colombier com:
4123e12c5d1SDavid du Colombier 	while(C==' ' || c=='\t')
4133e12c5d1SDavid du Colombier 		;
4143e12c5d1SDavid du Colombier comx:
4153e12c5d1SDavid du Colombier 	if((c1=c) == '\n')
4163e12c5d1SDavid du Colombier 		return;
4173e12c5d1SDavid du Colombier 	c2 = C;
4183e12c5d1SDavid du Colombier 	if(c1=='.' && c2!='.')
4193e12c5d1SDavid du Colombier 		inmacro = NO;
4203e12c5d1SDavid du Colombier 	if(msflag && c1 == '['){
4213e12c5d1SDavid du Colombier 		refer(c2);
4223e12c5d1SDavid du Colombier 		return;
4233e12c5d1SDavid du Colombier 	}
4243e12c5d1SDavid du Colombier 	if(c2 == '\n')
4253e12c5d1SDavid du Colombier 		return;
4263e12c5d1SDavid du Colombier 	if(c1 == '\\' && c2 == '\"')
4273e12c5d1SDavid du Colombier 		SKIP;
4283e12c5d1SDavid du Colombier 	else
4293e12c5d1SDavid du Colombier 	if (filesp==files && c1=='E' && c2=='Q')
4303e12c5d1SDavid du Colombier 			eqn();
4313e12c5d1SDavid du Colombier 	else
4323e12c5d1SDavid du Colombier 	if(filesp==files && c1=='T' && (c2=='S' || c2=='C' || c2=='&')) {
4333e12c5d1SDavid du Colombier 		if(msflag)
4343e12c5d1SDavid du Colombier 			stbl();
4353e12c5d1SDavid du Colombier 		else
4363e12c5d1SDavid du Colombier 			tbl();
4373e12c5d1SDavid du Colombier 	}
4383e12c5d1SDavid du Colombier 	else
4393e12c5d1SDavid du Colombier 	if(c1=='T' && c2=='E')
4403e12c5d1SDavid du Colombier 		intable = NO;
4413e12c5d1SDavid du Colombier 	else if (!inmacro &&
4423e12c5d1SDavid du Colombier 			((c1 == 'd' && c2 == 'e') ||
4433e12c5d1SDavid du Colombier 		   	 (c1 == 'i' && c2 == 'g') ||
4443e12c5d1SDavid du Colombier 		   	 (c1 == 'a' && c2 == 'm')))
4453e12c5d1SDavid du Colombier 				macro();
4463e12c5d1SDavid du Colombier 	else
4473e12c5d1SDavid du Colombier 	if(c1=='s' && c2=='o') {
4483e12c5d1SDavid du Colombier 		if(iflag)
4493e12c5d1SDavid du Colombier 			SKIP;
4503e12c5d1SDavid du Colombier 		else {
4513e12c5d1SDavid du Colombier 			getfname();
4523e12c5d1SDavid du Colombier 			if(fname[0]) {
4533e12c5d1SDavid du Colombier 				if(infile = opn(fname))
4543e12c5d1SDavid du Colombier 					*++filesp = infile;
4553e12c5d1SDavid du Colombier 				else infile = *filesp;
4563e12c5d1SDavid du Colombier 			}
4573e12c5d1SDavid du Colombier 		}
4583e12c5d1SDavid du Colombier 	}
4593e12c5d1SDavid du Colombier 	else
4603e12c5d1SDavid du Colombier 	if(c1=='n' && c2=='x')
4613e12c5d1SDavid du Colombier 		if(iflag)
4623e12c5d1SDavid du Colombier 			SKIP;
4633e12c5d1SDavid du Colombier 		else {
4643e12c5d1SDavid du Colombier 			getfname();
4653e12c5d1SDavid du Colombier 			if(fname[0] == '\0')
4663e12c5d1SDavid du Colombier 				exits(0);
4673e12c5d1SDavid du Colombier 			if(Bfildes(infile) != 0)
468*219b2ee8SDavid du Colombier 				Bterm(infile);
4693e12c5d1SDavid du Colombier 			infile = *filesp = opn(fname);
4703e12c5d1SDavid du Colombier 		}
4713e12c5d1SDavid du Colombier 	else
4723e12c5d1SDavid du Colombier 	if(c1 == 't' && c2 == 'm')
4733e12c5d1SDavid du Colombier 		SKIP;
4743e12c5d1SDavid du Colombier 	else
4753e12c5d1SDavid du Colombier 	if(c1=='h' && c2=='w')
4763e12c5d1SDavid du Colombier 		SKIP;
4773e12c5d1SDavid du Colombier 	else
4783e12c5d1SDavid du Colombier 	if(msflag && c1 == 'T' && c2 == 'L') {
4793e12c5d1SDavid du Colombier 		SKIP_TO_COM;
4803e12c5d1SDavid du Colombier 		goto comx;
4813e12c5d1SDavid du Colombier 	}
4823e12c5d1SDavid du Colombier 	else
4833e12c5d1SDavid du Colombier 	if(msflag && c1=='N' && c2 == 'R')
4843e12c5d1SDavid du Colombier 		SKIP;
4853e12c5d1SDavid du Colombier 	else
486*219b2ee8SDavid du Colombier 	if(msflag && c1 == 'A' && (c2 == 'U' || c2 == 'I')){
4873e12c5d1SDavid du Colombier 		if(mac==MM)SKIP;
4883e12c5d1SDavid du Colombier 		else {
4893e12c5d1SDavid du Colombier 			SKIP_TO_COM;
4903e12c5d1SDavid du Colombier 			goto comx;
4913e12c5d1SDavid du Colombier 		}
4923e12c5d1SDavid du Colombier 	} else
4933e12c5d1SDavid du Colombier 	if(msflag && c1=='F' && c2=='S') {
4943e12c5d1SDavid du Colombier 		SKIP_TO_COM;
4953e12c5d1SDavid du Colombier 		goto comx;
4963e12c5d1SDavid du Colombier 	}
4973e12c5d1SDavid du Colombier 	else
4983e12c5d1SDavid du Colombier 	if(msflag && (c1=='S' || c1=='N') && c2=='H') {
4993e12c5d1SDavid du Colombier 		SKIP_TO_COM;
5003e12c5d1SDavid du Colombier 		goto comx;
5013e12c5d1SDavid du Colombier 	} else
5023e12c5d1SDavid du Colombier 	if(c1 == 'U' && c2 == 'X') {
5033e12c5d1SDavid du Colombier 		if(wordflag)
5043e12c5d1SDavid du Colombier 			Bprint(&bout, "UNIX\n");
5053e12c5d1SDavid du Colombier 		else
5063e12c5d1SDavid du Colombier 			Bprint(&bout, "UNIX ");
5073e12c5d1SDavid du Colombier 	} else
5083e12c5d1SDavid du Colombier 	if(msflag && c1=='O' && c2=='K') {
5093e12c5d1SDavid du Colombier 		SKIP_TO_COM;
5103e12c5d1SDavid du Colombier 		goto comx;
5113e12c5d1SDavid du Colombier 	} else
5123e12c5d1SDavid du Colombier 	if(msflag && c1=='N' && c2=='D')
5133e12c5d1SDavid du Colombier 		SKIP;
5143e12c5d1SDavid du Colombier 	else
515*219b2ee8SDavid du Colombier 	if(msflag && mac==MM && c1=='H' && (c2==' '||c2=='U'))
5163e12c5d1SDavid du Colombier 		SKIP;
517*219b2ee8SDavid du Colombier 	else
5183e12c5d1SDavid du Colombier 	if(msflag && mac==MM && c2=='L') {
5193e12c5d1SDavid du Colombier 		if(disp || c1=='R')
5203e12c5d1SDavid du Colombier 			sdis('L', 'E');
5213e12c5d1SDavid du Colombier 		else {
5223e12c5d1SDavid du Colombier 			SKIP;
5233e12c5d1SDavid du Colombier 			Bprint(&bout, " .");
5243e12c5d1SDavid du Colombier 		}
5253e12c5d1SDavid du Colombier 	} else
5263e12c5d1SDavid du Colombier 	if(!msflag && c1=='P' && c2=='S') {
5273e12c5d1SDavid du Colombier 		inpic();
5283e12c5d1SDavid du Colombier 	} else
5293e12c5d1SDavid du Colombier 	if(msflag && (c1=='D' || c1=='N' || c1=='K'|| c1=='P') && c2=='S') {
5303e12c5d1SDavid du Colombier 		sdis(c1, 'E');
5313e12c5d1SDavid du Colombier 	} else
5323e12c5d1SDavid du Colombier 	if(msflag && (c1 == 'K' && c2 == 'F')) {
5333e12c5d1SDavid du Colombier 		sdis(c1,'E');
5343e12c5d1SDavid du Colombier 	} else
5353e12c5d1SDavid du Colombier 	if(msflag && c1=='n' && c2=='f')
5363e12c5d1SDavid du Colombier 		sdis('f','i');
5373e12c5d1SDavid du Colombier 	else
5383e12c5d1SDavid du Colombier 	if(msflag && c1=='c' && c2=='e')
5393e12c5d1SDavid du Colombier 		sce();
5403e12c5d1SDavid du Colombier 	else {
5413e12c5d1SDavid du Colombier 		if(c1=='.' && c2=='.') {
5423e12c5d1SDavid du Colombier 			if(msflag) {
5433e12c5d1SDavid du Colombier 				SKIP;
5443e12c5d1SDavid du Colombier 				return;
5453e12c5d1SDavid du Colombier 			}
5463e12c5d1SDavid du Colombier 			while(C == '.')
5473e12c5d1SDavid du Colombier 				;
5483e12c5d1SDavid du Colombier 		}
5493e12c5d1SDavid du Colombier 		inmacro++;
5503e12c5d1SDavid du Colombier 		if(c1 <= 'Z' && msflag)
5513e12c5d1SDavid du Colombier 			regline(YES,ONE);
5523e12c5d1SDavid du Colombier 		else {
5533e12c5d1SDavid du Colombier 			if(wordflag)
5543e12c5d1SDavid du Colombier 				C;
5553e12c5d1SDavid du Colombier 			regline(YES,TWO);
5563e12c5d1SDavid du Colombier 		}
5573e12c5d1SDavid du Colombier 		inmacro--;
5583e12c5d1SDavid du Colombier 	}
5593e12c5d1SDavid du Colombier }
5603e12c5d1SDavid du Colombier 
5613e12c5d1SDavid du Colombier void
5623e12c5d1SDavid du Colombier macro(void)
5633e12c5d1SDavid du Colombier {
5643e12c5d1SDavid du Colombier 	if(msflag) {
5653e12c5d1SDavid du Colombier 		do {
5663e12c5d1SDavid du Colombier 			SKIP1;
5673e12c5d1SDavid du Colombier 		} while(C1 != '.' || C1 != '.' || C1 == '.');
5683e12c5d1SDavid du Colombier 		if(c != '\n')
5693e12c5d1SDavid du Colombier 			SKIP;
5703e12c5d1SDavid du Colombier 		return;
5713e12c5d1SDavid du Colombier 	}
5723e12c5d1SDavid du Colombier 	SKIP;
5733e12c5d1SDavid du Colombier 	inmacro = YES;
5743e12c5d1SDavid du Colombier }
5753e12c5d1SDavid du Colombier 
5763e12c5d1SDavid du Colombier void
5773e12c5d1SDavid du Colombier sdis(char a1, char a2)
5783e12c5d1SDavid du Colombier {
5793e12c5d1SDavid du Colombier 	int c1, c2;
5803e12c5d1SDavid du Colombier 	int eqnf;
5813e12c5d1SDavid du Colombier 	int lct;
5823e12c5d1SDavid du Colombier 
5833e12c5d1SDavid du Colombier 	if(a1 == 'P'){
5843e12c5d1SDavid du Colombier 		while(C1 == ' ')
5853e12c5d1SDavid du Colombier 			;
5863e12c5d1SDavid du Colombier 		if(c == '<') {
5873e12c5d1SDavid du Colombier 			SKIP1;
5883e12c5d1SDavid du Colombier 			return;
5893e12c5d1SDavid du Colombier 		}
5903e12c5d1SDavid du Colombier 	}
5913e12c5d1SDavid du Colombier 	lct = 0;
5923e12c5d1SDavid du Colombier 	eqnf = 1;
5933e12c5d1SDavid du Colombier 	if(c != '\n')
5943e12c5d1SDavid du Colombier 		SKIP1;
5953e12c5d1SDavid du Colombier 	for(;;) {
5963e12c5d1SDavid du Colombier 		while(C1 != '.')
5973e12c5d1SDavid du Colombier 			if(c == '\n')
5983e12c5d1SDavid du Colombier 				continue;
5993e12c5d1SDavid du Colombier 			else
6003e12c5d1SDavid du Colombier 				SKIP1;
6013e12c5d1SDavid du Colombier 		if((c1=C1) == '\n')
6023e12c5d1SDavid du Colombier 			continue;
6033e12c5d1SDavid du Colombier 		if((c2=C1) == '\n') {
6043e12c5d1SDavid du Colombier 			if(a1 == 'f' && (c1 == 'P' || c1 == 'H'))
6053e12c5d1SDavid du Colombier 				return;
6063e12c5d1SDavid du Colombier 			continue;
6073e12c5d1SDavid du Colombier 		}
6083e12c5d1SDavid du Colombier 		if(c1==a1 && c2 == a2) {
6093e12c5d1SDavid du Colombier 			SKIP1;
6103e12c5d1SDavid du Colombier 			if(lct != 0){
6113e12c5d1SDavid du Colombier 				lct--;
6123e12c5d1SDavid du Colombier 				continue;
6133e12c5d1SDavid du Colombier 			}
6143e12c5d1SDavid du Colombier 			if(eqnf)
6153e12c5d1SDavid du Colombier 				Bprint(&bout, " .");
6163e12c5d1SDavid du Colombier 			Bputc(&bout, '\n');
6173e12c5d1SDavid du Colombier 			return;
6183e12c5d1SDavid du Colombier 		} else
6193e12c5d1SDavid du Colombier 		if(a1 == 'L' && c2 == 'L') {
6203e12c5d1SDavid du Colombier 			lct++;
6213e12c5d1SDavid du Colombier 			SKIP1;
6223e12c5d1SDavid du Colombier 		} else
6233e12c5d1SDavid du Colombier 		if(a1 == 'D' && c1 == 'E' && c2 == 'Q') {
6243e12c5d1SDavid du Colombier 			eqn();
6253e12c5d1SDavid du Colombier 			eqnf = 0;
6263e12c5d1SDavid du Colombier 		} else
6273e12c5d1SDavid du Colombier 		if(a1 == 'f') {
6283e12c5d1SDavid du Colombier 			if((mac == MS && c2 == 'P') ||
6293e12c5d1SDavid du Colombier 				(mac == MM && c1 == 'H' && c2 == 'U')){
6303e12c5d1SDavid du Colombier 				SKIP1;
6313e12c5d1SDavid du Colombier 				return;
6323e12c5d1SDavid du Colombier 			}
6333e12c5d1SDavid du Colombier 			SKIP1;
6343e12c5d1SDavid du Colombier 		}
6353e12c5d1SDavid du Colombier 		else
6363e12c5d1SDavid du Colombier 			SKIP1;
6373e12c5d1SDavid du Colombier 	}
6383e12c5d1SDavid du Colombier }
6393e12c5d1SDavid du Colombier 
6403e12c5d1SDavid du Colombier void
6413e12c5d1SDavid du Colombier tbl(void)
6423e12c5d1SDavid du Colombier {
6433e12c5d1SDavid du Colombier 	while(C != '.')
6443e12c5d1SDavid du Colombier 		;
6453e12c5d1SDavid du Colombier 	SKIP;
6463e12c5d1SDavid du Colombier 	intable = YES;
6473e12c5d1SDavid du Colombier }
6483e12c5d1SDavid du Colombier 
6493e12c5d1SDavid du Colombier void
6503e12c5d1SDavid du Colombier stbl(void)
6513e12c5d1SDavid du Colombier {
6523e12c5d1SDavid du Colombier 	while(C != '.')
6533e12c5d1SDavid du Colombier 		;
6543e12c5d1SDavid du Colombier 	SKIP_TO_COM;
6553e12c5d1SDavid du Colombier 	if(c != 'T' || C != 'E') {
6563e12c5d1SDavid du Colombier 		SKIP;
6573e12c5d1SDavid du Colombier 		pc = c;
6583e12c5d1SDavid du Colombier 		while(C != '.' || pc != '\n' || C != 'T' || C != 'E')
6593e12c5d1SDavid du Colombier 			pc = c;
6603e12c5d1SDavid du Colombier 	}
6613e12c5d1SDavid du Colombier }
6623e12c5d1SDavid du Colombier 
6633e12c5d1SDavid du Colombier void
6643e12c5d1SDavid du Colombier eqn(void)
6653e12c5d1SDavid du Colombier {
6663e12c5d1SDavid du Colombier 	long c1, c2;
6673e12c5d1SDavid du Colombier 	int dflg;
6683e12c5d1SDavid du Colombier 	char last;
6693e12c5d1SDavid du Colombier 
6703e12c5d1SDavid du Colombier 	last = 0;
6713e12c5d1SDavid du Colombier 	dflg = 1;
6723e12c5d1SDavid du Colombier 	SKIP;
6733e12c5d1SDavid du Colombier 
6743e12c5d1SDavid du Colombier 	for(;;) {
6753e12c5d1SDavid du Colombier 		if(C1 == '.'  || c == '\'') {
6763e12c5d1SDavid du Colombier 			while(C1==' ' || c=='\t')
6773e12c5d1SDavid du Colombier 				;
6783e12c5d1SDavid du Colombier 			if(c=='E' && C1=='N') {
6793e12c5d1SDavid du Colombier 				SKIP;
6803e12c5d1SDavid du Colombier 				if(msflag && dflg) {
6813e12c5d1SDavid du Colombier 					Bputc(&bout, 'x');
6823e12c5d1SDavid du Colombier 					Bputc(&bout, ' ');
6833e12c5d1SDavid du Colombier 					if(last) {
6843e12c5d1SDavid du Colombier 						Bputc(&bout, last);
6853e12c5d1SDavid du Colombier 						Bputc(&bout, '\n');
6863e12c5d1SDavid du Colombier 					}
6873e12c5d1SDavid du Colombier 				}
6883e12c5d1SDavid du Colombier 				return;
6893e12c5d1SDavid du Colombier 			}
6903e12c5d1SDavid du Colombier 		} else
6913e12c5d1SDavid du Colombier 		if(c == 'd') {
6923e12c5d1SDavid du Colombier 			if(C1=='e' && C1=='l')
6933e12c5d1SDavid du Colombier 				if(C1=='i' && C1=='m') {
6943e12c5d1SDavid du Colombier 					while(C1 == ' ')
6953e12c5d1SDavid du Colombier 						;
6963e12c5d1SDavid du Colombier 					if((c1=c)=='\n' || (c2=C1)=='\n' ||
6973e12c5d1SDavid du Colombier 					  (c1=='o' && c2=='f' && C1=='f')) {
6983e12c5d1SDavid du Colombier 						ldelim = NOCHAR;
6993e12c5d1SDavid du Colombier 						rdelim = NOCHAR;
7003e12c5d1SDavid du Colombier 					} else {
7013e12c5d1SDavid du Colombier 						ldelim = c1;
7023e12c5d1SDavid du Colombier 						rdelim = c2;
7033e12c5d1SDavid du Colombier 					}
7043e12c5d1SDavid du Colombier 				}
7053e12c5d1SDavid du Colombier 			dflg = 0;
7063e12c5d1SDavid du Colombier 		}
7073e12c5d1SDavid du Colombier 		if(c != '\n')
7083e12c5d1SDavid du Colombier 			while(C1 != '\n') {
7093e12c5d1SDavid du Colombier 				if(chars[c] == PUNCT)
7103e12c5d1SDavid du Colombier 					last = c;
7113e12c5d1SDavid du Colombier 				else
7123e12c5d1SDavid du Colombier 				if(c != ' ')
7133e12c5d1SDavid du Colombier 					last = 0;
7143e12c5d1SDavid du Colombier 			}
7153e12c5d1SDavid du Colombier 	}
7163e12c5d1SDavid du Colombier }
7173e12c5d1SDavid du Colombier 
7183e12c5d1SDavid du Colombier /*
7193e12c5d1SDavid du Colombier  * skip over a complete backslash vconstruction
7203e12c5d1SDavid du Colombier  */
7213e12c5d1SDavid du Colombier void
7223e12c5d1SDavid du Colombier backsl(void)
7233e12c5d1SDavid du Colombier {
7243e12c5d1SDavid du Colombier 	int bdelim;
7253e12c5d1SDavid du Colombier 
7263e12c5d1SDavid du Colombier sw:
7273e12c5d1SDavid du Colombier 	switch(C1)
7283e12c5d1SDavid du Colombier 	{
7293e12c5d1SDavid du Colombier 	case '"':
7303e12c5d1SDavid du Colombier 		SKIP1;
7313e12c5d1SDavid du Colombier 		return;
7323e12c5d1SDavid du Colombier 
7333e12c5d1SDavid du Colombier 	case 's':
7343e12c5d1SDavid du Colombier 		if(C1 == '\\')
7353e12c5d1SDavid du Colombier 			backsl();
7363e12c5d1SDavid du Colombier 		else {
7373e12c5d1SDavid du Colombier 			while(C1>='0' && c<='9')
7383e12c5d1SDavid du Colombier 				;
7393e12c5d1SDavid du Colombier 			Bungetrune(infile);
7403e12c5d1SDavid du Colombier 			c = '0';
7413e12c5d1SDavid du Colombier 		}
7423e12c5d1SDavid du Colombier 		lp--;
7433e12c5d1SDavid du Colombier 		return;
7443e12c5d1SDavid du Colombier 
7453e12c5d1SDavid du Colombier 	case 'f':
7463e12c5d1SDavid du Colombier 	case 'n':
7473e12c5d1SDavid du Colombier 	case '*':
7483e12c5d1SDavid du Colombier 		if(C1 != '(')
7493e12c5d1SDavid du Colombier 			return;
7503e12c5d1SDavid du Colombier 
7513e12c5d1SDavid du Colombier 	case '(':
7523e12c5d1SDavid du Colombier 		if(msflag) {
7533e12c5d1SDavid du Colombier 			if(C == 'e') {
7543e12c5d1SDavid du Colombier 				if(C1 == 'm') {
7553e12c5d1SDavid du Colombier 					*lp = '-';
7563e12c5d1SDavid du Colombier 					return;
7573e12c5d1SDavid du Colombier 				}
7583e12c5d1SDavid du Colombier 			} else
7593e12c5d1SDavid du Colombier 			if(c != '\n')
7603e12c5d1SDavid du Colombier 				C1;
7613e12c5d1SDavid du Colombier 			return;
7623e12c5d1SDavid du Colombier 		}
7633e12c5d1SDavid du Colombier 		if(C1 != '\n')
7643e12c5d1SDavid du Colombier 			C1;
7653e12c5d1SDavid du Colombier 		return;
7663e12c5d1SDavid du Colombier 
7673e12c5d1SDavid du Colombier 	case '$':
7683e12c5d1SDavid du Colombier 		C1;	/* discard argument number */
7693e12c5d1SDavid du Colombier 		return;
7703e12c5d1SDavid du Colombier 
7713e12c5d1SDavid du Colombier 	case 'b':
7723e12c5d1SDavid du Colombier 	case 'x':
7733e12c5d1SDavid du Colombier 	case 'v':
7743e12c5d1SDavid du Colombier 	case 'h':
7753e12c5d1SDavid du Colombier 	case 'w':
7763e12c5d1SDavid du Colombier 	case 'o':
7773e12c5d1SDavid du Colombier 	case 'l':
7783e12c5d1SDavid du Colombier 	case 'L':
7793e12c5d1SDavid du Colombier 		if((bdelim=C1) == '\n')
7803e12c5d1SDavid du Colombier 			return;
7813e12c5d1SDavid du Colombier 		while(C1!='\n' && c!=bdelim)
7823e12c5d1SDavid du Colombier 			if(c == '\\')
7833e12c5d1SDavid du Colombier 				backsl();
7843e12c5d1SDavid du Colombier 		return;
7853e12c5d1SDavid du Colombier 
7863e12c5d1SDavid du Colombier 	case '\\':
7873e12c5d1SDavid du Colombier 		if(inmacro)
7883e12c5d1SDavid du Colombier 			goto sw;
7893e12c5d1SDavid du Colombier 	default:
7903e12c5d1SDavid du Colombier 		return;
7913e12c5d1SDavid du Colombier 	}
7923e12c5d1SDavid du Colombier }
7933e12c5d1SDavid du Colombier 
7943e12c5d1SDavid du Colombier char*
7953e12c5d1SDavid du Colombier copys(char *s)
7963e12c5d1SDavid du Colombier {
7973e12c5d1SDavid du Colombier 	char *t, *t0;
7983e12c5d1SDavid du Colombier 
7993e12c5d1SDavid du Colombier 	if((t0 = t = malloc((strlen(s)+1))) == 0)
8003e12c5d1SDavid du Colombier 		fatal("Cannot allocate memory", (char*)0);
8013e12c5d1SDavid du Colombier 	while(*t++ = *s++)
8023e12c5d1SDavid du Colombier 		;
8033e12c5d1SDavid du Colombier 	return(t0);
8043e12c5d1SDavid du Colombier }
8053e12c5d1SDavid du Colombier 
8063e12c5d1SDavid du Colombier void
8073e12c5d1SDavid du Colombier sce(void)
8083e12c5d1SDavid du Colombier {
8093e12c5d1SDavid du Colombier 	int n = 1;
8103e12c5d1SDavid du Colombier 
8113e12c5d1SDavid du Colombier 	while (C != L'\n' && !(L'0' <= c && c <= L'9'))
8123e12c5d1SDavid du Colombier 		;
8133e12c5d1SDavid du Colombier 	if (c != L'\n') {
8143e12c5d1SDavid du Colombier 		for (n = c-L'0';'0' <= C && c <= L'9';)
8153e12c5d1SDavid du Colombier 			n = n*10 + c-L'0';
8163e12c5d1SDavid du Colombier 	}
8173e12c5d1SDavid du Colombier 	while(n) {
8183e12c5d1SDavid du Colombier 		if(C == '.') {
8193e12c5d1SDavid du Colombier 			if(C == 'c') {
8203e12c5d1SDavid du Colombier 				if(C == 'e') {
8213e12c5d1SDavid du Colombier 					while(C == ' ')
8223e12c5d1SDavid du Colombier 						;
8233e12c5d1SDavid du Colombier 					if(c == '0') {
8243e12c5d1SDavid du Colombier 						SKIP;
8253e12c5d1SDavid du Colombier 						break;
8263e12c5d1SDavid du Colombier 					} else
8273e12c5d1SDavid du Colombier 						SKIP;
8283e12c5d1SDavid du Colombier 				} else
8293e12c5d1SDavid du Colombier 					SKIP;
8303e12c5d1SDavid du Colombier 			} else
8313e12c5d1SDavid du Colombier 			if(c == 'P' || C == 'P') {
8323e12c5d1SDavid du Colombier 				if(c != '\n')
8333e12c5d1SDavid du Colombier 					SKIP;
8343e12c5d1SDavid du Colombier 				break;
8353e12c5d1SDavid du Colombier 			} else
8363e12c5d1SDavid du Colombier 				if(c != '\n')
8373e12c5d1SDavid du Colombier 					SKIP;
8383e12c5d1SDavid du Colombier 		} else {
8393e12c5d1SDavid du Colombier 			SKIP;
8403e12c5d1SDavid du Colombier 			n--;
8413e12c5d1SDavid du Colombier 		}
8423e12c5d1SDavid du Colombier 	}
8433e12c5d1SDavid du Colombier }
8443e12c5d1SDavid du Colombier 
8453e12c5d1SDavid du Colombier void
8463e12c5d1SDavid du Colombier refer(int c1)
8473e12c5d1SDavid du Colombier {
8483e12c5d1SDavid du Colombier 	int c2;
8493e12c5d1SDavid du Colombier 
8503e12c5d1SDavid du Colombier 	if(c1 != '\n')
8513e12c5d1SDavid du Colombier 		SKIP;
8523e12c5d1SDavid du Colombier 	c2 = 0;
8533e12c5d1SDavid du Colombier 	for(;;) {
8543e12c5d1SDavid du Colombier 		if(C != '.')
8553e12c5d1SDavid du Colombier 			SKIP;
8563e12c5d1SDavid du Colombier 		else {
8573e12c5d1SDavid du Colombier 			if(C != ']')
8583e12c5d1SDavid du Colombier 				SKIP;
8593e12c5d1SDavid du Colombier 			else {
8603e12c5d1SDavid du Colombier 				while(C != '\n')
8613e12c5d1SDavid du Colombier 					c2 = c;
8623e12c5d1SDavid du Colombier 				if(CHARCLASS(c2) == PUNCT)
8633e12c5d1SDavid du Colombier 					Bprint(&bout, " %C",c2);
8643e12c5d1SDavid du Colombier 				return;
8653e12c5d1SDavid du Colombier 			}
8663e12c5d1SDavid du Colombier 		}
8673e12c5d1SDavid du Colombier 	}
8683e12c5d1SDavid du Colombier }
8693e12c5d1SDavid du Colombier 
8703e12c5d1SDavid du Colombier void
8713e12c5d1SDavid du Colombier inpic(void)
8723e12c5d1SDavid du Colombier {
8733e12c5d1SDavid du Colombier 	int c1;
8743e12c5d1SDavid du Colombier 	Rune *p1;
8753e12c5d1SDavid du Colombier 
8763e12c5d1SDavid du Colombier /*	SKIP1;*/
8773e12c5d1SDavid du Colombier 	while(C1 != '\n')
8783e12c5d1SDavid du Colombier 		if(c == '<'){
8793e12c5d1SDavid du Colombier 			SKIP1;
8803e12c5d1SDavid du Colombier 			return;
8813e12c5d1SDavid du Colombier 		}
8823e12c5d1SDavid du Colombier 	p1 = line;
8833e12c5d1SDavid du Colombier 	c = '\n';
8843e12c5d1SDavid du Colombier 	for(;;) {
8853e12c5d1SDavid du Colombier 		c1 = c;
8863e12c5d1SDavid du Colombier 		if(C1 == '.' && c1 == '\n') {
8873e12c5d1SDavid du Colombier 			if(C1 != 'P' || C1 != 'E') {
8883e12c5d1SDavid du Colombier 				if(c != '\n'){
8893e12c5d1SDavid du Colombier 					SKIP1;
8903e12c5d1SDavid du Colombier 					c = '\n';
8913e12c5d1SDavid du Colombier 				}
8923e12c5d1SDavid du Colombier 				continue;
8933e12c5d1SDavid du Colombier 			}
8943e12c5d1SDavid du Colombier 			SKIP1;
8953e12c5d1SDavid du Colombier 			return;
8963e12c5d1SDavid du Colombier 		} else
8973e12c5d1SDavid du Colombier 		if(c == '\"') {
8983e12c5d1SDavid du Colombier 			while(C1 != '\"') {
8993e12c5d1SDavid du Colombier 				if(c == '\\') {
9003e12c5d1SDavid du Colombier 					if(C1 == '\"')
9013e12c5d1SDavid du Colombier 						continue;
9023e12c5d1SDavid du Colombier 					Bungetrune(infile);
9033e12c5d1SDavid du Colombier 					backsl();
9043e12c5d1SDavid du Colombier 				} else
9053e12c5d1SDavid du Colombier 					*p1++ = c;
9063e12c5d1SDavid du Colombier 			}
9073e12c5d1SDavid du Colombier 			*p1++ = ' ';
9083e12c5d1SDavid du Colombier 		} else
9093e12c5d1SDavid du Colombier 		if(c == '\n' && p1 != line) {
9103e12c5d1SDavid du Colombier 			*p1 = '\0';
9113e12c5d1SDavid du Colombier 			if(wordflag)
9123e12c5d1SDavid du Colombier 				putwords();
9133e12c5d1SDavid du Colombier 			else
9143e12c5d1SDavid du Colombier 				Bprint(&bout, "%S\n\n", line);
9153e12c5d1SDavid du Colombier 			p1 = line;
9163e12c5d1SDavid du Colombier 		}
9173e12c5d1SDavid du Colombier 	}
9183e12c5d1SDavid du Colombier }
919