Annotation of src/usr.bin/deroff/deroff.c, Revision 1.1
1.1 ! millert 1: /* $OpenBSD$ */
! 2:
! 3: /*-
! 4: * Copyright (c) 1988, 1993
! 5: * The Regents of the University of California. All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: * 3. All advertising materials mentioning features or use of this software
! 16: * must display the following acknowledgement:
! 17: * This product includes software developed by the University of
! 18: * California, Berkeley and its contributors.
! 19: * 4. Neither the name of the University nor the names of its contributors
! 20: * may be used to endorse or promote products derived from this software
! 21: * without specific prior written permission.
! 22: *
! 23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 33: * SUCH DAMAGE.
! 34: */
! 35: /*
! 36: * Copyright (C) Caldera International Inc. 2001-2002.
! 37: * All rights reserved.
! 38: *
! 39: * Redistribution and use in source and binary forms, with or without
! 40: * modification, are permitted provided that the following conditions
! 41: * are met:
! 42: * 1. Redistributions of source code and documentation must retain the above
! 43: * copyright notice, this list of conditions and the following disclaimer.
! 44: * 2. Redistributions in binary form must reproduce the above copyright
! 45: * notice, this list of conditions and the following disclaimer in the
! 46: * documentation and/or other materials provided with the distribution.
! 47: * 3. All advertising materials mentioning features or use of this software
! 48: * must display the following acknowledgement:
! 49: * This product includes software developed or owned by Caldera
! 50: * International, Inc.
! 51: * 4. Neither the name of Caldera International, Inc. nor the names of other
! 52: * contributors may be used to endorse or promote products derived from
! 53: * this software without specific prior written permission.
! 54: *
! 55: * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
! 56: * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
! 57: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 58: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 59: * IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE FOR ANY DIRECT,
! 60: * INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
! 61: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
! 62: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 63: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
! 64: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
! 65: * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
! 66: * POSSIBILITY OF SUCH DAMAGE.
! 67: */
! 68:
! 69: #ifndef lint
! 70: static const char copyright[] =
! 71: "@(#) Copyright (c) 1988, 1993\n\
! 72: The Regents of the University of California. All rights reserved.\n";
! 73: #endif /* not lint */
! 74:
! 75: #ifndef lint
! 76: #if 0
! 77: static const char sccsid[] = "@(#)deroff.c 8.1 (Berkeley) 6/6/93";
! 78: #else
! 79: static const char rcsid[] = "$OpenBSD$";
! 80: #endif
! 81: #endif /* not lint */
! 82:
! 83: #include <err.h>
! 84: #include <limits.h>
! 85: #include <stdio.h>
! 86: #include <stdlib.h>
! 87: #include <string.h>
! 88: #include <unistd.h>
! 89:
! 90: /*
! 91: * Deroff command -- strip troff, eqn, and Tbl sequences from
! 92: * a file. Has two flags argument, -w, to cause output one word per line
! 93: * rather than in the original format.
! 94: * -mm (or -ms) causes the corresponding macro's to be interpreted
! 95: * so that just sentences are output
! 96: * -ml also gets rid of lists.
! 97: * Deroff follows .so and .nx commands, removes contents of macro
! 98: * definitions, equations (both .EQ ... .EN and $...$),
! 99: * Tbl command sequences, and Troff backslash constructions.
! 100: *
! 101: * All input is through the Cget macro;
! 102: * the most recently read character is in c.
! 103: *
! 104: * Modified by Robert Henry to process -me and -man macros.
! 105: */
! 106:
! 107: #define Cget ( (c=getc(infile)) == EOF ? eof() : ((c==ldelim)&&(filesp==files) ? skeqn() : c) )
! 108: #define C1get ( (c=getc(infile)) == EOF ? eof() : c)
! 109:
! 110: #ifdef DEBUG
! 111: # define C _C()
! 112: # define C1 _C1()
! 113: #else not DEBUG
! 114: # define C Cget
! 115: # define C1 C1get
! 116: #endif not DEBUG
! 117:
! 118: #define SKIP while (C != '\n')
! 119: #define SKIP_TO_COM SKIP; SKIP; pc=c; while (C != '.' || pc != '\n' || C > 'Z')pc=c
! 120:
! 121: #define YES 1
! 122: #define NO 0
! 123: #define MS 0 /* -ms */
! 124: #define MM 1 /* -mm */
! 125: #define ME 2 /* -me */
! 126: #define MA 3 /* -man */
! 127:
! 128: #ifdef DEBUG
! 129: char *mactab[] = { "-ms", "-mm", "-me", "-ma" };
! 130: #endif DEBUG
! 131:
! 132: #define ONE 1
! 133: #define TWO 2
! 134:
! 135: #define NOCHAR -2
! 136: #define SPECIAL 0
! 137: #define APOS 1
! 138: #define PUNCT 2
! 139: #define DIGIT 3
! 140: #define LETTER 4
! 141:
! 142: #define MAXFILES 20
! 143:
! 144: int iflag;
! 145: int wordflag;
! 146: int msflag; /* processing a source written using a mac package */
! 147: int mac; /* which package */
! 148: int disp;
! 149: int parag;
! 150: int inmacro;
! 151: int intable;
! 152: int keepblock; /* keep blocks of text; normally false when msflag */
! 153:
! 154: char chars[128]; /* SPECIAL, PUNCT, APOS, DIGIT, or LETTER */
! 155:
! 156: char line[LINE_MAX];
! 157: char *lp;
! 158:
! 159: int c;
! 160: int pc;
! 161: int ldelim;
! 162: int rdelim;
! 163:
! 164: char fname[PATH_MAX];
! 165: FILE *files[MAXFILES];
! 166: FILE **filesp;
! 167: FILE *infile;
! 168:
! 169: int argc;
! 170: char **argv;
! 171:
! 172: /*
! 173: * Macro processing
! 174: *
! 175: * Macro table definitions
! 176: */
! 177: typedef int pacmac; /* compressed macro name */
! 178: int argconcat = 0; /* concat arguments together (-me only) */
! 179:
! 180: #define tomac(c1, c2) ((((c1) & 0xFF) << 8) | ((c2) & 0xFF))
! 181: #define frommac(src, c1, c2) (((c1)=((src)>>8)&0xFF),((c2) =(src)&0xFF))
! 182:
! 183: struct mactab{
! 184: int condition;
! 185: pacmac macname;
! 186: int (*func)(); /* XXX - args */
! 187: };
! 188:
! 189: struct mactab troffmactab[];
! 190: struct mactab ppmactab[];
! 191: struct mactab msmactab[];
! 192: struct mactab mmmactab[];
! 193: struct mactab memactab[];
! 194: struct mactab manmactab[];
! 195:
! 196: /*
! 197: * Macro table initialization
! 198: */
! 199: #define M(cond, c1, c2, func) {cond, tomac(c1, c2), func}
! 200:
! 201: /*
! 202: * Flags for matching conditions other than
! 203: * the macro name
! 204: */
! 205: #define NONE 0
! 206: #define FNEST 1 /* no nested files */
! 207: #define NOMAC 2 /* no macro */
! 208: #define MAC 3 /* macro */
! 209: #define PARAG 4 /* in a paragraph */
! 210: #define MSF 5 /* msflag is on */
! 211: #define NBLK 6 /* set if no blocks to be kept */
! 212:
! 213: /*
! 214: * Return codes from macro minions, determine where to jump,
! 215: * how to repeat/reprocess text
! 216: */
! 217: #define COMX 1 /* goto comx */
! 218: #define COM 2 /* goto com */
! 219:
! 220: int skeqn(void);
! 221: int eof(void);
! 222: int _C1(void);
! 223: int _C(void);
! 224: int EQ(void);
! 225: int domacro(void);
! 226: int PS(void);
! 227: int skip(void);
! 228: int intbl(void);
! 229: int outtbl(void);
! 230: int so(void);
! 231: int nx(void);
! 232: int skiptocom(void);
! 233: int PP(pacmac);
! 234: int AU(void);
! 235: int SH(pacmac);
! 236: int UX(void);
! 237: int MMHU(pacmac);
! 238: int mesnblock(pacmac);
! 239: int mssnblock(pacmac);
! 240: int nf(void);
! 241: int ce(void);
! 242: int meip(pacmac);
! 243: int mepp(pacmac);
! 244: int mesh(pacmac);
! 245: int mefont(pacmac);
! 246: int manfont(pacmac);
! 247: int manpp(pacmac);
! 248: int macsort(const void *, const void *);
! 249: int sizetab(struct mactab *);
! 250: void getfname(void);
! 251: void textline(char *, int);
! 252: void work(void);
! 253: void regline(void (*)(char *, int), int);
! 254: void macro(void);
! 255: void tbl(void);
! 256: void stbl(void);
! 257: void eqn(void);
! 258: void backsl(void);
! 259: void sce(void);
! 260: void refer(int);
! 261: void inpic(void);
! 262: void msputmac(char *, int);
! 263: void msputwords(int);
! 264: void meputmac(char *, int);
! 265: void meputwords(int);
! 266: void noblock(char, char);
! 267: void defcomline(pacmac);
! 268: void comline(void);
! 269: void buildtab(struct mactab **, int *);
! 270: FILE *opn(char *);
! 271: struct mactab *macfill(struct mactab *, struct mactab *);
! 272: __dead void usage(void);
! 273:
! 274: int
! 275: main(int ac, char **av)
! 276: {
! 277: int i, ch;
! 278: int errflg = 0;
! 279: int kflag = NO;
! 280:
! 281: iflag = NO;
! 282: wordflag = NO;
! 283: msflag = NO;
! 284: mac = ME;
! 285: disp = NO;
! 286: parag = NO;
! 287: inmacro = NO;
! 288: intable = NO;
! 289: ldelim = NOCHAR;
! 290: rdelim = NOCHAR;
! 291: keepblock = YES;
! 292:
! 293: while ((ch = getopt(ac, av, "ikpwm:")) != -1) {
! 294: switch (ch) {
! 295: case 'i':
! 296: iflag = YES;
! 297: break;
! 298: case 'k':
! 299: kflag = YES;
! 300: break;
! 301: case 'm':
! 302: msflag = YES;
! 303: keepblock = NO;
! 304: switch (optarg[0]) {
! 305: case 'm':
! 306: mac = MM;
! 307: break;
! 308: case 's':
! 309: mac = MS;
! 310: break;
! 311: case 'e':
! 312: mac = ME;
! 313: break;
! 314: case 'a':
! 315: mac = MA;
! 316: break;
! 317: case 'l':
! 318: disp = YES;
! 319: break;
! 320: default:
! 321: errflg++;
! 322: break;
! 323: }
! 324: if (errflg == 0 && optarg[1] != '\0')
! 325: errflg++;
! 326: break;
! 327: case 'p':
! 328: parag = YES;
! 329: break;
! 330: case 'w':
! 331: wordflag = YES;
! 332: kflag = YES;
! 333: break;
! 334: default:
! 335: errflg++;
! 336: }
! 337: }
! 338: argc = ac - optind;
! 339: argv = av + optind;
! 340:
! 341: if (kflag)
! 342: keepblock = YES;
! 343: if (errflg)
! 344: usage();
! 345:
! 346: #ifdef DEBUG
! 347: printf("msflag = %d, mac = %s, keepblock = %d, disp = %d\n",
! 348: msflag, mactab[mac], keepblock, disp);
! 349: #endif DEBUG
! 350: if (argc == 0) {
! 351: infile = stdin;
! 352: } else {
! 353: infile = opn(argv[0]);
! 354: --argc;
! 355: ++argv;
! 356: }
! 357: files[0] = infile;
! 358: filesp = &files[0];
! 359:
! 360: for (i = 'a'; i <= 'z' ; ++i)
! 361: chars[i] = LETTER;
! 362: for (i = 'A'; i <= 'Z'; ++i)
! 363: chars[i] = LETTER;
! 364: for (i = '0'; i <= '9'; ++i)
! 365: chars[i] = DIGIT;
! 366: chars['\''] = APOS;
! 367: chars['&'] = APOS;
! 368: chars['.'] = PUNCT;
! 369: chars[','] = PUNCT;
! 370: chars[';'] = PUNCT;
! 371: chars['?'] = PUNCT;
! 372: chars[':'] = PUNCT;
! 373: work();
! 374: exit(0);
! 375: }
! 376:
! 377: int
! 378: skeqn(void)
! 379: {
! 380:
! 381: while ((c = getc(infile)) != rdelim) {
! 382: if (c == EOF)
! 383: c = eof();
! 384: else if (c == '"') {
! 385: while ((c = getc(infile)) != '"') {
! 386: if (c == EOF ||
! 387: (c == '\\' && (c = getc(infile)) == EOF))
! 388: c = eof();
! 389: }
! 390: }
! 391: }
! 392: if (msflag)
! 393: return((c = 'x'));
! 394: return((c = ' '));
! 395: }
! 396:
! 397: FILE *
! 398: opn(char *p)
! 399: {
! 400: FILE *fd;
! 401:
! 402: if ((fd = fopen(p, "r")) == NULL)
! 403: err(1, "fopen %s", p);
! 404:
! 405: return(fd);
! 406: }
! 407:
! 408: int
! 409: eof(void)
! 410: {
! 411:
! 412: if (infile != stdin)
! 413: fclose(infile);
! 414: if (filesp > files)
! 415: infile = *--filesp;
! 416: else if (argc > 0) {
! 417: infile = opn(argv[0]);
! 418: --argc;
! 419: ++argv;
! 420: } else
! 421: exit(0);
! 422: return(C);
! 423: }
! 424:
! 425: void
! 426: getfname(void)
! 427: {
! 428: char *p;
! 429: struct chain {
! 430: struct chain *nextp;
! 431: char *datap;
! 432: } *q;
! 433: static struct chain *namechain= NULL;
! 434:
! 435: while (C == ' ')
! 436: ; /* nothing */
! 437:
! 438: for (p = fname ; p - fname < sizeof(fname) && (*p = c) != '\n' &&
! 439: c != ' ' && c != '\t' && c != '\\'; ++p)
! 440: C;
! 441: *p = '\0';
! 442: while (c != '\n')
! 443: C;
! 444:
! 445: /* see if this name has already been used */
! 446: for (q = namechain ; q; q = q->nextp)
! 447: if (strcmp(fname, q->datap) == 0) {
! 448: fname[0] = '\0';
! 449: return;
! 450: }
! 451:
! 452: q = (struct chain *) malloc(sizeof(struct chain));
! 453: if (q == NULL)
! 454: err(1, "malloc");
! 455: q->nextp = namechain;
! 456: q->datap = strdup(fname);
! 457: if (q->datap == NULL)
! 458: err(1, "strdup");
! 459: namechain = q;
! 460: }
! 461:
! 462: /*ARGSUSED*/
! 463: void
! 464: textline(char *str, int constant)
! 465: {
! 466:
! 467: if (wordflag) {
! 468: msputwords(0);
! 469: return;
! 470: }
! 471: puts(str);
! 472: }
! 473:
! 474: void
! 475: work(void)
! 476: {
! 477:
! 478: for (;;) {
! 479: C;
! 480: #ifdef FULLDEBUG
! 481: printf("Starting work with `%c'\n", c);
! 482: #endif FULLDEBUG
! 483: if (c == '.' || c == '\'')
! 484: comline();
! 485: else
! 486: regline(textline, TWO);
! 487: }
! 488: }
! 489:
! 490: void
! 491: regline(void (*pfunc)(char *, int), int constant)
! 492: {
! 493:
! 494: line[0] = c;
! 495: lp = line;
! 496: while (lp - line < sizeof(line)) {
! 497: if (c == '\\') {
! 498: *lp = ' ';
! 499: backsl();
! 500: }
! 501: if (c == '\n')
! 502: break;
! 503: if (intable && c == 'T') {
! 504: *++lp = C;
! 505: if (c == '{' || c == '}') {
! 506: lp[-1] = ' ';
! 507: *lp = C;
! 508: }
! 509: } else {
! 510: *++lp = C;
! 511: }
! 512: }
! 513: *lp = '\0';
! 514:
! 515: if (line[0] != '\0')
! 516: (*pfunc)(line, constant);
! 517: }
! 518:
! 519: void
! 520: macro(void)
! 521: {
! 522:
! 523: if (msflag) {
! 524: do {
! 525: SKIP;
! 526: } while (C!='.' || C!='.' || C=='.'); /* look for .. */
! 527: if (c != '\n')
! 528: SKIP;
! 529: return;
! 530: }
! 531: SKIP;
! 532: inmacro = YES;
! 533: }
! 534:
! 535: void
! 536: tbl(void)
! 537: {
! 538:
! 539: while (C != '.')
! 540: ; /* nothing */
! 541: SKIP;
! 542: intable = YES;
! 543: }
! 544:
! 545: void
! 546: stbl(void)
! 547: {
! 548:
! 549: while (C != '.')
! 550: ; /* nothing */
! 551: SKIP_TO_COM;
! 552: if (c != 'T' || C != 'E') {
! 553: SKIP;
! 554: pc = c;
! 555: while (C != '.' || pc != '\n' || C != 'T' || C != 'E')
! 556: pc = c;
! 557: }
! 558: }
! 559:
! 560: void
! 561: eqn(void)
! 562: {
! 563: int c1, c2;
! 564: int dflg;
! 565: char last;
! 566:
! 567: last=0;
! 568: dflg = 1;
! 569: SKIP;
! 570:
! 571: for (;;) {
! 572: if (C1 == '.' || c == '\'') {
! 573: while (C1 == ' ' || c == '\t')
! 574: ;
! 575: if (c == 'E' && C1 == 'N') {
! 576: SKIP;
! 577: if (msflag && dflg) {
! 578: putchar('x');
! 579: putchar(' ');
! 580: if (last) {
! 581: putchar(last);
! 582: putchar('\n');
! 583: }
! 584: }
! 585: return;
! 586: }
! 587: } else if (c == 'd') {
! 588: /* look for delim */
! 589: if (C1 == 'e' && C1 == 'l')
! 590: if (C1 == 'i' && C1 == 'm') {
! 591: while (C1 == ' ')
! 592: ; /* nothing */
! 593:
! 594: if ((c1 = c) == '\n' ||
! 595: (c2 = C1) == '\n' ||
! 596: (c1 == 'o' && c2 == 'f' && C1=='f')) {
! 597: ldelim = NOCHAR;
! 598: rdelim = NOCHAR;
! 599: } else {
! 600: ldelim = c1;
! 601: rdelim = c2;
! 602: }
! 603: }
! 604: dflg = 0;
! 605: }
! 606:
! 607: if (c != '\n')
! 608: while (C1 != '\n') {
! 609: if (chars[c] == PUNCT)
! 610: last = c;
! 611: else if (c != ' ')
! 612: last = 0;
! 613: }
! 614: }
! 615: }
! 616:
! 617: /* skip over a complete backslash construction */
! 618: void
! 619: backsl(void)
! 620: {
! 621: int bdelim;
! 622:
! 623: sw:
! 624: switch (C) {
! 625: case '"':
! 626: SKIP;
! 627: return;
! 628:
! 629: case 's':
! 630: if (C == '\\')
! 631: backsl();
! 632: else {
! 633: while (C >= '0' && c <= '9')
! 634: ; /* nothing */
! 635: ungetc(c, infile);
! 636: c = '0';
! 637: }
! 638: --lp;
! 639: return;
! 640:
! 641: case 'f':
! 642: case 'n':
! 643: case '*':
! 644: if (C != '(')
! 645: return;
! 646:
! 647: case '(':
! 648: if (msflag) {
! 649: if (C == 'e') {
! 650: if (C == 'm') {
! 651: *lp = '-';
! 652: return;
! 653: }
! 654: }
! 655: else if (c != '\n')
! 656: C;
! 657: return;
! 658: }
! 659: if (C != '\n')
! 660: C;
! 661: return;
! 662:
! 663: case '$':
! 664: C; /* discard argument number */
! 665: return;
! 666:
! 667: case 'b':
! 668: case 'x':
! 669: case 'v':
! 670: case 'h':
! 671: case 'w':
! 672: case 'o':
! 673: case 'l':
! 674: case 'L':
! 675: if ((bdelim = C) == '\n')
! 676: return;
! 677: while (C != '\n' && c != bdelim)
! 678: if (c == '\\')
! 679: backsl();
! 680: return;
! 681:
! 682: case '\\':
! 683: if (inmacro)
! 684: goto sw;
! 685:
! 686: default:
! 687: return;
! 688: }
! 689: }
! 690:
! 691: void
! 692: sce(void)
! 693: {
! 694: char *ap;
! 695: int n, i;
! 696: char a[10];
! 697:
! 698: for (ap = a; C != '\n'; ap++) {
! 699: *ap = c;
! 700: if (ap == &a[9]) {
! 701: SKIP;
! 702: ap = a;
! 703: break;
! 704: }
! 705: }
! 706: if (ap != a)
! 707: n = atoi(a);
! 708: else
! 709: n = 1;
! 710: for (i = 0; i < n;) {
! 711: if (C == '.') {
! 712: if (C == 'c') {
! 713: if (C == 'e') {
! 714: while (C == ' ')
! 715: ; /* nothing */
! 716: if (c == '0') {
! 717: SKIP;
! 718: break;
! 719: } else
! 720: SKIP;
! 721: }
! 722: else
! 723: SKIP;
! 724: } else if (c == 'P' || C == 'P') {
! 725: if (c != '\n')
! 726: SKIP;
! 727: break;
! 728: } else if (c != '\n')
! 729: SKIP;
! 730: } else {
! 731: SKIP;
! 732: i++;
! 733: }
! 734: }
! 735: }
! 736:
! 737: void
! 738: refer(int c1)
! 739: {
! 740: int c2;
! 741:
! 742: if (c1 != '\n')
! 743: SKIP;
! 744:
! 745: for (c2 = -1;;) {
! 746: if (C != '.')
! 747: SKIP;
! 748: else {
! 749: if (C != ']')
! 750: SKIP;
! 751: else {
! 752: while (C != '\n')
! 753: c2 = c;
! 754: if (c2 != -1 && chars[c2] == PUNCT)
! 755: putchar(c2);
! 756: return;
! 757: }
! 758: }
! 759: }
! 760: }
! 761:
! 762: void
! 763: inpic(void)
! 764: {
! 765: int c1;
! 766: char *p1;
! 767:
! 768: SKIP;
! 769: p1 = line;
! 770: c = '\n';
! 771: for (;;) {
! 772: c1 = c;
! 773: if (C == '.' && c1 == '\n') {
! 774: if (C != 'P') {
! 775: if (c == '\n')
! 776: continue;
! 777: else {
! 778: SKIP;
! 779: c = '\n';
! 780: continue;
! 781: }
! 782: }
! 783: if (C != 'E') {
! 784: if (c == '\n')
! 785: continue;
! 786: else {
! 787: SKIP;
! 788: c = '\n';
! 789: continue;
! 790: }
! 791: }
! 792: SKIP;
! 793: return;
! 794: }
! 795: else if (c == '\"') {
! 796: while (C != '\"') {
! 797: if (c == '\\') {
! 798: if (C == '\"')
! 799: continue;
! 800: ungetc(c, infile);
! 801: backsl();
! 802: } else
! 803: *p1++ = c;
! 804: }
! 805: *p1++ = ' ';
! 806: }
! 807: else if (c == '\n' && p1 != line) {
! 808: *p1 = '\0';
! 809: if (wordflag)
! 810: msputwords(NO);
! 811: else {
! 812: puts(line);
! 813: putchar('\n');
! 814: }
! 815: p1 = line;
! 816: }
! 817: }
! 818: }
! 819:
! 820: #ifdef DEBUG
! 821: int
! 822: _C1(void)
! 823: {
! 824:
! 825: return(C1get);
! 826: }
! 827:
! 828: int
! 829: _C(void)
! 830: {
! 831:
! 832: return(Cget);
! 833: }
! 834: #endif DEBUG
! 835:
! 836: /*
! 837: * Put out a macro line, using ms and mm conventions.
! 838: */
! 839: void
! 840: msputmac(char *s, int constant)
! 841: {
! 842: char *t;
! 843: int found;
! 844: int last;
! 845:
! 846: last = 0;
! 847: found = 0;
! 848: if (wordflag) {
! 849: msputwords(YES);
! 850: return;
! 851: }
! 852: while (*s) {
! 853: while (*s == ' ' || *s == '\t')
! 854: putchar(*s++);
! 855: for (t = s ; *t != ' ' && *t != '\t' && *t != '\0' ; ++t)
! 856: ; /* nothing */
! 857: if (*s == '\"')
! 858: s++;
! 859: if (t > s + constant && chars[(unsigned char)s[0]] == LETTER &&
! 860: chars[(unsigned char)s[1]] == LETTER) {
! 861: while (s < t)
! 862: if (*s == '\"')
! 863: s++;
! 864: else
! 865: putchar(*s++);
! 866: last = *(t-1);
! 867: found++;
! 868: } else if (found && chars[(unsigned char)s[0]] == PUNCT &&
! 869: s[1] == '\0') {
! 870: putchar(*s++);
! 871: } else {
! 872: last = *(t - 1);
! 873: s = t;
! 874: }
! 875: }
! 876: putchar('\n');
! 877: if (msflag && chars[last] == PUNCT) {
! 878: putchar(last);
! 879: putchar('\n');
! 880: }
! 881: }
! 882:
! 883: /*
! 884: * put out words (for the -w option) with ms and mm conventions
! 885: */
! 886: void
! 887: msputwords(int macline)
! 888: {
! 889: char *p, *p1;
! 890: int i, nlet;
! 891:
! 892: for (p1 = line;;) {
! 893: /*
! 894: * skip initial specials ampersands and apostrophes
! 895: */
! 896: while (chars[(unsigned char)*p1] < DIGIT)
! 897: if (*p1++ == '\0')
! 898: return;
! 899: nlet = 0;
! 900: for (p = p1 ; (i = chars[(unsigned char)*p]) != SPECIAL ; ++p)
! 901: if (i == LETTER)
! 902: ++nlet;
! 903:
! 904: if (nlet > 1 && chars[(unsigned char)p1[0]] == LETTER) {
! 905: /*
! 906: * delete trailing ampersands and apostrophes
! 907: */
! 908: while ((i = chars[(unsigned char)p[-1]]) == PUNCT ||
! 909: i == APOS )
! 910: --p;
! 911: while (p1 < p)
! 912: putchar(*p1++);
! 913: putchar('\n');
! 914: } else {
! 915: p1 = p;
! 916: }
! 917: }
! 918: }
! 919:
! 920: /*
! 921: * put out a macro using the me conventions
! 922: */
! 923: #define SKIPBLANK(cp) while (*cp == ' ' || *cp == '\t') { cp++; }
! 924: #define SKIPNONBLANK(cp) while (*cp !=' ' && *cp !='\cp' && *cp !='\0') { cp++; }
! 925:
! 926: void
! 927: meputmac(char *cp, int constant)
! 928: {
! 929: char *np;
! 930: int found;
! 931: int argno;
! 932: int last;
! 933: int inquote;
! 934:
! 935: last = 0;
! 936: found = 0;
! 937: if (wordflag) {
! 938: meputwords(YES);
! 939: return;
! 940: }
! 941: for (argno = 0; *cp; argno++) {
! 942: SKIPBLANK(cp);
! 943: inquote = (*cp == '"');
! 944: if (inquote)
! 945: cp++;
! 946: for (np = cp; *np; np++) {
! 947: switch (*np) {
! 948: case '\n':
! 949: case '\0':
! 950: break;
! 951:
! 952: case '\t':
! 953: case ' ':
! 954: if (inquote)
! 955: continue;
! 956: else
! 957: goto endarg;
! 958:
! 959: case '"':
! 960: if (inquote && np[1] == '"') {
! 961: strcpy(np, np + 1);
! 962: np++;
! 963: continue;
! 964: } else {
! 965: *np = ' '; /* bye bye " */
! 966: goto endarg;
! 967: }
! 968:
! 969: default:
! 970: continue;
! 971: }
! 972: }
! 973: endarg: ;
! 974: /*
! 975: * cp points at the first char in the arg
! 976: * np points one beyond the last char in the arg
! 977: */
! 978: if ((argconcat == 0) || (argconcat != argno))
! 979: putchar(' ');
! 980: #ifdef FULLDEBUG
! 981: {
! 982: char *p;
! 983: printf("[%d,%d: ", argno, np - cp);
! 984: for (p = cp; p < np; p++) {
! 985: putchar(*p);
! 986: }
! 987: printf("]");
! 988: }
! 989: #endif FULLDEBUG
! 990: /*
! 991: * Determine if the argument merits being printed
! 992: *
! 993: * constant is the cut off point below which something
! 994: * is not a word.
! 995: */
! 996: if (((np - cp) > constant) &&
! 997: (inquote || (chars[(unsigned char)cp[0]] == LETTER))) {
! 998: for (cp = cp; cp < np; cp++)
! 999: putchar(*cp);
! 1000: last = np[-1];
! 1001: found++;
! 1002: } else if (found && (np - cp == 1) &&
! 1003: chars[(unsigned char)*cp] == PUNCT) {
! 1004: putchar(*cp);
! 1005: } else {
! 1006: last = np[-1];
! 1007: }
! 1008: cp = np;
! 1009: }
! 1010: if (msflag && chars[last] == PUNCT)
! 1011: putchar(last);
! 1012: putchar('\n');
! 1013: }
! 1014:
! 1015: /*
! 1016: * put out words (for the -w option) with ms and mm conventions
! 1017: */
! 1018: void
! 1019: meputwords(int macline)
! 1020: {
! 1021:
! 1022: msputwords(macline);
! 1023: }
! 1024:
! 1025: /*
! 1026: *
! 1027: * Skip over a nested set of macros
! 1028: *
! 1029: * Possible arguments to noblock are:
! 1030: *
! 1031: * fi end of unfilled text
! 1032: * PE pic ending
! 1033: * DE display ending
! 1034: *
! 1035: * for ms and mm only:
! 1036: * KE keep ending
! 1037: *
! 1038: * NE undocumented match to NS (for mm?)
! 1039: * LE mm only: matches RL or *L (for lists)
! 1040: *
! 1041: * for me:
! 1042: * ([lqbzcdf]
! 1043: */
! 1044: void
! 1045: noblock(char a1, char a2)
! 1046: {
! 1047: int c1,c2;
! 1048: int eqnf;
! 1049: int lct;
! 1050:
! 1051: lct = 0;
! 1052: eqnf = 1;
! 1053: SKIP;
! 1054: for (;;) {
! 1055: while (C != '.')
! 1056: if (c == '\n')
! 1057: continue;
! 1058: else
! 1059: SKIP;
! 1060: if ((c1 = C) == '\n')
! 1061: continue;
! 1062: if ((c2 = C) == '\n')
! 1063: continue;
! 1064: if (c1 == a1 && c2 == a2) {
! 1065: SKIP;
! 1066: if (lct != 0) {
! 1067: lct--;
! 1068: continue;
! 1069: }
! 1070: if (eqnf)
! 1071: putchar('.');
! 1072: putchar('\n');
! 1073: return;
! 1074: } else if (a1 == 'L' && c2 == 'L') {
! 1075: lct++;
! 1076: SKIP;
! 1077: }
! 1078: /*
! 1079: * equations (EQ) nested within a display
! 1080: */
! 1081: else if (c1 == 'E' && c2 == 'Q') {
! 1082: if ((mac == ME && a1 == ')')
! 1083: || (mac != ME && a1 == 'D')) {
! 1084: eqn();
! 1085: eqnf=0;
! 1086: }
! 1087: }
! 1088: /*
! 1089: * turning on filling is done by the paragraphing
! 1090: * macros
! 1091: */
! 1092: else if (a1 == 'f') { /* .fi */
! 1093: if ((mac == ME && (c2 == 'h' || c2 == 'p'))
! 1094: || (mac != ME && (c1 == 'P' || c2 == 'P'))) {
! 1095: SKIP;
! 1096: return;
! 1097: }
! 1098: } else {
! 1099: SKIP;
! 1100: }
! 1101: }
! 1102: }
! 1103:
! 1104: int
! 1105: EQ(void)
! 1106: {
! 1107:
! 1108: eqn();
! 1109: return(0);
! 1110: }
! 1111:
! 1112: int
! 1113: domacro(void)
! 1114: {
! 1115:
! 1116: macro();
! 1117: return(0);
! 1118: }
! 1119:
! 1120: int
! 1121: PS(void)
! 1122: {
! 1123:
! 1124: for (C; c == ' ' || c == '\t'; C)
! 1125: ; /* nothing */
! 1126:
! 1127: if (c == '<') { /* ".PS < file" -- don't expect a .PE */
! 1128: SKIP;
! 1129: return(0);
! 1130: }
! 1131: if (!msflag)
! 1132: inpic();
! 1133: else
! 1134: noblock('P', 'E');
! 1135: return(0);
! 1136: }
! 1137:
! 1138: int
! 1139: skip(void)
! 1140: {
! 1141:
! 1142: SKIP;
! 1143: return(0);
! 1144: }
! 1145:
! 1146: int
! 1147: intbl(void)
! 1148: {
! 1149:
! 1150: if (msflag)
! 1151: stbl();
! 1152: else
! 1153: tbl();
! 1154: return(0);
! 1155: }
! 1156:
! 1157: int
! 1158: outtbl(void)
! 1159: {
! 1160:
! 1161: intable = NO;
! 1162: return(0);
! 1163: }
! 1164:
! 1165: int
! 1166: so(void)
! 1167: {
! 1168:
! 1169: if (!iflag) {
! 1170: getfname();
! 1171: if (fname[0]) {
! 1172: if (++filesp - &files[0] > MAXFILES)
! 1173: err(1, "too many nested files (max %d)",
! 1174: MAXFILES);
! 1175: infile = *filesp = opn(fname);
! 1176: }
! 1177: }
! 1178: return(0);
! 1179: }
! 1180:
! 1181: int
! 1182: nx(void)
! 1183: {
! 1184:
! 1185: if (!iflag) {
! 1186: getfname();
! 1187: if (fname[0] == '\0')
! 1188: exit(0);
! 1189: if (infile != stdin)
! 1190: fclose(infile);
! 1191: infile = *filesp = opn(fname);
! 1192: }
! 1193: return(0);
! 1194: }
! 1195:
! 1196: int
! 1197: skiptocom(void)
! 1198: {
! 1199:
! 1200: SKIP_TO_COM;
! 1201: return(COMX);
! 1202: }
! 1203:
! 1204: int
! 1205: PP(pacmac c12)
! 1206: {
! 1207: int c1, c2;
! 1208:
! 1209: frommac(c12, c1, c2);
! 1210: printf(".%c%c", c1, c2);
! 1211: while (C != '\n')
! 1212: putchar(c);
! 1213: putchar('\n');
! 1214: return(0);
! 1215: }
! 1216:
! 1217: int
! 1218: AU(void)
! 1219: {
! 1220:
! 1221: if (mac == MM)
! 1222: return(0);
! 1223: SKIP_TO_COM;
! 1224: return(COMX);
! 1225: }
! 1226:
! 1227: int
! 1228: SH(pacmac c12)
! 1229: {
! 1230: int c1, c2;
! 1231:
! 1232: frommac(c12, c1, c2);
! 1233:
! 1234: if (parag) {
! 1235: printf(".%c%c", c1, c2);
! 1236: while (C != '\n')
! 1237: putchar(c);
! 1238: putchar(c);
! 1239: putchar('!');
! 1240: for (;;) {
! 1241: while (C != '\n')
! 1242: putchar(c);
! 1243: putchar('\n');
! 1244: if (C == '.')
! 1245: return(COM);
! 1246: putchar('!');
! 1247: putchar(c);
! 1248: }
! 1249: /*NOTREACHED*/
! 1250: } else {
! 1251: SKIP_TO_COM;
! 1252: return(COMX);
! 1253: }
! 1254: }
! 1255:
! 1256: int
! 1257: UX(void)
! 1258: {
! 1259:
! 1260: if (wordflag)
! 1261: printf("UNIX\n");
! 1262: else
! 1263: printf("UNIX ");
! 1264: return(0);
! 1265: }
! 1266:
! 1267: int
! 1268: MMHU(pacmac c12)
! 1269: {
! 1270: int c1, c2;
! 1271:
! 1272: frommac(c12, c1, c2);
! 1273: if (parag) {
! 1274: printf(".%c%c", c1, c2);
! 1275: while (C != '\n')
! 1276: putchar(c);
! 1277: putchar('\n');
! 1278: } else {
! 1279: SKIP;
! 1280: }
! 1281: return(0);
! 1282: }
! 1283:
! 1284: int
! 1285: mesnblock(pacmac c12)
! 1286: {
! 1287: int c1, c2;
! 1288:
! 1289: frommac(c12, c1, c2);
! 1290: noblock(')', c2);
! 1291: return(0);
! 1292: }
! 1293:
! 1294: int
! 1295: mssnblock(pacmac c12)
! 1296: {
! 1297: int c1, c2;
! 1298:
! 1299: frommac(c12, c1, c2);
! 1300: noblock(c1, 'E');
! 1301: return(0);
! 1302: }
! 1303:
! 1304: int
! 1305: nf(void)
! 1306: {
! 1307:
! 1308: noblock('f', 'i');
! 1309: return(0);
! 1310: }
! 1311:
! 1312: int
! 1313: ce(void)
! 1314: {
! 1315:
! 1316: sce();
! 1317: return(0);
! 1318: }
! 1319:
! 1320: int
! 1321: meip(pacmac c12)
! 1322: {
! 1323:
! 1324: if (parag)
! 1325: mepp(c12);
! 1326: else if (wordflag) /* save the tag */
! 1327: regline(meputmac, ONE);
! 1328: else
! 1329: SKIP;
! 1330: return(0);
! 1331: }
! 1332:
! 1333: /*
! 1334: * only called for -me .pp or .sh, when parag is on
! 1335: */
! 1336: int
! 1337: mepp(pacmac c12)
! 1338: {
! 1339:
! 1340: PP(c12); /* eats the line */
! 1341: return(0);
! 1342: }
! 1343:
! 1344: /*
! 1345: * Start of a section heading; output the section name if doing words
! 1346: */
! 1347: int
! 1348: mesh(pacmac c12)
! 1349: {
! 1350:
! 1351: if (parag)
! 1352: mepp(c12);
! 1353: else if (wordflag)
! 1354: defcomline(c12);
! 1355: else
! 1356: SKIP;
! 1357: return(0);
! 1358: }
! 1359:
! 1360: /*
! 1361: * process a font setting
! 1362: */
! 1363: int
! 1364: mefont(pacmac c12)
! 1365: {
! 1366:
! 1367: argconcat = 1;
! 1368: defcomline(c12);
! 1369: argconcat = 0;
! 1370: return(0);
! 1371: }
! 1372:
! 1373: int
! 1374: manfont(pacmac c12)
! 1375: {
! 1376:
! 1377: return(mefont(c12));
! 1378: }
! 1379:
! 1380: int
! 1381: manpp(pacmac c12)
! 1382: {
! 1383:
! 1384: return(mepp(c12));
! 1385: }
! 1386:
! 1387: void
! 1388: defcomline(pacmac c12)
! 1389: {
! 1390: int c1, c2;
! 1391:
! 1392: frommac(c12, c1, c2);
! 1393: if (msflag && mac == MM && c2 == 'L') {
! 1394: if (disp || c1 == 'R') {
! 1395: noblock('L', 'E');
! 1396: } else {
! 1397: SKIP;
! 1398: putchar('.');
! 1399: }
! 1400: }
! 1401: else if (c1 == '.' && c2 == '.') {
! 1402: if (msflag) {
! 1403: SKIP;
! 1404: return;
! 1405: }
! 1406: while (C == '.')
! 1407: /*VOID*/;
! 1408: }
! 1409: ++inmacro;
! 1410: /*
! 1411: * Process the arguments to the macro
! 1412: */
! 1413: switch (mac) {
! 1414: default:
! 1415: case MM:
! 1416: case MS:
! 1417: if (c1 <= 'Z' && msflag)
! 1418: regline(msputmac, ONE);
! 1419: else
! 1420: regline(msputmac, TWO);
! 1421: break;
! 1422: case ME:
! 1423: regline(meputmac, ONE);
! 1424: break;
! 1425: }
! 1426: --inmacro;
! 1427: }
! 1428:
! 1429: void
! 1430: comline(void)
! 1431: {
! 1432: int c1;
! 1433: int c2;
! 1434: pacmac c12;
! 1435: int mid;
! 1436: int lb, ub;
! 1437: int hit;
! 1438: static int tabsize = 0;
! 1439: static struct mactab *mactab = (struct mactab *)0;
! 1440: struct mactab *mp;
! 1441:
! 1442: if (mactab == 0)
! 1443: buildtab(&mactab, &tabsize);
! 1444: com:
! 1445: while (C == ' ' || c == '\t')
! 1446: ;
! 1447: comx:
! 1448: if ((c1 = c) == '\n')
! 1449: return;
! 1450: c2 = C;
! 1451: if (c1 == '.' && c2 != '.')
! 1452: inmacro = NO;
! 1453: if (msflag && c1 == '[') {
! 1454: refer(c2);
! 1455: return;
! 1456: }
! 1457: if (parag && mac==MM && c1 == 'P' && c2 == '\n') {
! 1458: printf(".P\n");
! 1459: return;
! 1460: }
! 1461: if (c2 == '\n')
! 1462: return;
! 1463: /*
! 1464: * Single letter macro
! 1465: */
! 1466: if (mac == ME && (c2 == ' ' || c2 == '\t') )
! 1467: c2 = ' ';
! 1468: c12 = tomac(c1, c2);
! 1469: /*
! 1470: * binary search through the table of macros
! 1471: */
! 1472: lb = 0;
! 1473: ub = tabsize - 1;
! 1474: while (lb <= ub) {
! 1475: mid = (ub + lb) / 2;
! 1476: mp = &mactab[mid];
! 1477: if (mp->macname < c12)
! 1478: lb = mid + 1;
! 1479: else if (mp->macname > c12)
! 1480: ub = mid - 1;
! 1481: else {
! 1482: hit = 1;
! 1483: #ifdef FULLDEBUG
! 1484: printf("preliminary hit macro %c%c ", c1, c2);
! 1485: #endif FULLDEBUG
! 1486: switch (mp->condition) {
! 1487: case NONE:
! 1488: hit = YES;
! 1489: break;
! 1490: case FNEST:
! 1491: hit = (filesp == files);
! 1492: break;
! 1493: case NOMAC:
! 1494: hit = !inmacro;
! 1495: break;
! 1496: case MAC:
! 1497: hit = inmacro;
! 1498: break;
! 1499: case PARAG:
! 1500: hit = parag;
! 1501: break;
! 1502: case NBLK:
! 1503: hit = !keepblock;
! 1504: break;
! 1505: default:
! 1506: hit = 0;
! 1507: }
! 1508:
! 1509: if (hit) {
! 1510: #ifdef FULLDEBUG
! 1511: printf("MATCH\n");
! 1512: #endif FULLDEBUG
! 1513: switch ((*(mp->func))(c12)) {
! 1514: default:
! 1515: return;
! 1516: case COMX:
! 1517: goto comx;
! 1518: case COM:
! 1519: goto com;
! 1520: }
! 1521: }
! 1522: #ifdef FULLDEBUG
! 1523: printf("FAIL\n");
! 1524: #endif FULLDEBUG
! 1525: break;
! 1526: }
! 1527: }
! 1528: defcomline(c12);
! 1529: }
! 1530:
! 1531: int
! 1532: macsort(const void *p1, const void *p2)
! 1533: {
! 1534: struct mactab *t1 = (struct mactab *)p1;
! 1535: struct mactab *t2 = (struct mactab *)p2;
! 1536:
! 1537: return(t1->macname - t2->macname);
! 1538: }
! 1539:
! 1540: int
! 1541: sizetab(struct mactab *mp)
! 1542: {
! 1543: int i;
! 1544:
! 1545: i = 0;
! 1546: if (mp) {
! 1547: for (; mp->macname; mp++, i++)
! 1548: /*VOID*/ ;
! 1549: }
! 1550: return(i);
! 1551: }
! 1552:
! 1553: struct mactab *
! 1554: macfill(struct mactab *dst, struct mactab *src)
! 1555: {
! 1556:
! 1557: if (src) {
! 1558: while (src->macname)
! 1559: *dst++ = *src++;
! 1560: }
! 1561: return(dst);
! 1562: }
! 1563:
! 1564: __dead void
! 1565: usage(void)
! 1566: {
! 1567: extern char *__progname;
! 1568:
! 1569: fprintf(stderr, "usage: %s [-ikpw ] [ -m ( a | e | m | s | l ) ] [ filename ] ... \n", __progname);
! 1570: exit(1);
! 1571: }
! 1572:
! 1573: void
! 1574: buildtab(struct mactab **r_back, int *r_size)
! 1575: {
! 1576: int size;
! 1577: struct mactab *p, *p1, *p2;
! 1578: struct mactab *back;
! 1579:
! 1580: size = sizetab(troffmactab) + sizetab(ppmactab);
! 1581: p1 = p2 = NULL;
! 1582: if (msflag) {
! 1583: switch (mac) {
! 1584: case ME:
! 1585: p1 = memactab;
! 1586: break;
! 1587: case MM:
! 1588: p1 = msmactab;
! 1589: p2 = mmmactab;
! 1590: break;
! 1591: case MS:
! 1592: p1 = msmactab;
! 1593: break;
! 1594: case MA:
! 1595: p1 = manmactab;
! 1596: break;
! 1597: default:
! 1598: break;
! 1599: }
! 1600: }
! 1601: size += sizetab(p1);
! 1602: size += sizetab(p2);
! 1603: back = (struct mactab *)calloc(size+2, sizeof(struct mactab));
! 1604: if (back == NULL)
! 1605: err(1, "calloc");
! 1606:
! 1607: p = macfill(back, troffmactab);
! 1608: p = macfill(p, ppmactab);
! 1609: p = macfill(p, p1);
! 1610: p = macfill(p, p2);
! 1611:
! 1612: qsort(back, size, sizeof(struct mactab), macsort);
! 1613: *r_size = size;
! 1614: *r_back = back;
! 1615: }
! 1616:
! 1617: /*
! 1618: * troff commands
! 1619: */
! 1620: struct mactab troffmactab[] = {
! 1621: M(NONE, '\\','"', skip), /* comment */
! 1622: M(NOMAC, 'd','e', domacro), /* define */
! 1623: M(NOMAC, 'i','g', domacro), /* ignore till .. */
! 1624: M(NOMAC, 'a','m', domacro), /* append macro */
! 1625: M(NBLK, 'n','f', nf), /* filled */
! 1626: M(NBLK, 'c','e', ce), /* centered */
! 1627:
! 1628: M(NONE, 's','o', so), /* source a file */
! 1629: M(NONE, 'n','x', nx), /* go to next file */
! 1630:
! 1631: M(NONE, 't','m', skip), /* print string on tty */
! 1632: M(NONE, 'h','w', skip), /* exception hyphen words */
! 1633: M(NONE, 0,0, 0)
! 1634: };
! 1635:
! 1636: /*
! 1637: * Preprocessor output
! 1638: */
! 1639: struct mactab ppmactab[] = {
! 1640: M(FNEST, 'E','Q', EQ), /* equation starting */
! 1641: M(FNEST, 'T','S', intbl), /* table starting */
! 1642: M(FNEST, 'T','C', intbl), /* alternative table? */
! 1643: M(FNEST, 'T','&', intbl), /* table reformatting */
! 1644: M(NONE, 'T','E', outtbl),/* table ending */
! 1645: M(NONE, 'P','S', PS), /* picture starting */
! 1646: M(NONE, 0,0, 0)
! 1647: };
! 1648:
! 1649: /*
! 1650: * Particular to ms and mm
! 1651: */
! 1652: struct mactab msmactab[] = {
! 1653: M(NONE, 'T','L', skiptocom), /* title follows */
! 1654: M(NONE, 'F','S', skiptocom), /* start footnote */
! 1655: M(NONE, 'O','K', skiptocom), /* Other kws */
! 1656:
! 1657: M(NONE, 'N','R', skip), /* undocumented */
! 1658: M(NONE, 'N','D', skip), /* use supplied date */
! 1659:
! 1660: M(PARAG, 'P','P', PP), /* begin parag */
! 1661: M(PARAG, 'I','P', PP), /* begin indent parag, tag x */
! 1662: M(PARAG, 'L','P', PP), /* left blocked parag */
! 1663:
! 1664: M(NONE, 'A','U', AU), /* author */
! 1665: M(NONE, 'A','I', AU), /* authors institution */
! 1666:
! 1667: M(NONE, 'S','H', SH), /* section heading */
! 1668: M(NONE, 'S','N', SH), /* undocumented */
! 1669: M(NONE, 'U','X', UX), /* unix */
! 1670:
! 1671: M(NBLK, 'D','S', mssnblock), /* start display text */
! 1672: M(NBLK, 'K','S', mssnblock), /* start keep */
! 1673: M(NBLK, 'K','F', mssnblock), /* start float keep */
! 1674: M(NONE, 0,0, 0)
! 1675: };
! 1676:
! 1677: struct mactab mmmactab[] = {
! 1678: M(NONE, 'H',' ', MMHU), /* -mm ? */
! 1679: M(NONE, 'H','U', MMHU), /* -mm ? */
! 1680: M(PARAG, 'P',' ', PP), /* paragraph for -mm */
! 1681: M(NBLK, 'N','S', mssnblock), /* undocumented */
! 1682: M(NONE, 0,0, 0)
! 1683: };
! 1684:
! 1685: struct mactab memactab[] = {
! 1686: M(PARAG, 'p','p', mepp),
! 1687: M(PARAG, 'l','p', mepp),
! 1688: M(PARAG, 'n','p', mepp),
! 1689: M(NONE, 'i','p', meip),
! 1690:
! 1691: M(NONE, 's','h', mesh),
! 1692: M(NONE, 'u','h', mesh),
! 1693:
! 1694: M(NBLK, '(','l', mesnblock),
! 1695: M(NBLK, '(','q', mesnblock),
! 1696: M(NBLK, '(','b', mesnblock),
! 1697: M(NBLK, '(','z', mesnblock),
! 1698: M(NBLK, '(','c', mesnblock),
! 1699:
! 1700: M(NBLK, '(','d', mesnblock),
! 1701: M(NBLK, '(','f', mesnblock),
! 1702: M(NBLK, '(','x', mesnblock),
! 1703:
! 1704: M(NONE, 'r',' ', mefont),
! 1705: M(NONE, 'i',' ', mefont),
! 1706: M(NONE, 'b',' ', mefont),
! 1707: M(NONE, 'u',' ', mefont),
! 1708: M(NONE, 'q',' ', mefont),
! 1709: M(NONE, 'r','b', mefont),
! 1710: M(NONE, 'b','i', mefont),
! 1711: M(NONE, 'b','x', mefont),
! 1712: M(NONE, 0,0, 0)
! 1713: };
! 1714:
! 1715: struct mactab manmactab[] = {
! 1716: M(PARAG, 'B','I', manfont),
! 1717: M(PARAG, 'B','R', manfont),
! 1718: M(PARAG, 'I','B', manfont),
! 1719: M(PARAG, 'I','R', manfont),
! 1720: M(PARAG, 'R','B', manfont),
! 1721: M(PARAG, 'R','I', manfont),
! 1722:
! 1723: M(PARAG, 'P','P', manpp),
! 1724: M(PARAG, 'L','P', manpp),
! 1725: M(PARAG, 'H','P', manpp),
! 1726: M(NONE, 0,0, 0)
! 1727: };