📄 deroff.c
字号:
/* * put out words (for the -w option) with ms and mm conventions */msputwords(macline) int macline; /* is this is a macro line */{ register char *p, *p1; int i, nlet; for(p1 = line ; ;) { /* * skip initial specials ampersands and apostrophes */ while( chars[*p1] < DIGIT) if(*p1++ == '\0') return; nlet = 0; for(p = p1 ; (i=chars[*p]) != SPECIAL ; ++p) if(i == LETTER) ++nlet; if ( (macline && nlet > 1) || (!macline && nlet > 2 && chars[p1[0]] == LETTER && chars[p1[1]] == LETTER) ) { /* * delete trailing ampersands and apostrophes */ while( (p[-1]=='\'') || (p[-1]=='&') || (chars[p[-1]] == PUNCT) ){ --p; } while(p1 < p) putchar(*p1++); putchar('\n'); } else { p1 = p; } }}/* * put out a macro using the me conventions */#define SKIPBLANK(cp) while(*cp == ' ' || *cp == '\t') { cp++; }#define SKIPNONBLANK(cp) while(*cp !=' ' && *cp !='\cp' && *cp !='\0') { cp++; }meputmac(cp, const_val) reg char *cp; int const_val;{ reg char *np; int found; int argno; int last; int inquote; 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] == '"'){ strcpy(np, np + 1); np++; continue; } else { *np = ' '; /* bye bye " */ goto endarg; } default: continue; } } endarg: ; /* * cp points at the first char in the arg * np points one beyond the last char in the arg */ 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 FULLDEBUG /* * Determine if the argument merits being printed * * const_val is the cut off point below which something * is not a word. */ if ( ( (np - cp) > const_val) && ( inquote || (chars[cp[0]] == LETTER)) ){ for (cp = cp; cp < np; cp++){ putchar(*cp); } last = np[-1]; found++; } else if(found && (np - cp == 1) && chars[*cp] == PUNCT){ putchar(*cp); } else { last = np[-1]; } cp = np; } if(msflag && chars[last] == PUNCT) putchar(last); putchar('\n');}/* * put out words (for the -w option) with ms and mm conventions */meputwords(macline) int macline;{ msputwords(macline);}/* * * Skip over a nested set of macros * * Possible arguments to noblock are: * * fi end of unfilled text * PE pic ending * DE display ending * * for ms and mm only: * KE keep ending * * NE undocumented match to NS (for mm?) * LE mm only: matches RL or *L (for lists) * * for me: * ([lqbzcdf] */noblock(a1, a2) char a1, a2;{ register int c1,c2; register int eqnf; int lct; lct = 0; eqnf = 1; SKIP; while(1){ 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; } /* * equations (EQ) nested within a display */ else if(c1 == 'E' && c2 == 'Q'){ if ( (mac == ME && a1 == ')') || (mac != ME && a1 == 'D') ) { eqn(); eqnf=0; } } /* * turning on filling is done by the paragraphing * macros */ else if(a1 == 'f') { /* .fi */ if ( (mac == ME && (c2 == 'h' || c2 == 'p')) ||(mac != ME && (c1 == 'P' || c2 == 'P')) ) { SKIP; return; } } else { SKIP; } }}EQ(){ eqn(); return(0);}domacro(){ macro(); return(0);}PS(){ if (!msflag) { inpic(); } else { noblock('P', 'E'); } return(0);}skip(){ SKIP; return(0);}intbl(){ if(msflag){ stbl(); } else tbl(); return(0);}outtbl(){ intable = NO; }so(){ getfname(); if( fname[0] ) infile = *++filesp = opn( fname ); return(0);}nx(){ getfname(); if(fname[0] == '\0') exit(0); if(infile != stdin) fclose(infile); infile = *filesp = opn(fname); return(0);}skiptocom(){ SKIP_TO_COM; return(COMX); }PP(c12) pacmac c12;{ int c1, c2; frommac(c12, c1, c2); printf(".%c%c",c1,c2); while(C != '\n')putchar(c); putchar('\n'); return(0);}AU(){ if(mac==MM) { return(0); } else { SKIP_TO_COM; return(COMX); }}SH(c12) pacmac c12;{ int c1, c2; frommac(c12, c1, c2); if(parag){ printf(".%c%c",c1,c2); while(C != '\n')putchar(c); putchar(c); putchar('!'); while(1){ while(C != '\n')putchar(c); putchar('\n'); if(C == '.') return(COM); putchar('!'); putchar(c); } /*NOTREACHED*/ } else { SKIP_TO_COM; return(COMX); }}UX(){ if(wordflag) printf("UNIX\n"); else printf("UNIX "); return(0);}MMHU(c12) 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);}mesnblock(c12) pacmac c12;{ int c1, c2; frommac(c12, c1, c2); noblock(')',c2); return(0);}mssnblock(c12) pacmac c12;{ int c1, c2; frommac(c12, c1, c2); noblock(c1,'E'); return(0);} nf(){ noblock('f','i'); return(0);}ce(){ sce(); return(0);}meip(c12) pacmac c12;{ if(parag) mepp(c12); else if (wordflag) /* save the tag */ regline(meputmac, ONE); else { SKIP; } return(0);}/* * only called for -me .pp or .sh, when parag is on */mepp(c12) pacmac c12;{ PP(c12); /* eats the line */ return(0);}/* * Start of a section heading; output the section name if doing words */mesh(c12) pacmac c12;{ if (parag) mepp(c12); else if (wordflag) defcomline(c12); else { SKIP; } return(0);}/* * process a font setting */mefont(c12) pacmac c12;{ argconcat = 1; defcomline(c12); argconcat = 0; return(0);}manfont(c12) pacmac c12;{ return(mefont(c12));}manpp(c12) pacmac c12;{ return(mepp(c12));}defcomline(c12) 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 == '.') /*VOID*/; } ++inmacro; /* * Process the arguments to the macro */ 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;}comline(){ reg int c1; reg int c2; pacmac c12; reg int mid; int lb, ub; int hit; static int tabsize = 0; static struct mactab *mactab = (struct mactab *)0; reg 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; /* * Single letter macro */ if (mac == ME && (c2 == ' ' || c2 == '\t') ) c2 = ' '; c12 = tomac(c1, c2); /* * binary search through the table of macros */ 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 FULLDEBUG 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 FULLDEBUG switch( (*(mp->func))(c12) ) { default: return; case COMX: goto comx; case COM: goto com; } }#ifdef FULLDEBUG printf("FAIL\n");#endif FULLDEBUG break; } } defcomline(c12);}int macsort(p1, p2) struct mactab *p1, *p2;{ return(p1->macname - p2->macname);}int sizetab(mp) reg struct mactab *mp;{ reg int i; i = 0; if (mp){ for (; mp->macname; mp++, i++) /*VOID*/ ; } return(i);}struct mactab *macfill(dst, src) reg struct mactab *dst; reg struct mactab *src;{ if (src) { while(src->macname){ *dst++ = *src++; } } return(dst);}buildtab(r_back, r_size) struct mactab **r_back; int *r_size;{ int size; struct mactab *p, *p1, *p2; struct mactab *back; size = sizetab(troffmactab); size += sizetab(ppmactab); p1 = p2 = (struct mactab *)0; 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 = (struct mactab *)calloc(size+2, sizeof(struct mactab)); 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;}/* * troff commands */struct mactab troffmactab[] = { M(NONE, '\\','"', skip), /* comment */ M(NOMAC, 'd','e', domacro), /* define */ M(NOMAC, 'i','g', domacro), /* ignore till .. */ M(NOMAC, 'a','m', domacro), /* append macro */ M(NBLK, 'n','f', nf), /* filled */ M(NBLK, 'c','e', ce), /* centered */ M(NONE, 's','o', so), /* source a file */ M(NONE, 'n','x', nx), /* go to next file */ M(NONE, 't','m', skip), /* print string on tty */ M(NONE, 'h','w', skip), /* exception hyphen words */ M(NONE, 0,0, 0)};/* * Preprocessor output */struct mactab ppmactab[] = { M(FNEST, 'E','Q', EQ), /* equation starting */ M(FNEST, 'T','S', intbl), /* table starting */ M(FNEST, 'T','C', intbl), /* alternative table? */ M(FNEST, 'T','&', intbl), /* table reformatting */ M(NONE, 'T','E', outtbl),/* table ending */ M(NONE, 'P','S', PS), /* picture starting */ M(NONE, 0,0, 0)};/* * Particular to ms and mm */struct mactab msmactab[] = { M(NONE, 'T','L', skiptocom), /* title follows */ M(NONE, 'F','S', skiptocom), /* start footnote */ M(NONE, 'O','K', skiptocom), /* Other kws */ M(NONE, 'N','R', skip), /* undocumented */ M(NONE, 'N','D', skip), /* use supplied date */ M(PARAG, 'P','P', PP), /* begin parag */ M(PARAG, 'I','P', PP), /* begin indent parag, tag x */ M(PARAG, 'L','P', PP), /* left blocked parag */ M(NONE, 'A','U', AU), /* author */ M(NONE, 'A','I', AU), /* authors institution */ M(NONE, 'S','H', SH), /* section heading */ M(NONE, 'S','N', SH), /* undocumented */ M(NONE, 'U','X', UX), /* unix */ M(NBLK, 'D','S', mssnblock), /* start display text */ M(NBLK, 'K','S', mssnblock), /* start keep */ M(NBLK, 'K','F', mssnblock), /* start float keep */ M(NONE, 0,0, 0)};struct mactab mmmactab[] = { M(NONE, 'H',' ', MMHU), /* -mm ? */ M(NONE, 'H','U', MMHU), /* -mm ? */ M(PARAG, 'P',' ', PP), /* paragraph for -mm */ M(NBLK, 'N','S', mssnblock), /* undocumented */ 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)};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -