home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol126 / roff47.c < prev    next >
C/C++ Source or Header  |  1984-04-29  |  8KB  |  307 lines

  1. /********************************************************/
  2. /*                            */
  3. /*            ROFF4, Version 1.50            */
  4. /*                            */
  5. /* (C) 1983 by    Ernest E. Bergmann            */
  6. /*        Physics, Building #16            */
  7. /*        Lehigh Univerisity            */
  8. /*        Bethlehem, Pa. 18015            */
  9. /*                            */
  10. /* Permission is hereby granted for all commercial and    */
  11. /* non-commercial reproduction and distribution of this    */
  12. /* material provided this notice is included.        */
  13. /*                            */
  14. /********************************************************/
  15. /*June 27, 1983*/
  16. #include "roff4.h"
  17. /*assuming REVSCROLL is FALSE*/
  18. /*output OUTBUF2 whith the vertical height of the mainline
  19. specified by VLINENO,FVLINENO[they must not be changed here].
  20. Excessive superscripting will be pushed down.*/
  21.  
  22. printout()
  23. {int level,top,bot;    /*"up" is negative;units fractional*/
  24. int lsave,fsave;
  25.  
  26. OUTBUF2[BPOS]='\0';
  27. fsave=FVLINENO;
  28. lsave=VLINENO;
  29. level=FRVAL*(PLINENO-VLINENO)+FPLINENO-FVLINENO;
  30. if(!OLDBOT) level++;
  31. excurs(&OUTBUF2[0],&top,&bot);
  32. if(top>level) level=top;
  33.  
  34. if(!REVSCROLL) FVLINENO += level;
  35. padv();
  36. for(;level<=bot;level++)
  37.     {OCNT=0;
  38.     do {OCNT++; flp(level,FALSE); }
  39.     while(retype());
  40.     if(level<bot)
  41.         {fraction();
  42.         putchar('\n');
  43.         FPLINENO++;
  44.         }
  45.     }
  46. flp(level,TRUE);    /*update UF, XF, MCNT*/
  47. OUTBUF2[0]=BPOS=0;
  48. OLDLN=VLINENO=lsave;
  49. OLDBOT=bot;
  50. FVLINENO=fsave;
  51. }
  52. /****************************************/
  53. /*moves printer vertically so that its position is specified
  54. by VLINENO,FVLINENO*/
  55. padv()
  56. {int w,f;    /*whole,fractional lines*/
  57. w=VLINENO-PLINENO;
  58. f=FVLINENO-FPLINENO;
  59. while(f<0) {w--; f += FRVAL; }
  60. while(f>=FRVAL)    {w++; f -= FRVAL; }
  61. if(w<0) if(REVSCROLL) backup(w*FRVAL+f);
  62.     else {VLINENO +=w;
  63.           FVLINENO +=f;
  64.           while(FVLINENO<0){VLINENO++;FVLINENO+=FRVAL;}
  65.           while(FVLINENO<FRVAL){VLINENO--;FVLINENO-=FRVAL;}
  66.           return;
  67.          }
  68. if(FRQ)    {while(f--){putchar('\n'); FPLINENO++; }
  69.     if(w){whole();while(w--){putchar('\n');PLINENO++;}}
  70.     }
  71. else    {while(w--){putchar('\n'); PLINENO++; }
  72.     if(f){fraction();while(f--){putchar('\n');FPLINENO++;}}
  73.     }
  74. while(FPLINENO>=FRVAL) {PLINENO++; FPLINENO -= FRVAL; }
  75. }
  76. /****************************************/
  77. backup(i)    /*not yet implemented*/
  78. int i;        /*# of fractional lines(probably negative)*/
  79. {fprintf(STDERR,"\nCan't back up yet\n");
  80. }
  81. /**************************************************/
  82. excurs(str,t,b) /*finds the topmost and bottommost line
  83.         positions of str*/
  84. char *str;
  85. int *t,*b;
  86. {int l;
  87. char c;
  88. *t=*b=l=0; /*current line position */
  89. c=*str;
  90. while(c){if(c==CFVAL){if(c=*(++str))
  91.             switch(c)
  92.             {case '+':l--; if(l<*t) *t=l;
  93.                 c=*(++str); break;
  94.             case '-':l++; if(l>*b) *b=l;
  95.                 c=*(++str); break;
  96.             default : c=*(++str); break;
  97.             }
  98.             }
  99.     else c=*(++str);
  100.     }
  101. }
  102.  
  103. /**************************************************/
  104. flp(level,updat)/*fancy line print at a given vertical level
  105.         the string in OUTBUF2[] with backspacing,
  106.         underlining, and strikout.  To permit boldface
  107.         it modifies DBUF[],DPOS so that retype can be
  108.         used to patch up OUTBUF2 for resubmittal to
  109.         flp()*/
  110. int level;    /* current vertical level to print*/
  111. int updat;    /* boolean for update of UF,XF,MCNT*/
  112. {int i;
  113.     BLKCNT=lbc(level,OUTBUF2);
  114.     FIRST=TRUE;
  115.     while((BLKCNT>0)||updat)
  116.         {prpass(level,updat); putchar('\r');
  117.         updat=FIRST=FALSE;
  118.         }
  119.     if(XCOL>-1){for(i=0;i<=XCOL;i++)
  120.             putchar(XBUF[i]);
  121.             putchar('\r');
  122.            }
  123.     if(UCOL>-1){for(i=0;i<=UCOL;i++)
  124.             putchar(UBUF[i]);
  125.             putchar('\r');
  126.            }
  127.     if((UCOL>-1)||(XCOL>-1)) initxu();
  128. }
  129.  
  130. /**************************************************/
  131. retype()    /*restores characters into OUTBUF2 from DBUF
  132.         that need to be overstruck again*/
  133. {int i;
  134. if(DPOS==-1) return(FALSE);
  135. else    {for(i=0;i<=DPOS;i++)
  136.         {if(DBUF[i])
  137.             {OUTBUF2[i]=DBUF[i];
  138.             DBUF[i]=FALSE;
  139.             }
  140.         }
  141.     DPOS=-1;
  142.     return(TRUE);
  143.     }
  144. }
  145.  
  146. /**************************************************/
  147. int lbc(lev,str) /*counts printable chars in line level and
  148.         above; parity must be reset*/
  149. int lev; /*=0 main line,=-1 superscripts,=+1 subscripts, etc.*/
  150. char *str;
  151. {char c,n;
  152. int l;
  153. l=n=0;
  154. c=*str;
  155. while(c){if(c==CFVAL){if(c=*(++str))
  156.             switch(c)
  157.             {case '+':l--;c=*(++str);break;
  158.             case '-':l++;c=*(++str);break;
  159.             default: c=*(++str);break;
  160.             }    }
  161.     else    {if((c>' ')&&(l<=lev)) if(c!=TCVAL) n++;
  162.         c=*(++str);
  163.         }
  164.     }
  165. return(n);
  166. }
  167.  
  168. /**************************************************/
  169. prpass(lev,updat) /*printer pass initial cr; no lf anywhere*/
  170. int lev; /*=0 main line,=-1 superscripts,=+1 subscripts, etc.*/
  171. int updat;/*boolean to update UF,XF,MCNT*/
  172. {char ch;
  173. int l;
  174. int xfs,ufs,mcnts;    /*save variables*/
  175. int p1,p2,p3;        /*position holders*/
  176. int cp2;    /*for tabulation calculation*/
  177. xfs=XF; ufs=UF; mcnts=MCNT;
  178. p1=p2=p3=l=BPOS=CP=PP=0;
  179. while(ch=OUTBUF2[BPOS])
  180.     {switch (class(ch))
  181.     {case    BLACK:/*print it if posssible*/
  182.         if((PP>CP)||(l>lev)){CP++;BPOS++;break;}
  183.         else    {while(CP>PP){putchar(' ');PP++;}
  184.             if(ch==SCVAL)putchar(' ');
  185.             else putchar(ch);PP++;
  186.             if(MCNT>OCNT)
  187.                 {DBUF[BPOS]=OUTBUF2[BPOS];
  188.                 if(BPOS>DPOS) DPOS=BPOS;
  189.                 }
  190.             OUTBUF2[BPOS++]=' ';
  191.             if(UF&&FIRST)UBUF[UCOL=CP]=UCHAR;
  192.             if(XF&&FIRST)XBUF[XCOL=CP]=XCHAR;
  193.             BLKCNT--; CP++;
  194.             } break;
  195.     case    WHITE:/*assume blank*/ CP++;BPOS++;break;
  196.     case    TRANSLATE:/*similar to BLACK and WHITE*/
  197.             ch=OUTBUF2[++BPOS];
  198.             if((PP>CP)||(l>lev)||(ch==' '))
  199.                 {CP++;BPOS++;break;}
  200.             else
  201.               {while(CP>PP){putchar(' ');PP++;}
  202.             trch(ch);PP++;
  203.             if(MCNT>OCNT)
  204.                 {DBUF[BPOS]=OUTBUF2[BPOS];
  205.                 DBUF[BPOS-1]=OUTBUF2[BPOS-1];
  206.                 if(BPOS>DPOS) DPOS=BPOS;
  207.                 }
  208.             OUTBUF2[BPOS++]=' ';
  209.             if(UF&&FIRST)UBUF[UCOL=CP]=UCHAR;
  210.             if(XF&&FIRST)XBUF[XCOL=CP]=XCHAR;
  211.             BLKCNT--; CP++;
  212.             } break;
  213.     case    CONTROL:/*decode on following letter*/
  214.             ch=OUTBUF2[++BPOS];
  215.             if(CPTR[ch-' ']) pcont(ch);
  216.             else switch(ch)
  217.             {case 'h':
  218.             case 'H':/*backspace*/
  219.                 if(CP)CP--;break;
  220.             case '+': l--; break;
  221.             case '-': l++; break;
  222.             case 'U': UF=TRUE;break;
  223.             case 'u': UF=FALSE;break;
  224.             case 'X': XF=TRUE;break;
  225.             case 'x': XF=FALSE;break;
  226.             case 'B': MCNT *=3;break;
  227.             case 'b': if(!(MCNT /=3))MCNT=1;
  228.                     break;
  229.             case 'D': MCNT *=2;break;
  230.             case 'd': if(!(MCNT /=2))MCNT=1;
  231.                     break;
  232.             case '(': p1=CP;break;
  233.             case ')': CP=p1;break;
  234.             case '[': p2=CP;break;
  235.             case ']': CP=p2;break;
  236.             case '{': p3=CP;break;
  237.             case '}': CP=p3;break;
  238.             default:/*?,ignore*/;break;
  239.             } BPOS++; break;
  240.     case    SENTINEL: OUTBUF2[BPOS]=0;break;
  241.     case    HTAB: for(cp2=0;CP>=0;cp2+=TABSIZ)CP-=TABSIZ;
  242.             CP=cp2; BPOS++; break;
  243.     case    OTHERS:
  244.        printf("\nweird character value: %o\n",ch);
  245.         BPOS++;
  246.         break;
  247.     }}
  248. if(!updat){/*restore original values*/
  249.     XF=xfs;
  250.     UF=ufs;
  251.     MCNT=mcnts;
  252.     }
  253. }
  254. /**************************************************/
  255. int class(c)
  256. char c;
  257. {if(c==TCVAL) return(TRANSLATE);
  258. if (c==CFVAL) return(CONTROL);
  259. if(c>' ') return(BLACK);
  260. if(c==' ') return(WHITE);
  261. if(c=='\n') return(SENTINEL);
  262. if(c=='\r') return(SENTINEL);
  263. if(c==TAB) return(HTAB);
  264. if(!c) return(SENTINEL);
  265. return(OTHERS);
  266. }
  267. /**************************************************/
  268. fraction()    /*put printer in fractional spcing mode;
  269.             set FRQ*/
  270. {if(!FRQ && FRSTRING && (FRVAL!=1))
  271.     {outstr(FRSTRING);
  272.     FRQ = TRUE;
  273.     }
  274. }
  275. /**************************************************/
  276. whole()        /*put printer in whole line spacing;
  277.             reset FRQ */
  278. {if(FRQ && WHSTRING)
  279.     {outstr(WHSTRING);
  280.     FRQ = FALSE;
  281.     }
  282. }
  283. /**************************************************/
  284. trch(c)    /*output string translation of c*/
  285. char c;
  286. {char *p;
  287.     if(c<' ') {putchar(TCVAL);putchar(c);return;}
  288.     p = TPTR[c-' '];
  289.     if(p) outstr(p);
  290.     else    {/*not initialized*/
  291.         putchar(TCVAL);
  292.         putchar('?');
  293.         }
  294. }
  295. /****************************************/
  296. pcont(c) /*output printer control string for c*/
  297. char c;
  298. {char *p;
  299.     if(c<' ') {putchar(CFVAL);putchar(c);return;}
  300.     p = CPTR[c-' '];
  301.     if(p) outstr(p);
  302.     else    {/*not initialized*/
  303.         putchar(CFVAL);
  304.         putchar('?');
  305.         }
  306. }
  307.