home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d3xx / d352 / mg.lha / MG / src.LZH / mg / paragraph.c < prev    next >
C/C++ Source or Header  |  1990-05-23  |  8KB  |  296 lines

  1. /*
  2.  * Code for dealing with paragraphs and filling. Adapted from MicroEMACS 3.6
  3.  * and GNU-ified by mwm@ucbvax.     Several bug fixes by blarson@usc-oberon.
  4.  */
  5. #include "def.h"
  6. #include "line.h"
  7. #include "buffer.h"
  8. #include "window.h"
  9.  
  10. static int      fillcol = 70;
  11. #define MAXWORD 256
  12.  
  13. /*
  14.  * go back to the begining of the current paragraph here we look for a
  15.  * <NL><NL> or <NL><TAB> or <NL><SPACE> combination to delimit the begining
  16.  * of a paragraph
  17.  */
  18. /* ARGSUSED */
  19. gotobop(f, n)
  20. {
  21.     if (n < 0)        /* the other way... */
  22.         return gotoeop(f, -n);
  23.  
  24.     while (n-- > 0) {    /* for each one asked for */
  25.  
  26.         /* first scan back until we are in a word */
  27.  
  28.         while (backchar(FFRAND, 1) && !inword()) {
  29.         }
  30.         curwp->w_doto = 0;    /* and go to the B-O-Line */
  31.  
  32.         /*
  33.          * and scan back until we hit a <NL><SP> <NL><TAB> or
  34.          * <NL><NL>
  35.          */
  36.         while (lback(curwp->w_dotp) != curbp->b_linep)
  37.             if (llength(lback(curwp->w_dotp))
  38.                 && lgetc(curwp->w_dotp, 0) != ' '
  39.                 && lgetc(curwp->w_dotp, 0) != '\t')
  40.                 curwp->w_dotp = lback(curwp->w_dotp);
  41.             else
  42.                 break;
  43.     }
  44.     curwp->w_flag |= WFMOVE;/* force screen update */
  45.     return TRUE;
  46. }
  47.  
  48. /*
  49.  * go forword to the end of the current paragraph here we look for a <NL><NL>
  50.  * or <NL><TAB> or <NL><SPACE> combination to delimit the begining of a
  51.  * paragraph
  52.  */
  53. /* ARGSUSED */
  54. gotoeop(f, n)
  55. {
  56.     if (n < 0)        /* the other way... */
  57.         return gotobop(f, -n);
  58.  
  59.     while (n-- > 0) {    /* for each one asked for */
  60.  
  61.         /* Find the first word on/after the current line */
  62.         curwp->w_doto = 0;
  63.         while (forwchar(FFRAND, 1) && !inword()) {
  64.         }
  65.         curwp->w_doto = 0;
  66.         curwp->w_dotp = lforw(curwp->w_dotp);
  67.         /* and scan forword until we hit a <NL><SP> or ... */
  68.         while (curwp->w_dotp != curbp->b_linep) {
  69.             if (llength(curwp->w_dotp)
  70.                 && lgetc(curwp->w_dotp, 0) != ' '
  71.                 && lgetc(curwp->w_dotp, 0) != '\t')
  72.                 curwp->w_dotp = lforw(curwp->w_dotp);
  73.             else
  74.                 break;
  75.         }
  76.         if (curwp->w_dotp == curbp->b_linep) {
  77.             /* beond end of buffer, cleanup time */
  78.             curwp->w_dotp = lback(curwp->w_dotp);
  79.             curwp->w_doto = llength(curwp->w_dotp);
  80.             break;
  81.         }
  82.     }
  83.     curwp->w_flag |= WFMOVE;/* force screen update */
  84.     return TRUE;
  85. }
  86.  
  87. /*
  88.  * Fill the current paragraph according to the current fill column
  89.  */
  90. /* ARGSUSED */
  91. fillpara(f, n)
  92. {
  93.     register int    c;    /* current char durring scan     */
  94.     register int    wordlen;/* length of current word     */
  95.     register int    clength;/* position on line during fill */
  96.     register int    i;    /* index during word copy     */
  97.     register int    eopflag;/* Are we at the End-Of-Paragraph? */
  98.     int             firstflag;    /* first word? (needs no space) */
  99.     int             newlength;    /* tentative new line length     */
  100.     int             eolflag;/* was at end of line         */
  101.     struct line    *eopline;/* pointer to line just past EOP */
  102.     char            wbuf[MAXWORD];    /* buffer for current word     */
  103.  
  104.     /* record the pointer to the line just past the EOP */
  105.     (VOID) gotoeop(FFRAND, 1);
  106.     if (curwp->w_doto != 0) {
  107.         /* paragraph ends at end of buffer */
  108.         (VOID) lnewline();
  109.         eopline = lforw(curwp->w_dotp);
  110.     } else
  111.         eopline = curwp->w_dotp;
  112.  
  113.     /* and back top the begining of the paragraph */
  114.     (VOID) gotobop(FFRAND, 1);
  115.  
  116.     /* initialize various info */
  117.     while (!inword() && forwchar(FFRAND, 1)) {
  118.     }
  119.     for (clength = i = 0; i < curwp->w_doto; i += 1)
  120.         if (ltext(curwp->w_dotp)[i] == '\t')
  121.             clength |= 0x07;
  122.         else
  123.             clength += 1;
  124.     wordlen = 0;
  125.  
  126.     /* scan through lines, filling words */
  127.     firstflag = TRUE;
  128.     eopflag = FALSE;
  129.     while (!eopflag) {
  130.         /* get the next character in the paragraph */
  131.         if (eolflag = (curwp->w_doto == llength(curwp->w_dotp))) {
  132.             c = ' ';
  133.             if (lforw(curwp->w_dotp) == eopline)
  134.                 eopflag = TRUE;
  135.         } else
  136.             c = lgetc(curwp->w_dotp, curwp->w_doto);
  137.  
  138.         /* and then delete it */
  139.         if (fdelete((RSIZE) 1, FALSE) == FALSE && !eopflag)
  140.             return FALSE;
  141.  
  142.         /* if not a separator, just add it in */
  143.         if (c != ' ' && c != '\t') {
  144.             if (wordlen < MAXWORD - 1)
  145.                 wbuf[wordlen++] = c;
  146.             else {
  147.                 /*
  148.                  * You loose chars beyond MAXWORD if the word
  149.                  * is to long. I'm to lazy to fix it now; it
  150.                  * just silently truncated the word before,
  151.                  * so I get to feel smug.
  152.                  */
  153.                 ewprintf("Word too long!");
  154.             }
  155.         } else if (wordlen) {
  156.             /* calculate tenatitive new length with word added */
  157.             newlength = clength + 1 + wordlen;
  158.             /*
  159.              * if at end of line or at doublespace and previous
  160.              * character was one of '.','?','!' doublespace here.
  161.              */
  162.             if ((eolflag || curwp->w_doto == llength(curwp->w_dotp)
  163.              || (c = lgetc(curwp->w_dotp, curwp->w_doto)) == ' '
  164.                  || c == '\t')
  165.                 && ISEOSP(wbuf[wordlen - 1])
  166.                 && wordlen < MAXWORD - 1)
  167.                 wbuf[wordlen++] = ' ';
  168.             /* at a word break with a word waiting */
  169.             if (newlength <= fillcol) {
  170.                 /* add word to current line */
  171.                 if (!firstflag) {
  172.                     (VOID) linsert(1, ' ');
  173.                     ++clength;
  174.                 }
  175.                 firstflag = FALSE;
  176.             } else {
  177.                 if (curwp->w_doto > 0 &&
  178.                     lgetc(curwp->w_dotp, curwp->w_doto - 1) == ' ') {
  179.                     curwp->w_doto -= 1;
  180.                     (VOID) fdelete((RSIZE) 1, FALSE);
  181.                 }
  182.                 /* start a new line */
  183.                 (VOID) lnewline();
  184.                 clength = 0;
  185.             }
  186.  
  187.             /* and add the word in in either case */
  188.             for (i = 0; i < wordlen; i++) {
  189.                 (VOID) linsert(1, wbuf[i]);
  190.                 ++clength;
  191.             }
  192.             wordlen = 0;
  193.         }
  194.     }
  195.     /* and add a last newline for the end of our new paragraph */
  196.     (VOID) lnewline();
  197.     /*
  198.      * we realy should wind up where we started, (which is hard to keep
  199.      * track of) but I think the end of the last line is better than the
  200.      * begining of the blank line.
  201.      */
  202.     (VOID) backchar(FFRAND, 1);
  203.     return TRUE;
  204. }
  205.  
  206. /* delete n paragraphs starting with the current one */
  207. /* ARGSUSED */
  208. killpara(f, n)
  209. {
  210.     register int    status;    /* returned status of functions */
  211.  
  212.     while (n--) {        /* for each paragraph to delete */
  213.  
  214.         /* mark out the end and begining of the para to delete */
  215.         (VOID) gotoeop(FFRAND, 1);
  216.  
  217.         /* set the mark here */
  218.         curwp->w_markp = curwp->w_dotp;
  219.         curwp->w_marko = curwp->w_doto;
  220.  
  221.         /* go to the begining of the paragraph */
  222.         (VOID) gotobop(FFRAND, 1);
  223.         curwp->w_doto = 0;    /* force us to the begining of line */
  224.  
  225.         /* and delete it */
  226.         if ((status = killregion(FFRAND, 1)) != TRUE)
  227.             return status;
  228.  
  229.         /* and clean up the 2 extra lines */
  230.         (VOID) fdelete((RSIZE) 1, TRUE);
  231.     }
  232.     return TRUE;
  233. }
  234.  
  235. /*
  236.  * check to see if we're past fillcol, and if so, justify this line. As a
  237.  * last step, justify the line.
  238.  */
  239. /* ARGSUSED */
  240. fillword(f, n)
  241. {
  242.     register char   c;
  243.     register int    col, i, nce;
  244.  
  245.     for (i = col = 0; col <= fillcol; ++i, ++col) {
  246.         if (i == curwp->w_doto)
  247.             return selfinsert(f, n);
  248.         c = lgetc(curwp->w_dotp, i);
  249.         if (c == '\t'
  250. #ifdef    NOTAB
  251.             && !(curbp->b_flag & BFNOTAB)
  252. #endif
  253.             )
  254.             col |= 0x07;
  255.         else if (ISCTRL(c) != FALSE)
  256.             ++col;
  257.     }
  258.     if (curwp->w_doto != llength(curwp->w_dotp)) {
  259.         (VOID) selfinsert(f, n);
  260.         nce = llength(curwp->w_dotp) - curwp->w_doto;
  261.     } else
  262.         nce = 0;
  263.     curwp->w_doto = i;
  264.  
  265.     if ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ' && c != '\t')
  266.         do {
  267.             (VOID) backchar(FFRAND, 1);
  268.         } while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' '
  269.              && c != '\t' && curwp->w_doto > 0);
  270.  
  271.     if (curwp->w_doto == 0)
  272.         do {
  273.             (VOID) forwchar(FFRAND, 1);
  274.         } while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' '
  275.             && c != '\t' && curwp->w_doto < llength(curwp->w_dotp));
  276.  
  277.     (VOID) delwhite(FFRAND, 1);
  278.     (VOID) lnewline();
  279.     i = llength(curwp->w_dotp) - nce;
  280.     curwp->w_doto = i > 0 ? i : 0;
  281.     curwp->w_flag |= WFMOVE;
  282.     if (nce == 0 && curwp->w_doto != 0)
  283.         return fillword(f, n);
  284.     return TRUE;
  285. }
  286.  
  287. /* Set fill column to n. */
  288. setfillcol(f, n)
  289. {
  290.     extern int      getcolpos();
  291.  
  292.     fillcol = ((f & FFARG) ? n : getcolpos());
  293.     ewprintf("Fill column set to %d", fillcol);
  294.     return TRUE;
  295. }
  296.