home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 304_01 / roff55.c < prev    next >
Text File  |  1990-02-14  |  10KB  |  334 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 <roff5.h>
  11. #if (VERSION!=2) || (subVERSION!=00)
  12. #error ***************This is version 2.00******************
  13. #endif
  14. /****************************************/
  15. void puttl3(char *s1,char *s2,char *s3,int pageno, FORMAT fmt)
  16.         /*put out three part title, none
  17.         containing '\n', with
  18.         optional page numbering; aligning
  19.         with page margins,0 & RMVAL;*/
  20. {int size1,gap1,size2,gap2,size3;
  21.     size1 =strln4(s1,FALSE,pageno,fmt);
  22.     OUTTOP=LTOP;OUTBOT=LBOT;
  23.     size2 =strln4(s2,FALSE,pageno,fmt);
  24.     if(LTOP<OUTTOP) OUTTOP=LTOP;
  25.     size3 =strln4(s3,FALSE,pageno,fmt);
  26.     if(LTOP<OUTTOP) OUTTOP=LTOP;
  27.     gap1 = ((RMVAL-INVAL-size2)/2) - size1;
  28.     gap2 = RMVAL-INVAL-size1-size2-size3-gap1;
  29.     blankb(INVAL);
  30.     puttl(s1,pageno,fmt);
  31.     blankb(gap1);
  32.     puttl(s2,pageno,fmt);
  33.     blankb(gap2);
  34.     puttl(s3,pageno,fmt);
  35.     putlinout(FALSE);
  36. }
  37. /****************************************/
  38. void blankb(int i) /*sends i blanks to OUTBUF2, handles negative i*/
  39. {    if(i<0)    for( ; i ;i++) {putout('^');putout('H');}
  40.     else for( ; i ; i--) putout( BLANK );
  41. }
  42. /****************************************/
  43. void gettl3(char *sl,char ttl1[MAXLINE],char **ttl2,char **ttl3)
  44.     /* Gets from source line (s1) three part title that it
  45.     transfers to buffer delineated by ttl1 which has
  46.     capacity for all three strings; none of the strings
  47.     will contain '\n' */
  48. {char c, cc, *dp;
  49.     /*pass over command*/
  50.     for(c=*sl;c!=' '&&c!='\n'&&c!='\t';sl++)c=*sl;
  51.     /*advance to first non-blank or '\n' */
  52.     for(;c==' '||c=='\t';sl++)c=*sl;
  53.     /*advance beyond delim. if present:*/
  54.     if(c!='\n'&&!c) sl++;
  55.     dp=ttl1;
  56.     transfer(&sl,&dp,c);
  57.     *ttl2=dp;
  58.     transfer(&sl,&dp,c);
  59.     *ttl3=dp;
  60.     transfer(&sl,&dp,c);
  61. }
  62. /********************************************************/
  63. /* title3() is the combination of gettl3() and puttl3() */
  64. /* used to implement the .tl command.            */
  65. /********************************************************/
  66. void title3(char *sl, int pageno, FORMAT fmt)
  67. {char TLBUFF[MAXLINE],*ttl2,*ttl3;
  68.  gettl3(sl,TLBUFF,&ttl2,&ttl3);
  69.  puttl3(TLBUFF,ttl2,ttl3,pageno,fmt);
  70. }
  71. /***************************************************************/
  72. /* Copy string from source to destination.  Original delim.    */
  73. /*can be \0, \n, or char.  The pointer to the source is updated*/
  74. /*to point at the \0, \n, or past char.  In destination, delim.*/
  75. /*is always replaced by \0.  The destination pointer always    */
  76. /*points past this \0.                           */
  77. /***************************************************************/
  78. void transfer(char **s,char **d,char c)
  79. {char a;
  80.     a=**s;
  81.     while(a!=c && a!='\n' && a)
  82.         {**d = a;  (*d)++;
  83.         (*s)++;  a=**s;
  84.         }
  85.     **d='\0';
  86.     (*d)++;
  87.     if(a!='\n' && a!='\0') (*s)++;
  88. }
  89. /**********************************************************
  90.         centers a line of text
  91. **********************************************************/
  92. void center(char *line)
  93. {TIVAL = max(( RMVAL+TIVAL-strln4(line,FALSE,-1,PAGFMT))/2, 0 );
  94. OUTTOP=LTOP;OUTBOT=LBOT;
  95. return;
  96. }
  97. /************************************************************
  98. Transfers next word from in to out.  Scans off leading white
  99. space from in.  If there is no word, returns FALSE.
  100. Otherwise, input is truncated on left of word which is
  101. transfered to out without leading or trailing blanks.
  102. WE_HAVE_A_WORD will be returned.  If the transfered word
  103. terminates a sentence then SENTENCE is set to 1, otherwise it
  104. is reset to FALSE.
  105. **************************************************************/
  106. int getwrd(char *in,char *out )
  107. {char *pin,*pout,c,cm,cp;
  108.  int i;
  109.     for(i=0; (c=in[i])!='\0'; i++)    /*replace tabs with spaces*/
  110.     {if (c==TAB) in[i]=BLANK;
  111.      else if (c=='^')
  112.         {c=in[i+1];
  113.          if ((c=='t')||(c=='T')) in[i]=in[i+1]=BLANK;
  114.         }
  115.     }
  116.     pin=in;
  117.     while(*pin==BLANK || *pin==NEWLINE) pin++;
  118.     pout=out;
  119.     c=*pin;
  120.     SENTENCE=FALSE;
  121.     if(c==NEWLINE || c=='\0')
  122.         {*out='\0';
  123.         return(FALSE);
  124.         }
  125.     while(c!=BLANK && c!=NEWLINE && c)
  126.         {*(pout++)=c;
  127.         *pin=BLANK;
  128.         c=*(++pin);
  129.         }
  130.     *pout='\0';    /*terminate out string*/
  131.     cm=*(pout-1);
  132.     cp=*(pin+1);
  133.     switch (cm)
  134.         {case ':' :
  135.         case ';' :
  136.         case '?' :
  137.         case '!' :
  138.             SENTENCE=1;
  139.             break;
  140.         case '.' :
  141.             if(cp==BLANK||cp==NEWLINE||c==NEWLINE)
  142.                 SENTENCE=1;
  143.         }
  144.     return(WE_HAVE_A_WORD);
  145. }
  146. /*********************************/
  147. int gwLIN(char *out)
  148. {return(getwrd(LIN,out)); }
  149. /*******************************************************
  150. Truncates white-space characters at the end of a string.
  151. ********************************************************/
  152. void trunc_bl (char *string)
  153. {char *ptr;
  154. int k;
  155. k = strlen (string);
  156. ptr = &string[ k-1 ];    /* char before terminating nul */
  157. while (*ptr==BLANK || *ptr==TAB || *ptr==NEWLINE)
  158.     *ptr--  = '\0';
  159. }
  160. /*********************************************
  161.     distribute words evenly across a line
  162. **********************************************/
  163. void spread ( line, nextra, no_words)
  164. char *line;
  165. int nextra;    /* no. extra places left in line */
  166. int no_words;   /* no. words in the line         */
  167. {int i, j, nblanks, nholes, half;
  168. if (nextra <= 0 ) return;
  169. if (DOTJ==0) return;
  170. if ((no_words<=1)&&(DOTJ==1))    return;
  171. DIR = !(DIR);
  172. nholes = no_words - 1;
  173. trunc_bl (line);
  174. i = strlen(line) - 1 ; /* last character of string */
  175. j = min(MAXLINE-2,i+nextra);    /* last  position in output */
  176. line[j+1] = '\0';
  177. switch(DOTJ)
  178. {case 1: /*both margins*/
  179.      for ( ; i<j ; i--, j-- )
  180.         { line[j] = line[i];
  181.           if ( line[i] == BLANK)
  182.               { if (DIR == 0) nblanks=(nextra-1)/nholes+1;
  183.             else        nblanks = nextra/nholes;
  184.             nextra = nextra - nblanks;
  185.             nholes = nholes - 1;
  186.             for ( ; nblanks > 0;  nblanks-- )
  187.                 line[--j] = BLANK;
  188.               }
  189.         }
  190.     break;
  191.  case 3: /*center*/
  192.     for(half=nextra/2; half; half--)
  193.         line[j--] = BLANK;
  194.     for( ; i>=0; i--,j-- )
  195.         line[j] = line[i];
  196.     for( ; j>=0; j-- )
  197.         line[j] = BLANK;
  198.     break;
  199.  case 5: /*right margin only*/
  200.     for( ; i>=0; i--,j-- )
  201.         line[j] = line[i];
  202.     for( ; j>=0; j-- )
  203.         line[j] = BLANK;
  204.  }
  205. }
  206. /************************************************/
  207. void adjust()    /* handle .ad request */
  208. {int i; ARGs a; char c;
  209.  i = process(&a);
  210.  JUSTIFY = YES;
  211.  if(i==0) return;
  212.  c = toupper(a.arg[1][0]);
  213.  switch(c)
  214.     {case 'L': DOTJ = 0; break;
  215.      case 'B':
  216.      case 'N': DOTJ = 1; break;
  217.      case 'C': DOTJ = 3; break;
  218.      case 'R': DOTJ = 5; break;
  219.     }
  220. }
  221. /************************************************
  222. place portion of title line with optional page no. in OUTBUF2
  223. *************************************************/
  224. void puttl (char *str, int num, FORMAT fmt)
  225. {char c;
  226. for ( ;'\0'!=(c= *str); str++)
  227.     {if ( c != NUMSIGN ) putout(c);
  228.     else putnum(num,fmt);
  229.     }
  230. }
  231. /*******************************************
  232.     put out num to OUTBUF2 (conversion)
  233. ********************************************/
  234. void putnum ( int num, FORMAT fmt )
  235. {int i, nd;
  236.  char chars[MAXLINE];
  237.     nd = itoC( num, chars, fmt );
  238.     for ( i=0;i<nd; i++) putout(chars[i]);
  239. }
  240. /*********************************************/
  241. /* itoC() converts a non-negative num <30000 */
  242. /* into a character representation returned  */
  243. /* in buff[] in the format specified by fmt. */
  244. /* fmt = (fill char) + 128*(min width).  It  */
  245. /* returns the length of the string.         */
  246. /*********************************************/
  247. int  itoC(int num, char buff[], FORMAT fmt)
  248. {int sl;
  249.  if (fmt.typ == 'i') strlwr(itoR(num, buff));
  250.  else if (fmt.typ=='I') itoR(num, buff);
  251.  else if (fmt.typ=='a') strlwr(itoA(num, buff));
  252.  else if (fmt.typ=='A') itoA(num, buff);
  253.  else itoa(num, buff, 10);
  254.  sl = strlen(buff);
  255.  if (sl >= fmt.minwidth) return (sl);
  256.  /* we need to left pad the string */
  257.  do buff[fmt.minwidth--] = buff[sl--];  while (sl >=0);
  258.  do buff[fmt.minwidth--] = fmt.fill;  while (fmt.minwidth >=0);
  259.  return ( strlen(buff) );
  260. }
  261. /*****************************************************************/
  262. /* itoR converts an integer into upper case roman numeral string */
  263. /*  it is similar in spirit to itoa()                            */
  264. /*****************************************************************/
  265. char *itoR(int value, char *string )
  266. {int digit;
  267. string[0]='\0';
  268. if (value==0) {string[0]='0'; string[1]='\0';}
  269. if (value<1)  return(string);
  270. digit = value / 1000 ;
  271. while (digit>0) {strcat(string,"M");digit--;}
  272. value = value % 1000;
  273. digit = value / 100 ;
  274. if (digit<4)
  275.    while (digit>0) {strcat(string,"C");digit--;}
  276. if (digit==4) strcat(string,"CD");
  277. if (digit==9) strcat(string,"CM");
  278. else if (digit>4)
  279.     {strcat(string,"D");
  280.          while (digit>5) {strcat(string,"C"); digit--;}
  281.          }
  282. value = value % 100;
  283. digit = value / 10 ;
  284. if (digit<4)
  285.    while (digit>0) {strcat(string,"X");digit--;}
  286. if (digit==4) strcat(string,"XL");
  287. if (digit==9) strcat(string,"XC");
  288. else if (digit>4)
  289.     {strcat(string,"L");
  290.          while (digit>5) {strcat(string,"X"); digit--;}
  291.          }
  292. digit = value % 10;
  293. if (digit<4)
  294.    while (digit>0) {strcat(string,"I");digit--;}
  295. if (digit==4) strcat(string,"IV");
  296. if (digit==9) strcat(string,"IX");
  297. else if (digit>4)
  298.     {strcat(string,"V");
  299.          while (digit>5) {strcat(string,"I"); digit--;}
  300.          }
  301.  
  302. return (string);
  303. }
  304. /*****************************************************************/
  305. /* itoA converts an integer into 0, A, B, .. AA, AB,..  strings  */
  306. /*  it is similar in spirit to itoa()                            */
  307. /*****************************************************************/
  308. char *itoA(int value, char *string )
  309. {int digit;
  310.  char c;
  311.  char lbuff[10], *sp;
  312.  string[0]='\0';
  313.  if (value==0) {string[0]='0'; string[1]='\0';}
  314.  if (value<1) return(string);
  315.  sp = &lbuff[9];
  316.  *sp = '\0';
  317.  while (value > 0)
  318.     {digit = value % 26;
  319.      if (digit==0)  *(--sp)='Z';
  320.      else *(--sp) = 'A'-1+digit;
  321.      value -= *sp - 'A'+1 ;
  322.      value /= 26;
  323.     }
  324.  strcpy(string,sp);
  325.  return ( string );
  326. }
  327. /****************************************/
  328. void putout(char c)    /*places c in OUTBUF2[]*/
  329. {if(c==SCVAL[0]) c= BLANK;
  330. if(c==NEWLINE)c='\0';
  331. OUTBUF2[BPOS++]=c;
  332. OUTBUF2[BPOS]='\0';/*safty net*/
  333. }
  334.