home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 December / simtel1292_SIMTEL_1292_Walnut_Creek.iso / msdos / c / cc03.arc / NROTXT.C < prev    next >
Text File  |  1985-09-12  |  14KB  |  638 lines

  1. /*
  2.  *      Text processing portion of NRO word processor
  3.  *
  4.  *      Stephen L. Browning
  5.  *      5723 North Parker Avenue
  6.  *      Indianapolis, Indiana 46220
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include "nro.h"
  11. #include "nroxtrn.h"
  12.  
  13. text(p)
  14. char *p;
  15. {
  16.         int i;
  17.         char wrdbuf[MAXLINE];
  18.  
  19.         if (*p == ' ' || *p == '\n' || *p == '\r') leadbl(p);
  20.         expesc(p,wrdbuf);
  21.         if (dc.ulval > 0) {
  22.                 /*
  23.                 *       Because of the way underlining is handled,
  24.                 *       MAXLINE should be declared to be three times
  25.                 *       larger than the longest expected input line
  26.                 *       for underlining.  Since many of the character
  27.                 *       buffers use this parameter, a lot of memory
  28.                 *       can be allocated when it may not really be
  29.                 *       needed.  A MAXLINE of 180 would allow about
  30.                 *       60 characters in the output line to be
  31.                 *       underlined (remember that only alphanumerics
  32.                 *       get underlined - no spaces or punctuation).
  33.                 */
  34.                 underl(p,wrdbuf,MAXLINE);
  35.                 --dc.ulval;
  36.         }
  37.         if (dc.cuval > 0) {
  38.                 underl(p,wrdbuf,MAXLINE);
  39.                 --dc.cuval;
  40.         }
  41.         if (dc.boval > 0) {
  42.                 bold(p,wrdbuf,MAXLINE);
  43.                 --dc.boval;
  44.         }
  45.         if (dc.ceval > 0) {
  46.                 center(p);
  47.                 put(p);
  48.                 --dc.ceval;
  49.         }
  50.         else if (*p == '\r' || *p == '\n') put(p); /* all blank line */
  51.         else if (dc.fill == NO) put(p);         /* unfilled */
  52.         else {
  53.                 while ((i = getwrd(p,wrdbuf)) > 0) {
  54.                         putwrd(wrdbuf);
  55.                         p += i;
  56.                 }
  57.         }
  58. }
  59.  
  60.  
  61. /*
  62.  *      insert bold face text
  63.  */
  64.  
  65. bold(p0,p1,size)
  66. char *p0, *p1;
  67. int size;
  68. {
  69.         int i, j;
  70.  
  71.         j = 0;
  72.         for (i=0; (p0[i] != '\n') && (j < size-1); ++i) {
  73.                 if (isalpha(p0[i]) || isdigit(p0[i])) {
  74.                         p1[j++] = p0[i];
  75.                         p1[j++] = '\b';
  76.                 }
  77.                 p1[j++] = p0[i];
  78.         }
  79.         p1[j++] = '\n';
  80.         p1[j] = EOS;
  81.         while (*p1 != EOS) *p0++ = *p1++;
  82.         *p0 = EOS;
  83. }
  84.  
  85.  
  86.  
  87.  
  88. /*
  89.  *      center a line by setting tival
  90.  */
  91.  
  92. center(p)
  93. char *p;
  94. {
  95.         dc.tival = max((dc.rmval + dc.tival - width(p)) >> 1,0);
  96. }
  97.  
  98.  
  99. /*
  100.  *      expand title buffer to include character string
  101.  */
  102.  
  103. expand(p0,c,s)
  104. char *p0;
  105. char c;
  106. char *s;
  107. {
  108.         char tmp[MAXLINE];
  109.         char *p, *q, *r;
  110.  
  111.         p = p0;
  112.         q = tmp;
  113.         while (*p != EOS) {
  114.                 if (*p == c) {
  115.                         r = s;
  116.                         while (*r != EOS) *q++ = *r++;
  117.                 }
  118.                 else *q++ = *p;
  119.                 ++p;
  120.         }
  121.         *q = EOS;
  122.         strcpy(p0,tmp);         /* copy it back */
  123. }
  124.  
  125.  
  126. /*
  127.  *      get field from title
  128.  */
  129.  
  130. char *getfield(p,q,delim)
  131. char *p, *q;
  132. char delim;
  133. {
  134.         while (*p != delim && *p != '\r' && *p != '\n' && *p != EOS) {
  135.                 *q++ = *p++;
  136.         }
  137.         *q = EOS;
  138.         if (*p == delim) ++p;
  139.         return(p);
  140. }
  141.  
  142.  
  143.  
  144. /*
  145.  *      get non-blank word from p0 into p1.
  146.  *      return number of characters processed.
  147.  */
  148.  
  149. getwrd(p0,p1)
  150. char *p0,*p1;
  151. {
  152.         int i;
  153.         char *p, c;
  154.  
  155.         i = 0;
  156.         while (*p0 == ' ' || *p0 == '\t') {
  157.                 ++i;
  158.                 ++p0;
  159.         }
  160.         p = p0;
  161.         while (*p0 != ' ' && *p0 != EOS && *p0 != '\t') {
  162.                 if (*p0 == '\n' || *p0 == '\r') break;
  163.                 *p1 = *p0++;
  164.                 ++p1;
  165.                 ++i;
  166.         }
  167.         c = *(p1-1);
  168.         if (c == '"') c = *(p1-2);
  169.         if (c == '?' || c == '!') {
  170.                 *p1++ = ' ';
  171.                 ++i;
  172.         }
  173.         if (c == '.' && (*p0 == '\n' || *p0 == '\r' || islower(*p))) {
  174.                 *p1++ = ' ';
  175.                 ++i;
  176.         }
  177.         *p1 = EOS;
  178.         return(i);
  179. }
  180.  
  181.  
  182. /*
  183.  *      convert integer to decimal ascii string
  184.  */
  185.  
  186. itoda(value,p,size)
  187. int value;
  188. char *p;
  189. int size;
  190. {
  191.         char c[7];
  192.         int i, j, k;
  193.         int aval;
  194.  
  195.         aval = abs(value);
  196.         c[0] = EOS;
  197.         i = 1;
  198.         do {
  199.                 c[i++] = (aval % 10) + '0';
  200.                 aval /= 10;
  201.         } while (aval > 0 && i <= size);
  202.         if (value < 0 && i <= size) c[i++] = '-';
  203.         for (j=0; j<i; ++j) *p++ = c[i-j-1];
  204.         return(i);
  205. }
  206.  
  207.  
  208. /*
  209.  *      center title text into print buffer
  210.  */
  211.  
  212. justcntr(p,q,limit)
  213. char *p, *q;
  214. int limit[];
  215. {
  216.         int len;
  217.  
  218.         len = width(p);
  219.         q = &q[(limit[RIGHT] + limit[LEFT] - len) >> 1];
  220.         while (*p != EOS) *q++ = *p++;
  221. }
  222.  
  223.  
  224.  
  225. /*
  226.  *      left justify title text into print buffer
  227.  */
  228.  
  229. justleft(p,q,limit)
  230. char *p, *q;
  231. int limit;
  232. {
  233.         q = &q[limit];
  234.         while (*p != EOS) *q++ = *p++;
  235. }
  236.  
  237.  
  238. /*
  239.  *      right justify title text into print buffer
  240.  */
  241.  
  242. justrite(p,q,limit)
  243. char *p, *q;
  244. int limit;
  245. {
  246.         int len;
  247.  
  248.         len = width(p);
  249.         q = &q[limit - len];
  250.         while (*p != EOS) *q++ = *p++;
  251. }
  252.  
  253.  
  254.  
  255.  
  256. /*
  257.  *      delete leading blanks, set tival
  258.  */
  259.  
  260. leadbl(p)
  261. char *p;
  262. {
  263.         int i,j;
  264.  
  265.         brk();
  266.         for (i=0; p[i] == ' '; ++i) ;
  267.         if (p[i] != '\n' && p[i] != '\r') dc.tival = i;
  268.         for (j=0; p[i] != EOS; ++j) p[j] = p[i++];
  269.         p[j] = EOS;
  270. }
  271.  
  272.  
  273.  
  274. /*
  275.  *      find minimum of two integer
  276.  */
  277.  
  278. min(v1,v2)
  279. int v1,v2;
  280. {
  281.         return((v1 < v2) ? v1 : v2);
  282. }
  283.  
  284.  
  285.  
  286. /*
  287.  *      find maximum of two integers
  288.  */
  289.  
  290. max(v1,v2)
  291. int v1,v2;
  292. {
  293.         return((v1 > v2) ? v1 : v2);
  294. }
  295.  
  296.  
  297.  
  298. /*
  299.  *      put out page footer
  300.  */
  301.  
  302. pfoot()
  303. {
  304.         if (dc.prflg == TRUE) {
  305.                 skip(pg.m3val);
  306.                 if (pg.m4val > 0) {
  307.                         if ((pg.curpag % 2) == 0) {
  308.                                 puttl(pg.efoot,pg.eflim,pg.curpag);
  309.                         }
  310.                         else {
  311.                                 puttl(pg.ofoot,pg.oflim,pg.curpag);
  312.                         }
  313.                         skip(pg.m4val - 1);
  314.                 }
  315.         }
  316. }
  317.  
  318.  
  319.  
  320. /*
  321.  *      put out page header
  322.  */
  323.  
  324. phead()
  325. {
  326.         pg.curpag = pg.newpag;
  327.         if (pg.curpag >= pg.frstpg && pg.curpag <= pg.lastpg) {
  328.                 dc.prflg = TRUE;
  329.         }
  330.         else {
  331.                 dc.prflg = FALSE;
  332.         }
  333.         ++pg.newpag;
  334.         if (dc.prflg == TRUE) {
  335.                 if (pg.m1val > 0) {
  336.                         skip(pg.m1val - 1);
  337.                         if ((pg.curpag % 2) == 0) {
  338.                                 puttl(pg.ehead,pg.ehlim,pg.curpag);
  339.                         }
  340.                         else {
  341.                                 puttl(pg.ohead,pg.ohlim,pg.curpag);
  342.                         }
  343.                 }
  344.                 skip(pg.m2val);
  345.         }
  346.         /*
  347.         *       initialize lineno for the next page
  348.         */
  349.         pg.lineno = pg.m1val + pg.m2val + 1;
  350. }
  351.  
  352.  
  353. /*
  354.  *      print character with test for printer
  355.  */
  356.  
  357. prchar(c,fp)
  358. char c;
  359. FILE *fp;
  360. {
  361.         if (co.lpr == TRUE) {
  362.                 bdos(5,c);
  363.         }
  364.         else {
  365.                 putc(c,fp);
  366.         }
  367. }
  368.  
  369.  
  370.  
  371.  
  372. /*
  373.  *      put out line with proper spacing and indenting
  374.  */
  375.  
  376. put(p)
  377. char *p;
  378. {
  379.         char os[MAXLINE];
  380.         int j;
  381.  
  382.         if (pg.lineno == 0 || pg.lineno > pg.bottom) {
  383.                 phead();
  384.         }
  385.         if (dc.prflg == TRUE) {
  386.                 if (!dc.bsflg) {
  387.                         if (strkovr(p,os) == TRUE) {
  388.                                 for (j=0; j<pg.offset; ++j) prchar(' ',pout);
  389.                                 for (j=0; j<dc.tival; ++j) prchar(' ',pout);
  390.                                 putlin(os,pout);
  391.                         }
  392.                 }
  393.                 for (j=0; j<pg.offset; ++j) prchar(' ',pout);
  394.                 for (j=0; j<dc.tival; ++j) prchar(' ',pout);
  395.                 putlin(p,pout);
  396.         }
  397.         dc.tival = dc.inval;
  398.         skip(min(dc.lsval-1,pg.bottom-pg.lineno));
  399.         pg.lineno = pg.lineno + dc.lsval;
  400.         if (pg.lineno > pg.bottom) pfoot();
  401. }
  402.  
  403.  
  404. /*
  405.  *      output a null terminated string to the file
  406.  *      specified by pbuf.
  407.  */
  408.  
  409. putlin(p,pbuf)
  410. char *p;
  411. struct buf *pbuf;
  412. {
  413.         while (*p != EOS) prchar(*p++,pbuf);
  414. }
  415.  
  416.  
  417.  
  418. /*
  419.  *      put out title or footer
  420.  */
  421.  
  422. puttl(p,lim,pgno)
  423. char *p;
  424. int lim[];
  425. int pgno;
  426. {
  427.         int i;
  428.         char pn[8];
  429.         char t[MAXLINE];
  430.         char h[MAXLINE];
  431.         char delim;
  432.  
  433.         itoda(pgno,pn,6);
  434.         for (i=0; i<MAXLINE; ++i) h[i] = ' ';
  435.         delim = *p++;
  436.         p = getfield(p,t,delim);
  437.         expand(t,dc.pgchr,pn);
  438.         justleft(t,h,lim[LEFT]);
  439.         p = getfield(p,t,delim);
  440.         expand(t,dc.pgchr,pn);
  441.         justcntr(t,h,lim);
  442.         p = getfield(p,t,delim);
  443.         expand(t,dc.pgchr,pn);
  444.         justrite(t,h,lim[RIGHT]);
  445.         for (i=MAXLINE-4; h[i] == ' '; --i) h[i] = EOS;
  446.         h[++i] = '\n';
  447.         h[++i] = '\r';
  448.         h[++i] = EOS;
  449.         if (strlen(h) > 2) {
  450.                 for (i=0; i<pg.offset; ++i) prchar(' ',pout);
  451.         }
  452.         putlin(h,pout);
  453. }
  454.  
  455.  
  456.  
  457. /*
  458.  *      put word in output buffer
  459.  */
  460.  
  461. putwrd(wrdbuf)
  462. char *wrdbuf;
  463. {
  464.         int w;
  465.         int last;
  466.         int llval;
  467.         char *p0, *p1;
  468.         int nextra;
  469.  
  470.         w = width(wrdbuf);
  471.         last = strlen(wrdbuf) + co.outp;
  472.         llval = dc.rmval - dc.tival;
  473.         if(((co.outp > 0) && ((co.outw + w) > llval)) || (last > MAXLINE)) {
  474.                 last -= co.outp;
  475.                 if(dc.juval == YES) {
  476.                         nextra = llval - co.outw + 1;
  477.                         /*
  478.                         *       Check whether last word was end of
  479.                         *       sentence and modify counts so that
  480.                         *       it is right justified.
  481.                         */
  482.                         if (co.outbuf[co.outp-2] == ' ') {
  483.                                 --co.outp;
  484.                                 ++nextra;
  485.                         }
  486.                         spread(co.outbuf,co.outp-1,nextra,co.outwds);
  487.                         if((nextra > 0) && (co.outwds > 1)) {
  488.                                 co.outp += (nextra - 1);
  489.                         }
  490.                 }
  491.                 brk();
  492.         }
  493.         p0 = wrdbuf;
  494.         p1 = co.outbuf + co.outp;
  495.         while(*p0 != EOS) *p1++ = *p0++;
  496.         co.outp = last;
  497.         co.outbuf[co.outp++] = ' ';
  498.         co.outw += w + 1;
  499.         ++co.outwds;
  500. }
  501.  
  502.  
  503. /*
  504.  *      skips the number of lines specified by n.
  505.  */
  506.  
  507. skip(n)
  508. int n;
  509. {
  510.         int i;
  511.  
  512.         if (dc.prflg == TRUE && n > 0) {
  513.                 for(i=0; i<n; ++i) {
  514.                         prchar('\n',pout);
  515.                 }
  516.                 prchar('\r',pout);
  517.         }
  518. }
  519.  
  520.  
  521.  
  522. /*
  523.  *      spread words to justify right margin
  524.  */
  525.  
  526. spread(p,outp,nextra,outwds)
  527. char p[];
  528. int outp,nextra,outwds;
  529. {
  530.         int i,j;
  531.         int nb,ne,nholes;
  532.  
  533.         if((nextra <= 0) || (outwds <= 1)) return;
  534.         dc.sprdir = ~dc.sprdir;
  535.         ne = nextra;
  536.         nholes = outwds - 1;    /* holes between words */
  537.         i = outp - 1;   /* last non-blank character */
  538.         j = min(MAXLINE-3,i+ne); /* leave room for CR, LF, EOS  */
  539.         while(i < j) {
  540.                 p[j] = p[i];
  541.                 if(p[i] == ' ') {
  542.                         if(dc.sprdir == 0) nb = (ne - 1)/nholes + 1;
  543.                         else nb = ne/nholes;
  544.                         ne -= nb;
  545.                         --nholes;
  546.                         for(; nb>0; --nb) {
  547.                                 --j;
  548.                                 p[j] = ' ';
  549.                         }
  550.                 }
  551.                 --i;
  552.                 --j;
  553.         }
  554. }
  555.  
  556.  
  557.  
  558. /*
  559.  *      split overstrikes (backspaces) into seperate buffer
  560.  */
  561.  
  562. strkovr(p,q)
  563. char *p, *q;
  564. {
  565.         char *pp;
  566.         int bsflg;
  567.  
  568.         bsflg = FALSE;
  569.         pp = p;
  570.         while (*p != EOS) {
  571.                 *q = ' ';
  572.                 *pp = *p;
  573.                 ++p;
  574.                 if (*p == '\b') {
  575.                         if (*pp >= ' ' && *pp <= '~') {
  576.                                 bsflg = TRUE;
  577.                                 *q = *pp;
  578.                                 ++p;
  579.                                 *pp = *p;
  580.                                 ++p;
  581.                         }
  582.                 }
  583.                 ++q;
  584.                 ++pp;
  585.         }
  586.         *q++ = '\r';
  587.         *q = *pp = EOS;
  588.         return(bsflg);
  589. }
  590.  
  591.  
  592.  
  593. /*
  594.  *      underline a line
  595.  */
  596.  
  597. underl(p0,p1,size)
  598. char *p0,*p1;
  599. int size;
  600. {
  601.         int i,j;
  602.  
  603.         j = 0;
  604.         for (i=0; (p0[i] != '\n') && (j < size-1); ++i) {
  605.                 if (p0[i] >= ' ' && p0[i] <= '~') {
  606.                         if (isalpha(p0[i]) || isdigit(p0[i]) || dc.cuval > 0) {
  607.  
  608.                                 p1[j++] = '_';
  609.                                 p1[j++] = '\b';
  610.                         }
  611.                 }
  612.                 p1[j++] = p0[i];
  613.         }
  614.         p1[j++] = '\n';
  615.         p1[j] = EOS;
  616.         while (*p1 != EOS) *p0++ = *p1++;
  617.         *p0 = EOS;
  618. }
  619.  
  620.  
  621. /*
  622.  *      compute width of character string
  623.  */
  624.  
  625. width(s)
  626. char *s;
  627. {
  628.         int w;
  629.  
  630.         w = 0;
  631.         while (*s != EOS) {
  632.                 if (*s == '\b') --w;
  633.                 else if (*s != '\n' && *s != '\r') ++w;
  634.                 ++s;
  635.         }
  636.         return(w);
  637. }
  638. +