home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 304_01 / roff54.c < prev    next >
Text File  |  1990-02-14  |  11KB  |  407 lines

  1. /********************************************************/
  2. /*         ROFF5, Version 2.00            */
  3. /*    (c) 1983,4,8,9 by Ernest E. Bergmann        */
  4. /*    730 Seneca Street, Bethlehem, Pa. 18015        */
  5. /*                            */
  6. /* Permission is hereby granted for all commercial and    */
  7. /* non-commercial reproduction and distribution of this    */
  8. /* material provided this notice is included.        */
  9. /********************************************************/
  10. #include <conio.h>
  11. #include <roff5.h>
  12. #if (VERSION!=2) || (subVERSION!=00)
  13. #error ***************This is version 2.00******************
  14. #endif
  15. /**************************************/
  16. void doTI(char *line)  /*removes leading space; updates TIVAL*/
  17. {int i, j, white;
  18.  char c;
  19. for (white=TIVAL,i=0; c=line[i],(c==' ')||(c=='\t')||(c=='^'); i++ )
  20.     {if(line[i]==' ') white++;
  21.      else if (c=='^')
  22.         {c=line[i+1];
  23.          if ((c=='T')||(c=='t')) {i++; c='\t';}
  24.          else break;
  25.         }
  26.      if (c=='\t')
  27.         {j=white+1;
  28.          while (RULER[j]=='-') j++;
  29.          if (strchr("lcr.,",RULER[j])) white=j;
  30.         }
  31.     }
  32. if ( line[i] != NEWLINE ) TIVAL = white;
  33. /* move line to left */
  34. for(j=0;(line[j]=line[i])!='\0';j++,i++);
  35. }
  36. /**************************************************
  37. handles case of leading blanks or tabs; empty lines
  38. ***************************************************/
  39. void leadbl(char *line)
  40. {if (JUSTIFY && (DOTJ>1))
  41.     {int nextra;
  42.      nextra=min(RMVAL-TIVAL,MAXLINE-1)-OUTW+1;
  43.      spread(OUTBUF,nextra,1);
  44.     }
  45. Brk();
  46. doTI(line);
  47. }
  48. /*****************************************
  49.         puts out page header
  50. ******************************************/
  51. void phead()
  52. {VLINENO=-1;
  53. setTRAP();
  54. chgenv(0,1);
  55. UF=XF=FALSE;
  56. MCNT=1;
  57. CURPAG = NEWPAG++;
  58. if((CURPAG<FIRSTPAGE)||(CURPAG>LASTPAGE)) SUPPRESS=TRUE;
  59. else SUPPRESS=FALSE;
  60. OLDLN=-1;
  61. if(PAGESTOP)
  62.     {putch(BELL);    /*ring bell*/
  63.     getch();    /*wait til char typed at console*/
  64.     }
  65. VLINENO=FVLINENO=PLINENO=FPLINENO=0;
  66. if (M1VAL[0] > 0 )
  67.       { VLINENO = M1VAL[0]-1;
  68.     if (CURPAG % 2) puttl3 ( OHEAD, OH2, OH3, CURPAG, PAGFMT );
  69.     else puttl3 ( EHEAD, EH2, EH3, CURPAG, PAGFMT );
  70.       }
  71. chgenv(1,0);
  72. VLINENO = M1VAL[0]+M2VAL[0];
  73. }
  74. /**************************************
  75.         puts out page footer
  76. ***************************************/
  77. void pfoot()
  78. {chgenv(0,1);
  79. UF=XF=FALSE;
  80. MCNT=1;
  81. VLINENO = FOOTLOC+M3VAL[0]; FVLINENO=0;
  82. if ( M4VAL[0] > 0 )
  83.       { if(CURPAG % 2)puttl3 ( OFOOT,OF2,OF3, CURPAG, PAGFMT );
  84.     else puttl3(EFOOT,EF2,EF3,CURPAG,PAGFMT);
  85.       }
  86. VLINENO = PLVAL[0];FVLINENO=0;
  87. if (FFEED) cputc(FORMF,ofp);
  88. else padv();
  89. whole();
  90. OLDBOT=PLINENO=FPLINENO=0;/*printer at start of newpage*/
  91. OLDLN=-1;
  92. chgenv(1,0);
  93. }
  94. void pbcmd(char *xx,int num) /*pbstr(".xx <num>\n") */
  95. {char cbuf[10];    /*if num<0, don't do <num> */
  96.  pbstr("\n");
  97.  if(num>=0)
  98.     {pbstr((char *)itoa(num,cbuf,9));
  99.      putback(' ');
  100.     }
  101.  pbstr(xx);
  102.  putback('.');
  103. }
  104. /*******************************************
  105. undoes stuff in progress during a page trap
  106. ********************************************/
  107. void retract()
  108. {int ti;
  109.  ti=TIVAL;
  110.  if (*(LIN-1)==COMMAND) LIN--;
  111.  else if(FILL) doTI(LIN);
  112.  if (GPWBUF[0])
  113.     {pbstr(LIN);
  114.      LIN=LINE;
  115.      LINE[0]='\0';
  116.      OUTPOS=0;
  117.      Brk();
  118.      putback(' ');
  119.      if(SENTENCE) putback(' ');
  120.      pbstr(GPWBUF);
  121.      GPWBUF[0]='\0';
  122.     }
  123.  else if((FILL)&&!CEVAL)
  124.     {pbstr(LIN);
  125.      LIN=LINE;
  126.      LINE[0]='\0';
  127.      OUTPOS=0;
  128.     }
  129.  pbcmd("ti",ti);
  130. }
  131. /**********************************************
  132.     space n lines or to bottom of the page or to trap
  133. ***********************************************/
  134. void space(int n)
  135. {int destination;
  136.  if(DIVERTING)
  137.     {for(;n>0;n--)
  138.     {divert("\n");
  139.      if((++DLINES)==Dstats->dt)
  140.         {char *pc;
  141.          pc=macq1(Dstats->dtname);
  142.          if(pc)
  143.             {retract();
  144.              pbstr(pc);
  145.              return;
  146.             }
  147.         }
  148.     }
  149.      return;
  150.     }
  151. /* else not DIVERTING:*/
  152.  if (VLINENO >= FOOTLOC) return;
  153.  if (VLINENO<0) phead();    /* top of page */
  154.  VLINENO+=n;
  155.  if (VLINENO>FOOTLOC) destination=VLINENO=FOOTLOC;
  156.  else destination=VLINENO;
  157.  if ((VLINENO >= TRAPLOC)&&(TRAPLOC>(M1VAL[0]+M2VAL[0]))) VLINENO=TRAPLOC;
  158.  if (VLINENO>=FOOTLOC) pfoot(); /* print footer if bottom */
  159.  else if (VLINENO >= TRAPLOC)
  160.     {char *pc;
  161.      /*execute TRAP:*/
  162.      pc=macq1(TRAPNAM);
  163.      if(pc)
  164.         {retract();
  165.          pbcmd("go",destination);
  166.          pbstr(pc);
  167.         }
  168.      setTRAP();
  169.     }
  170. }
  171. /*******************************************************/
  172.     char GPWBUF[LSZ];
  173. void text()
  174. {int i, j, k;
  175. char *p1, *p2;
  176. if(INTRAP) if(--INTRAP==0)
  177.         {p1=macq1(ITstring);
  178.          if(p1) pbstr(p1);
  179.         }
  180. if ((FILL) && (LIN[0] == BLANK || LIN[0]==NEWLINE || LIN[0] == TAB
  181.     ||((LIN[0]=='^')&&((LIN[1]=='T')||(LIN[1]=='t'))) ))
  182.     leadbl (LIN);
  183. if (CEVAL > 0)
  184.       { center(LIN);
  185.     put(LIN);
  186.     CEVAL--;
  187.       }
  188. else if(LIN[0]==NEWLINE)
  189.     {
  190.       Brk(); space(LSVAL[0]);
  191.     }
  192. else if(!FILL) put(LIN);
  193. else while (WE_HAVE_A_WORD == gwLIN(GPWBUF))
  194.     putwrd (GPWBUF);
  195. }
  196. /******************************************************
  197.     put out a line of text with correct indentation
  198.     underlining if specified;  starts new page if
  199.     line does not fit on current page.  if DIVERTING
  200.     it diverts line and advances the line spacing val.
  201. *******************************************************/
  202. void put(char *line)
  203. {int i,fs,minfs;
  204.  int top,bot;
  205.  if(!DIVERTING)
  206.    {if ((VLINENO < 0)||(VLINENO >= FOOTLOC)) phead();
  207.     fs=(VLINENO-OLDLN)*FRVAL;
  208.     minfs=OLDBOT-OUTTOP; if(!(OLDBOT&&OUTTOP)) minfs++;
  209.     while(fs<minfs) {fs+=FRVAL; VLINENO++;}
  210.     excurs(line,&top,&bot);
  211.     if ((VLINENO + (bot-top)/FRVAL)>=FOOTLOC) {pfoot(); phead();}
  212.    }
  213. putline(line);
  214. TIVAL = INVAL;
  215. space(LSVAL[0]);
  216. }
  217. /***********************************************************
  218. concatenates GPWBUF onto the end of OUTBUF for filled text
  219. ************************************************************/
  220. void putwrd()
  221. {int i, j, k, trapped;
  222. char s[MAXLINE], ch;
  223. int line_len, new_out_width, wid;
  224. int nextra;
  225. trapped=FALSE;
  226. trunc_bl (GPWBUF);
  227. wid =SENTENCE+strln4(GPWBUF,TRUE,-1,PAGFMT);/*sets WTOP,WBOT*/
  228. line_len = RMVAL - TIVAL;
  229. new_out_width = OUTW+wid;
  230. if (new_out_width > min (line_len, MAXLINE-1))
  231.       { nextra = min(line_len, MAXLINE-1)-OUTW+1;
  232.     if(OUTBUF[OUTPOS-2]==BLANK) nextra++;
  233.     if(JUSTIFY) spread(OUTBUF,nextra,OUTWRDS);
  234.     Brk();
  235.     if(GPWBUF[0]=='\0') trapped=TRUE;
  236.       }
  237. if(trapped)
  238.    {OUTTOP=0;
  239.     OUTBOT=0;
  240.     OUTWRDS=0;
  241.    }
  242. else
  243.    {OUTW += wid+1;
  244.     OUTcat(GPWBUF);
  245.     *GPWBUF= '\0'; /*marked empty after transfer*/
  246.     if(*OUTBUF) {OUTSP(); if(SENTENCE) OUTSP();}
  247.     OUTWRDS++;
  248.     if(WTOP<OUTTOP) OUTTOP=WTOP;
  249.     if(WBOT>OUTBOT) OUTBOT=WBOT;
  250.    }
  251. }
  252. /**********************************************************
  253.  offset() will insert leading blanks into a string
  254. ***********************************************************/
  255. void offset(char *s, int i)
  256. {char *p,*q;
  257.  if (i)
  258.  {for(p=s; *p ; p++);
  259.   for(q=p+i; p>=s; *q--=*p--);
  260.   for( ; q>=s; *q--=BLANK);
  261.  }
  262. }
  263. /**********************************************************
  264.   a new putline routine; sends line OF TEXT to  OUTPUT2 or diverts
  265. ***********************************************************/
  266. void putline(char *line)
  267. {char c;
  268. blankb(TIVAL);
  269. for(;'\0'!=(c=*line);line++) putout(c);
  270. putout('\0');
  271. detab();
  272. putlinout(TRUE);
  273. }
  274. /****************************************/
  275. void OUTcat(char *str)    /*appends string to OUTBUF*/
  276. {while('\0'!=(OUTBUF[OUTPOS]=*(str++)))
  277.     OUTPOS++;
  278. }
  279. /****************************************/
  280. void OUTSP()        /*appends BLANK to OUTBUF*/
  281. {OUTBUF[OUTPOS++]=BLANK;
  282. OUTBUF[OUTPOS]='\0';
  283. }
  284. /****************************************/
  285. void gloss()    /*prints on STDOUT a glossary of .tr chars*/
  286. {int i;
  287. char line[20],tcs,TCS;
  288. put("GLOSSARY:");
  289. put("USE     <GET>");
  290. tcs=TFVAL[0];
  291. TCS = 128 | tcs; /*set most significant bit*/
  292. TFVAL[0] = TCS; /*temporary change of character for class()*/
  293. for(i=1;i<19;i++) line[i]=' ';
  294. line[0]=tcs;
  295. line[8]='<';
  296. line[9]=TCS;
  297. line[11]='>';
  298. line[12]='\0';
  299. for(i=' ';i<127;i++)
  300.     {if(TPTR[i-' '])
  301.         {line[1]=line[10]=i;
  302.         put(line);
  303.         }
  304.     }
  305. TFVAL[0]=tcs; /*restore original*/
  306. Brk();
  307. space(HUGE);
  308. }
  309. /******** ENVIROMENT SWITCHING: ********/
  310. int UFs[NUMENV];
  311. int XFs[NUMENV];
  312. int MCNTs[NUMENV];
  313. int FILLs[NUMENV];
  314. int JUSTIFYs[NUMENV];
  315. int TIVALs[NUMENV];
  316. int CEVALs[NUMENV];
  317. char RULERs[NUMENV][LSZ];
  318. int SENTENCEs[NUMENV];
  319. int LSVALs[NUMENV][STKSIZ+1];
  320. int INVALs[NUMENV];
  321. int RMVALs[NUMENV];
  322.  
  323. int OUTPOSs[NUMENV];
  324. char OUTBUFs[NUMENV][LSZ];
  325. char GPWBUFs[NUMENV][LSZ];
  326. int OUTWs[NUMENV];
  327. int OUTWRDSs[NUMENV];
  328. int OUTTOPs[NUMENV];
  329. int OUTBOTs[NUMENV];
  330. char OUTBUF2s[NUMENV][LSZ];
  331. int BPOSs[NUMENV];
  332. /***************************************************/
  333. /* Saves current values of state variables to old. */
  334. /* Restores values of state variables from new.    */
  335. /* If old==-1 does restores only.           */
  336. /* If new==-1 does save only.               */
  337. /***************************************************/
  338. void chgenv(int old, int new)
  339. {
  340.  if ((old<-1)||(old>=NUMENV)) return /*error*/;
  341.  if ((new<-1)||(new>=NUMENV)) return /*error*/;
  342.  if (old!=-1) /*saves*/
  343.     {int i;
  344.      MCNTs[old]=MCNT;
  345.      XFs[old]=XF;
  346.      UFs[old]=UF;
  347.      FILLs[old]=FILL;
  348.      JUSTIFYs[old]=JUSTIFY;
  349.      TIVALs[old]=TIVAL;
  350.      CEVALs[old]=CEVAL;
  351.      for(i=0;i<LSZ;i++)
  352.     {RULERs[old][i]=RULER[i];
  353.      OUTBUFs[old][i]=OUTBUF[i];
  354.      GPWBUFs[old][i]=GPWBUF[i];
  355.      OUTBUF2s[old][i]=OUTBUF2[i];
  356.     }
  357.      OUTPOSs[old]=OUTPOS;
  358.      OUTWs[old]=OUTW;
  359.      OUTWRDSs[old]=OUTWRDS;
  360.      OUTTOPs[old]=OUTTOP;
  361.      OUTBOTs[old]=OUTBOT;
  362.      BPOSs[old]=BPOS;
  363.      SENTENCEs[old]=SENTENCE;
  364.      for(i=0;i<=STKSIZ;i++) LSVALs[old][i]=LSVAL[i];
  365.      INVALs[old]=INVAL;
  366.      RMVALs[old]=RMVAL;
  367.     }
  368.  if (new!=-1) /*restores*/
  369.     {int i;
  370.      MCNT=MCNTs[new];
  371.      XF=XFs[new];
  372.      UF=UFs[new];
  373.      FILL=FILLs[new];
  374.      JUSTIFY=JUSTIFYs[new];
  375.      TIVAL=TIVALs[new];
  376.      CEVAL=CEVALs[new];
  377.      for(i=0;i<LSZ;i++)
  378.     {RULER[i]=RULERs[new][i];
  379.      OUTBUF[i]=OUTBUFs[new][i];
  380.      GPWBUF[i]=GPWBUFs[new][i];
  381.      OUTBUF2[i]=OUTBUF2s[new][i];
  382.     }
  383.      OUTPOS=OUTPOSs[new];
  384.      OUTW=OUTWs[new];
  385.      OUTWRDS=OUTWRDSs[new];
  386.      OUTTOP=OUTTOPs[new];
  387.      OUTBOT=OUTBOTs[new];
  388.      BPOS=BPOSs[new];
  389.      SENTENCE=SENTENCEs[new];
  390.      for(i=0;i<=STKSIZ;i++) LSVAL[i]=LSVALs[new][i];
  391.      INVAL=INVALs[new];
  392.      RMVAL=RMVALs[new];
  393.     }
  394. }
  395. /********************************/
  396. /* selects printer or diversion */
  397. /********************************/
  398. void putlinout(int txtline)
  399. {if (DIVERTING)
  400.     {divert(OUTBUF2);
  401.      OUTBUF2[0]=BPOS=0;
  402.     }
  403.  else     {offset(OUTBUF2, dotO);
  404.      printout(txtline);
  405.     }
  406. }
  407.