#include <err.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define Cget ( (c=getc(infile)) == EOF ? eof() : ((c==ldelim)&&(filesp==files) ? skeqn() : c) )
#define C1get ( (c=getc(infile)) == EOF ? eof() : c)
#ifdef DEBUG
# define C _C()
# define C1 _C1()
#else
# define C Cget
# define C1 C1get
#endif
#define SKIP while (C != '\n')
#define SKIP_TO_COM SKIP; SKIP; pc=c; while (C != '.' || pc != '\n' || C > 'Z')pc=c
#define YES 1
#define NO 0
#define MS 0
#define MM 1
#define ME 2
#define MA 3
#ifdef DEBUG
char *mactab[] = { "-ms", "-mm", "-me", "-ma" };
#endif
#define ONE 1
#define TWO 2
#define NOCHAR -2
#define SPECIAL 0
#define APOS 1
#define PUNCT 2
#define DIGIT 3
#define LETTER 4
#define MAXFILES 20
int iflag;
int wordflag;
int msflag;
int mac;
int disp;
int parag;
int inmacro;
int intable;
int keepblock;
char chars[256];
size_t linesz;
char *line;
char *lp;
int c;
int pc;
int ldelim;
int rdelim;
char fname[PATH_MAX];
FILE *files[MAXFILES];
FILE **filesp;
FILE *infile;
int argc;
char **argv;
typedef int pacmac;
int argconcat = 0;
#define tomac(c1, c2) ((((c1) & 0xFF) << 8) | ((c2) & 0xFF))
#define frommac(src, c1, c2) (((c1)=((src)>>8)&0xFF),((c2) =(src)&0xFF))
struct mactab{
int condition;
pacmac macname;
int (*func)();
};
struct mactab troffmactab[];
struct mactab ppmactab[];
struct mactab msmactab[];
struct mactab mmmactab[];
struct mactab memactab[];
struct mactab manmactab[];
#define M(cond, c1, c2, func) {cond, tomac(c1, c2), func}
#define NONE 0
#define FNEST 1
#define NOMAC 2
#define MAC 3
#define PARAG 4
#define MSF 5
#define NBLK 6
#define COMX 1
#define COM 2
int skeqn(void);
int eof(void);
int _C1(void);
int _C(void);
int EQ(void);
int domacro(void);
int PS(void);
int skip(void);
int intbl(void);
int outtbl(void);
int so(void);
int nx(void);
int skiptocom(void);
int PP(pacmac);
int AU(void);
int SH(pacmac);
int UX(void);
int MMHU(pacmac);
int mesnblock(pacmac);
int mssnblock(pacmac);
int nf(void);
int ce(void);
int meip(pacmac);
int mepp(pacmac);
int mesh(pacmac);
int mefont(pacmac);
int manfont(pacmac);
int manpp(pacmac);
int macsort(const void *, const void *);
int sizetab(struct mactab *);
void getfname(void);
void textline(char *, int);
void work(void);
void regline(void (*)(char *, int), int);
void macro(void);
void tbl(void);
void stbl(void);
void eqn(void);
void backsl(void);
void sce(void);
void refer(int);
void inpic(void);
void msputmac(char *, int);
void msputwords(int);
void meputmac(char *, int);
void meputwords(int);
void noblock(char, char);
void defcomline(pacmac);
void comline(void);
void buildtab(struct mactab **, int *);
FILE *opn(char *);
struct mactab *macfill(struct mactab *, struct mactab *);
__dead void usage(void);
int
main(int ac, char **av)
{
int i, ch;
int errflg = 0;
int kflag = NO;
if (pledge("stdio rpath", NULL) == -1)
err(1, "pledge");
iflag = NO;
wordflag = NO;
msflag = NO;
mac = ME;
disp = NO;
parag = NO;
inmacro = NO;
intable = NO;
ldelim = NOCHAR;
rdelim = NOCHAR;
keepblock = YES;
while ((ch = getopt(ac, av, "ikpwm:")) != -1) {
switch (ch) {
case 'i':
iflag = YES;
break;
case 'k':
kflag = YES;
break;
case 'm':
msflag = YES;
keepblock = NO;
switch (optarg[0]) {
case 'm':
mac = MM;
break;
case 's':
mac = MS;
break;
case 'e':
mac = ME;
break;
case 'a':
mac = MA;
break;
case 'l':
disp = YES;
break;
default:
errflg = 1;
break;
}
if (optarg[1] != '\0')
errflg = 1;
break;
case 'p':
parag = YES;
break;
case 'w':
wordflag = YES;
kflag = YES;
break;
default:
errflg = 1;
}
}
argc = ac - optind;
argv = av + optind;
if (kflag)
keepblock = YES;
if (errflg)
usage();
#ifdef DEBUG
printf("msflag = %d, mac = %s, keepblock = %d, disp = %d\n",
msflag, mactab[mac], keepblock, disp);
#endif
if (argc == 0) {
infile = stdin;
} else {
infile = opn(argv[0]);
--argc;
++argv;
}
files[0] = infile;
filesp = &files[0];
linesz = LINE_MAX;
if ((line = malloc(linesz)) == NULL)
err(1, NULL);
for (i = 'a'; i <= 'z'; ++i)
chars[i] = LETTER;
for (i = 'A'; i <= 'Z'; ++i)
chars[i] = LETTER;
for (i = '0'; i <= '9'; ++i)
chars[i] = DIGIT;
chars['\''] = APOS;
chars['&'] = APOS;
chars['.'] = PUNCT;
chars[','] = PUNCT;
chars[';'] = PUNCT;
chars['?'] = PUNCT;
chars[':'] = PUNCT;
work();
exit(0);
}
int
skeqn(void)
{
while ((c = getc(infile)) != rdelim) {
if (c == EOF)
c = eof();
else if (c == '"') {
while ((c = getc(infile)) != '"') {
if (c == EOF ||
(c == '\\' && (c = getc(infile)) == EOF))
c = eof();
}
}
}
if (msflag)
return((c = 'x'));
return((c = ' '));
}
FILE *
opn(char *p)
{
FILE *fd;
if ((fd = fopen(p, "r")) == NULL)
err(1, "fopen %s", p);
return(fd);
}
int
eof(void)
{
if (infile != stdin)
fclose(infile);
if (filesp > files)
infile = *--filesp;
else if (argc > 0) {
infile = opn(argv[0]);
--argc;
++argv;
} else
exit(0);
return(C);
}
void
getfname(void)
{
char *p;
struct chain {
struct chain *nextp;
char *datap;
} *q;
static struct chain *namechain= NULL;
while (C == ' ')
;
for (p = fname ; p - fname < sizeof(fname) && (*p = c) != '\n' &&
c != ' ' && c != '\t' && c != '\\'; ++p)
C;
*p = '\0';
while (c != '\n')
C;
for (q = namechain ; q; q = q->nextp)
if (strcmp(fname, q->datap) == 0) {
fname[0] = '\0';
return;
}
q = malloc(sizeof(struct chain));
if (q == NULL)
err(1, NULL);
q->nextp = namechain;
q->datap = strdup(fname);
if (q->datap == NULL)
err(1, NULL);
namechain = q;
}
void
textline(char *str, int constant)
{
if (wordflag) {
msputwords(0);
return;
}
puts(str);
}
void
work(void)
{
for (;;) {
C;
#ifdef FULLDEBUG
printf("Starting work with `%c'\n", c);
#endif
if (c == '.' || c == '\'')
comline();
else
regline(textline, TWO);
}
}
void
regline(void (*pfunc)(char *, int), int constant)
{
line[0] = c;
lp = line;
for (;;) {
if (lp - line == linesz - 1) {
char *newline = reallocarray(line, linesz, 2);
if (newline == NULL)
err(1, NULL);
lp = newline + (lp - line);
line = newline;
linesz *= 2;
}
if (c == '\\') {
*lp = ' ';
backsl();
}
if (c == '\n')
break;
if (intable && c == 'T') {
*++lp = C;
if (c == '{' || c == '}') {
lp[-1] = ' ';
*lp = C;
}
} else {
*++lp = C;
}
}
*lp = '\0';
if (line[0] != '\0')
(*pfunc)(line, constant);
}
void
macro(void)
{
if (msflag) {
do {
SKIP;
} while (C!='.' || C!='.' || C=='.');
if (c != '\n')
SKIP;
return;
}
SKIP;
inmacro = YES;
}
void
tbl(void)
{
while (C != '.')
;
SKIP;
intable = YES;
}
void
stbl(void)
{
while (C != '.')
;
SKIP_TO_COM;
if (c != 'T' || C != 'E') {
SKIP;
pc = c;
while (C != '.' || pc != '\n' || C != 'T' || C != 'E')
pc = c;
}
}
void
eqn(void)
{
int c1, c2;
int dflg;
char last;
last=0;
dflg = 1;
SKIP;
for (;;) {
if (C1 == '.' || c == '\'') {
while (C1 == ' ' || c == '\t')
;
if (c == 'E' && C1 == 'N') {
SKIP;
if (msflag && dflg) {
putchar('x');
putchar(' ');
if (last) {
putchar(last);
putchar('\n');
}
}
return;
}
} else if (c == 'd') {
if (C1 == 'e' && C1 == 'l')
if (C1 == 'i' && C1 == 'm') {
while (C1 == ' ')
;
if ((c1 = c) == '\n' ||
(c2 = C1) == '\n' ||
(c1 == 'o' && c2 == 'f' && C1=='f')) {
ldelim = NOCHAR;
rdelim = NOCHAR;
} else {
ldelim = c1;
rdelim = c2;
}
}
dflg = 0;
}
if (c != '\n')
while (C1 != '\n') {
if (chars[c] == PUNCT)
last = c;
else if (c != ' ')
last = 0;
}
}
}
void
backsl(void)
{
int bdelim;
sw:
switch (C) {
case '"':
SKIP;
return;
case 's':
if (C == '\\')
backsl();
else {
while (C >= '0' && c <= '9')
;
ungetc(c, infile);
c = '0';
}
--lp;
return;
case 'f':
case 'n':
case '*':
if (C != '(')
return;
case '(':
if (msflag) {
if (C == 'e') {
if (C == 'm') {
*lp = '-';
return;
}
}
else if (c != '\n')
C;
return;
}
if (C != '\n')
C;
return;
case '$':
C;
return;
case 'b':
case 'x':
case 'v':
case 'h':
case 'w':
case 'o':
case 'l':
case 'L':
if ((bdelim = C) == '\n')
return;
while (C != '\n' && c != bdelim)
if (c == '\\')
backsl();
return;
case '\\':
if (inmacro)
goto sw;
default:
return;
}
}
void
sce(void)
{
char *ap;
int n, i;
char a[10];
for (ap = a; C != '\n'; ap++) {
*ap = c;
if (ap == &a[9]) {
SKIP;
ap = a;
break;
}
}
if (ap != a)
n = atoi(a);
else
n = 1;
for (i = 0; i < n;) {
if (C == '.') {
if (C == 'c') {
if (C == 'e') {
while (C == ' ')
;
if (c == '0') {
SKIP;
break;
} else
SKIP;
}
else
SKIP;
} else if (c == 'P' || C == 'P') {
if (c != '\n')
SKIP;
break;
} else if (c != '\n')
SKIP;
} else {
SKIP;
i++;
}
}
}
void
refer(int c1)
{
int c2;
if (c1 != '\n')
SKIP;
for (c2 = -1;;) {
if (C != '.')
SKIP;
else {
if (C != ']')
SKIP;
else {
while (C != '\n')
c2 = c;
if (c2 != -1 && chars[c2] == PUNCT)
putchar(c2);
return;
}
}
}
}
void
inpic(void)
{
int c1;
char *p1, *ep;
SKIP;
p1 = line;
ep = line + sizeof(line) - 1;
c = '\n';
for (;;) {
c1 = c;
if (C == '.' && c1 == '\n') {
if (C != 'P') {
if (c == '\n')
continue;
else {
SKIP;
c = '\n';
continue;
}
}
if (C != 'E') {
if (c == '\n')
continue;
else {
SKIP;
c = '\n';
continue;
}
}
SKIP;
return;
}
else if (c == '\"') {
while (C != '\"') {
if (c == '\\') {
if (C == '\"')
continue;
ungetc(c, infile);
backsl();
} else if (p1 + 1 >= ep) {
errx(1, ".PS length exceeds limit");
} else {
*p1++ = c;
}
}
*p1++ = ' ';
}
else if (c == '\n' && p1 != line) {
*p1 = '\0';
if (wordflag)
msputwords(NO);
else {
puts(line);
putchar('\n');
}
p1 = line;
}
}
}
#ifdef DEBUG
int
_C1(void)
{
return(C1get);
}
int
_C(void)
{
return(Cget);
}
#endif
void
msputmac(char *s, int constant)
{
char *t;
int found;
int last;
last = 0;
found = 0;
if (wordflag) {
msputwords(YES);
return;
}
while (*s) {
while (*s == ' ' || *s == '\t')
putchar(*s++);
for (t = s ; *t != ' ' && *t != '\t' && *t != '\0' ; ++t)
;
if (*s == '\"')
s++;
if (t > s + constant && chars[(unsigned char)s[0]] == LETTER &&
chars[(unsigned char)s[1]] == LETTER) {
while (s < t)
if (*s == '\"')
s++;
else
putchar(*s++);
last = *(t-1);
found++;
} else if (found && chars[(unsigned char)s[0]] == PUNCT &&
s[1] == '\0') {
putchar(*s++);
} else {
last = *(t - 1);
s = t;
}
}
putchar('\n');
if (msflag && chars[last] == PUNCT) {
putchar(last);
putchar('\n');
}
}
void
msputwords(int macline)
{
char *p, *p1;
int i, nlet;
for (p1 = line;;) {
while (chars[(unsigned char)*p1] < DIGIT)
if (*p1++ == '\0')
return;
nlet = 0;
for (p = p1 ; (i = chars[(unsigned char)*p]) != SPECIAL ; ++p)
if (i == LETTER)
++nlet;
if (nlet > 1 && chars[(unsigned char)p1[0]] == LETTER) {
while ((i = chars[(unsigned char)p[-1]]) == PUNCT ||
i == APOS )
--p;
while (p1 < p)
putchar(*p1++);
putchar('\n');
} else {
p1 = p;
}
}
}
#define SKIPBLANK(cp) while (*cp == ' ' || *cp == '\t') { cp++; }
#define SKIPNONBLANK(cp) while (*cp !=' ' && *cp !='\cp' && *cp !='\0') { cp++; }
void
meputmac(char *cp, int constant)
{
char *np;
int found;
int argno;
int last;
int inquote;
last = 0;
found = 0;
if (wordflag) {
meputwords(YES);
return;
}
for (argno = 0; *cp; argno++) {
SKIPBLANK(cp);
inquote = (*cp == '"');
if (inquote)
cp++;
for (np = cp; *np; np++) {
switch (*np) {
case '\n':
case '\0':
break;
case '\t':
case ' ':
if (inquote)
continue;
else
goto endarg;
case '"':
if (inquote && np[1] == '"') {
memmove(np, np + 1, strlen(np));
np++;
continue;
} else {
*np = ' ';
goto endarg;
}
default:
continue;
}
}
endarg: ;
if ((argconcat == 0) || (argconcat != argno))
putchar(' ');
#ifdef FULLDEBUG
{
char *p;
printf("[%d,%d: ", argno, np - cp);
for (p = cp; p < np; p++) {
putchar(*p);
}
printf("]");
}
#endif
if (((np - cp) > constant) &&
(inquote || (chars[(unsigned char)cp[0]] == LETTER))) {
for (; cp < np; cp++)
putchar(*cp);
last = np[-1];
found++;
} else if (found && (np - cp == 1) &&
chars[(unsigned char)*cp] == PUNCT) {
putchar(*cp);
} else {
last = np[-1];
}
cp = np;
}
if (msflag && chars[last] == PUNCT)
putchar(last);
putchar('\n');
}
void
meputwords(int macline)
{
msputwords(macline);
}
void
noblock(char a1, char a2)
{
int c1,c2;
int eqnf;
int lct;
lct = 0;
eqnf = 1;
SKIP;
for (;;) {
while (C != '.')
if (c == '\n')
continue;
else
SKIP;
if ((c1 = C) == '\n')
continue;
if ((c2 = C) == '\n')
continue;
if (c1 == a1 && c2 == a2) {
SKIP;
if (lct != 0) {
lct--;
continue;
}
if (eqnf)
putchar('.');
putchar('\n');
return;
} else if (a1 == 'L' && c2 == 'L') {
lct++;
SKIP;
}
else if (c1 == 'E' && c2 == 'Q') {
if ((mac == ME && a1 == ')')
|| (mac != ME && a1 == 'D')) {
eqn();
eqnf=0;
}
}
else if (a1 == 'f') {
if ((mac == ME && (c2 == 'h' || c2 == 'p'))
|| (mac != ME && (c1 == 'P' || c2 == 'P'))) {
SKIP;
return;
}
} else {
SKIP;
}
}
}
int
EQ(void)
{
eqn();
return(0);
}
int
domacro(void)
{
macro();
return(0);
}
int
PS(void)
{
for (C; c == ' ' || c == '\t'; C)
;
if (c == '<') {
SKIP;
return(0);
}
if (!msflag)
inpic();
else
noblock('P', 'E');
return(0);
}
int
skip(void)
{
SKIP;
return(0);
}
int
intbl(void)
{
if (msflag)
stbl();
else
tbl();
return(0);
}
int
outtbl(void)
{
intable = NO;
return(0);
}
int
so(void)
{
if (!iflag) {
getfname();
if (fname[0]) {
if (++filesp - &files[0] > MAXFILES)
err(1, "too many nested files (max %d)",
MAXFILES);
infile = *filesp = opn(fname);
}
}
return(0);
}
int
nx(void)
{
if (!iflag) {
getfname();
if (fname[0] == '\0')
exit(0);
if (infile != stdin)
fclose(infile);
infile = *filesp = opn(fname);
}
return(0);
}
int
skiptocom(void)
{
SKIP_TO_COM;
return(COMX);
}
int
PP(pacmac c12)
{
int c1, c2;
frommac(c12, c1, c2);
printf(".%c%c", c1, c2);
while (C != '\n')
putchar(c);
putchar('\n');
return(0);
}
int
AU(void)
{
if (mac == MM)
return(0);
SKIP_TO_COM;
return(COMX);
}
int
SH(pacmac c12)
{
int c1, c2;
frommac(c12, c1, c2);
if (parag) {
printf(".%c%c", c1, c2);
while (C != '\n')
putchar(c);
putchar(c);
putchar('!');
for (;;) {
while (C != '\n')
putchar(c);
putchar('\n');
if (C == '.')
return(COM);
putchar('!');
putchar(c);
}
} else {
SKIP_TO_COM;
return(COMX);
}
}
int
UX(void)
{
if (wordflag)
printf("UNIX\n");
else
printf("UNIX ");
return(0);
}
int
MMHU(pacmac c12)
{
int c1, c2;
frommac(c12, c1, c2);
if (parag) {
printf(".%c%c", c1, c2);
while (C != '\n')
putchar(c);
putchar('\n');
} else {
SKIP;
}
return(0);
}
int
mesnblock(pacmac c12)
{
int c1, c2;
frommac(c12, c1, c2);
noblock(')', c2);
return(0);
}
int
mssnblock(pacmac c12)
{
int c1, c2;
frommac(c12, c1, c2);
noblock(c1, 'E');
return(0);
}
int
nf(void)
{
noblock('f', 'i');
return(0);
}
int
ce(void)
{
sce();
return(0);
}
int
meip(pacmac c12)
{
if (parag)
mepp(c12);
else if (wordflag)
regline(meputmac, ONE);
else
SKIP;
return(0);
}
int
mepp(pacmac c12)
{
PP(c12);
return(0);
}
int
mesh(pacmac c12)
{
if (parag)
mepp(c12);
else if (wordflag)
defcomline(c12);
else
SKIP;
return(0);
}
int
mefont(pacmac c12)
{
argconcat = 1;
defcomline(c12);
argconcat = 0;
return(0);
}
int
manfont(pacmac c12)
{
return(mefont(c12));
}
int
manpp(pacmac c12)
{
return(mepp(c12));
}
void
defcomline(pacmac c12)
{
int c1, c2;
frommac(c12, c1, c2);
if (msflag && mac == MM && c2 == 'L') {
if (disp || c1 == 'R') {
noblock('L', 'E');
} else {
SKIP;
putchar('.');
}
}
else if (c1 == '.' && c2 == '.') {
if (msflag) {
SKIP;
return;
}
while (C == '.')
;
}
++inmacro;
switch (mac) {
default:
case MM:
case MS:
if (c1 <= 'Z' && msflag)
regline(msputmac, ONE);
else
regline(msputmac, TWO);
break;
case ME:
regline(meputmac, ONE);
break;
}
--inmacro;
}
void
comline(void)
{
int c1;
int c2;
pacmac c12;
int mid;
int lb, ub;
int hit;
static int tabsize = 0;
static struct mactab *mactab = NULL;
struct mactab *mp;
if (mactab == 0)
buildtab(&mactab, &tabsize);
com:
while (C == ' ' || c == '\t')
;
comx:
if ((c1 = c) == '\n')
return;
c2 = C;
if (c1 == '.' && c2 != '.')
inmacro = NO;
if (msflag && c1 == '[') {
refer(c2);
return;
}
if (parag && mac==MM && c1 == 'P' && c2 == '\n') {
printf(".P\n");
return;
}
if (c2 == '\n')
return;
if (mac == ME && (c2 == ' ' || c2 == '\t') )
c2 = ' ';
c12 = tomac(c1, c2);
lb = 0;
ub = tabsize - 1;
while (lb <= ub) {
mid = (ub + lb) / 2;
mp = &mactab[mid];
if (mp->macname < c12)
lb = mid + 1;
else if (mp->macname > c12)
ub = mid - 1;
else {
hit = 1;
#ifdef FULLDEBUG
printf("preliminary hit macro %c%c ", c1, c2);
#endif
switch (mp->condition) {
case NONE:
hit = YES;
break;
case FNEST:
hit = (filesp == files);
break;
case NOMAC:
hit = !inmacro;
break;
case MAC:
hit = inmacro;
break;
case PARAG:
hit = parag;
break;
case NBLK:
hit = !keepblock;
break;
default:
hit = 0;
}
if (hit) {
#ifdef FULLDEBUG
printf("MATCH\n");
#endif
switch ((*(mp->func))(c12)) {
default:
return;
case COMX:
goto comx;
case COM:
goto com;
}
}
#ifdef FULLDEBUG
printf("FAIL\n");
#endif
break;
}
}
defcomline(c12);
}
int
macsort(const void *p1, const void *p2)
{
struct mactab *t1 = (struct mactab *)p1;
struct mactab *t2 = (struct mactab *)p2;
return(t1->macname - t2->macname);
}
int
sizetab(struct mactab *mp)
{
int i;
i = 0;
if (mp) {
for (; mp->macname; mp++, i++)
;
}
return(i);
}
struct mactab *
macfill(struct mactab *dst, struct mactab *src)
{
if (src) {
while (src->macname)
*dst++ = *src++;
}
return(dst);
}
__dead void
usage(void)
{
extern char *__progname;
fprintf(stderr, "usage: %s [-ikpw] [-m a | e | l | m | s] [file ...]\n", __progname);
exit(1);
}
void
buildtab(struct mactab **r_back, int *r_size)
{
int size;
struct mactab *p, *p1, *p2;
struct mactab *back;
size = sizetab(troffmactab) + sizetab(ppmactab);
p1 = p2 = NULL;
if (msflag) {
switch (mac) {
case ME:
p1 = memactab;
break;
case MM:
p1 = msmactab;
p2 = mmmactab;
break;
case MS:
p1 = msmactab;
break;
case MA:
p1 = manmactab;
break;
default:
break;
}
}
size += sizetab(p1);
size += sizetab(p2);
back = calloc(size+2, sizeof(struct mactab));
if (back == NULL)
err(1, NULL);
p = macfill(back, troffmactab);
p = macfill(p, ppmactab);
p = macfill(p, p1);
p = macfill(p, p2);
qsort(back, size, sizeof(struct mactab), macsort);
*r_size = size;
*r_back = back;
}
struct mactab troffmactab[] = {
M(NONE, '\\','"', skip),
M(NOMAC, 'd','e', domacro),
M(NOMAC, 'i','g', domacro),
M(NOMAC, 'a','m', domacro),
M(NBLK, 'n','f', nf),
M(NBLK, 'c','e', ce),
M(NONE, 's','o', so),
M(NONE, 'n','x', nx),
M(NONE, 't','m', skip),
M(NONE, 'h','w', skip),
M(NONE, 0,0, 0)
};
struct mactab ppmactab[] = {
M(FNEST, 'E','Q', EQ),
M(FNEST, 'T','S', intbl),
M(FNEST, 'T','C', intbl),
M(FNEST, 'T','&', intbl),
M(NONE, 'T','E', outtbl),
M(NONE, 'P','S', PS),
M(NONE, 0,0, 0)
};
struct mactab msmactab[] = {
M(NONE, 'T','L', skiptocom),
M(NONE, 'F','S', skiptocom),
M(NONE, 'O','K', skiptocom),
M(NONE, 'N','R', skip),
M(NONE, 'N','D', skip),
M(PARAG, 'P','P', PP),
M(PARAG, 'I','P', PP),
M(PARAG, 'L','P', PP),
M(NONE, 'A','U', AU),
M(NONE, 'A','I', AU),
M(NONE, 'S','H', SH),
M(NONE, 'S','N', SH),
M(NONE, 'U','X', UX),
M(NBLK, 'D','S', mssnblock),
M(NBLK, 'K','S', mssnblock),
M(NBLK, 'K','F', mssnblock),
M(NONE, 0,0, 0)
};
struct mactab mmmactab[] = {
M(NONE, 'H',' ', MMHU),
M(NONE, 'H','U', MMHU),
M(PARAG, 'P',' ', PP),
M(NBLK, 'N','S', mssnblock),
M(NONE, 0,0, 0)
};
struct mactab memactab[] = {
M(PARAG, 'p','p', mepp),
M(PARAG, 'l','p', mepp),
M(PARAG, 'n','p', mepp),
M(NONE, 'i','p', meip),
M(NONE, 's','h', mesh),
M(NONE, 'u','h', mesh),
M(NBLK, '(','l', mesnblock),
M(NBLK, '(','q', mesnblock),
M(NBLK, '(','b', mesnblock),
M(NBLK, '(','z', mesnblock),
M(NBLK, '(','c', mesnblock),
M(NBLK, '(','d', mesnblock),
M(NBLK, '(','f', mesnblock),
M(NBLK, '(','x', mesnblock),
M(NONE, 'r',' ', mefont),
M(NONE, 'i',' ', mefont),
M(NONE, 'b',' ', mefont),
M(NONE, 'u',' ', mefont),
M(NONE, 'q',' ', mefont),
M(NONE, 'r','b', mefont),
M(NONE, 'b','i', mefont),
M(NONE, 'b','x', mefont),
M(NONE, 0,0, 0)
};
struct mactab manmactab[] = {
M(PARAG, 'B','I', manfont),
M(PARAG, 'B','R', manfont),
M(PARAG, 'I','B', manfont),
M(PARAG, 'I','R', manfont),
M(PARAG, 'R','B', manfont),
M(PARAG, 'R','I', manfont),
M(PARAG, 'P','P', manpp),
M(PARAG, 'L','P', manpp),
M(PARAG, 'H','P', manpp),
M(NONE, 0,0, 0)
};