diff -rc pine4.33/pico/efunc.h pine4.33.fillpara/pico/efunc.h *** pine4.33/pico/efunc.h Thu Dec 28 15:21:13 2000 --- pine4.33.fillpara/pico/efunc.h Fri Jul 6 14:09:58 2001 *************** *** 332,336 **** --- 332,337 ---- extern int fillpara PROTO((int, int)); extern int inword PROTO((void)); extern int quote_match PROTO((char *, LINE *)); + extern int is_quote PROTO((int [])); #endif /* EFUNC_H */ diff -rc pine4.33/pico/word.c pine4.33.fillpara/pico/word.c *** pine4.33/pico/word.c Tue May 16 15:57:52 2000 --- pine4.33.fillpara/pico/word.c Fri Jul 6 14:10:21 2001 *************** *** 377,383 **** --- 377,521 ---- return(1); } + #define is_cword(c) ((((c) >= 'a') && ((c) <= 'z')) || \ + (((c) >= 'A') && ((c) <= 'Z')) || \ + (((c) >= '0') && ((c) <= '9')) || \ + ((c) == ' ') || ((c) == '?') || \ + ((c) == '@') || ((c) == '.') || \ + ((c) == '!') || ((c) == '\'') || \ + ((c) == ',') || ((c) == '\"') ? 1 : 0) + #define isaquote(c) ((c) == '\"' || (c) == '\'') + #define is_cletter(c) ((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z') + #define is_cnumber(c) ((c) >= '0' && (c) <= '9') + #define allwd_after_word(c) ((c == ' ') || (c == '>') || is_cletter(c)) + #define before(word,i) (((i) > 0) ? word[(i) - 1] : 0) + #define next(word,i) ((word[(i)] != 0) ? word[(i) + 1] : 0) + #define now(word,i) (word[(i)]) + #define is_cquote(c) ((c) == '>' || (c) == '~' || (c) == ':' || (c) == RPAREN || \ + (c) == '|' || (c) == ']') + #define is_dash(c) (((c) == '-') ? 1 : 0) + #define is_pound(c) (((c) == '#') ? 1 : 0) + #define is_space(c) (((c) == ' ') ? 1 : 0) + #define is_allowed(c) (is_cquote(c) || is_cword(c) || is_dash(c) || \ + is_pound(c)) + /* given a string, it returns the position where the function thinks + that the quote string is over, if you are ever thinking of fixing + something, you got to the right place */ + + int is_quote (word) + int word[NSTRING]; + { + int i = 0, q = -1, c, nxt, fllwing, finished = 0; + int words = 0; + + if (!word || !word[0]) + return 0; + + while (!finished && (c = now(word,i))){ + if (is_cquote(c)){ + words = 0; + i++; + } + else{ + if (isspace(c)){ + if (words){ + if (q >= 0){ + while ((i > 0) && is_cword(nxt = before(word,i)) + && !isspace(nxt)) + i--; + finished++; + } + else{ + if (is_cquote(next(word,i))){ + i++; + words = 0; + } + else{ + finished++; + i -= words; + } + } + } + else{ + q = i; + i++; + } + } + else{ + if (is_cword(c) || is_dash(c) || is_pound(c)){ + if (is_dash(c)){ /* dashes can only be followed by qchar */ + if ((is_cquote(nxt = next(word,i))) || + (is_dash(nxt) && (is_cquote(next(word,i+1))))){ + if (!words) + i++; + else{ + finished++; + i -= words + 1; + } + } + else{ + while ((i > 0) && is_cword(nxt = before(word,i)) + && !isspace(nxt)) + i--; + finished++; + } + } + if (is_pound(c)){ + if (((is_allowed(nxt = next(word,i))) && (!is_pound(nxt))) || + (is_pound(nxt) && (is_allowed(fllwing = next(word,i+1))) + && (!is_pound(fllwing)))){ + if (!words) + i++; + else{ + finished++; + i -= words + 1; + } + } + else{ + finished++; + if (nxt == 0) + i += 1; + else + if (fllwing == 0) + i +=2; + } + } + if (is_cword(c)){ + words++; + if (isaquote(c) && isspace(before(word,i))) + finished++; + else{ + if ((words > 3) || + (is_cletter(c) && !allwd_after_word(next(word,i)))){ + finished++; + i -= words - 1 ; + } + else{ + if (is_cnumber(c)) /* no numbers in quote strings */ + finished++; + else + i++; + } + } + } + } + else{ + finished++; + if (words) + while ((i > 0) && is_cword(nxt = before(word,i)) && !isspace(nxt)) + i--; + } + } + } + } + while ((i > 0) && !is_cquote(nxt = before(word,i)) && !isspace(nxt)) + i--; /* a quote string can not end in a letter */ + for (q = 0; isspace(word[q]); q++); + if (q == i) i = 0; /* check for spaces at the beginning of the line */ + return i; + } + fillpara(f, n) /* Fill the current paragraph according to the current fill column */ *************** *** 384,394 **** int f, n; /* deFault flag and Numeric argument */ { ! int i, j, c, qlen, word[NSTRING], same_word, ! spaces, word_len, line_len, line_last; char *qstr; LINE *eopline; REGION region; if(curbp->b_mode&MDVIEW){ /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ --- 522,536 ---- int f, n; /* deFault flag and Numeric argument */ { ! int i, j, k, l, c, qlen, cline[NSTRING] = {0} , word[NSTRING], ! same_word, finished = 0, long_line = 0, ! spaces, word_len, line_len, line_last, len_line = 0; char *qstr; LINE *eopline; REGION region; + int qslen, bline = 0, ftime = 1; + char pstr[NSTRING] = {'\0'}; /* proposed string */ + char pstr2[NSTRING] = {'\0'}; /* proposed string backup */ if(curbp->b_mode&MDVIEW){ /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ *************** *** 444,518 **** /* ...and leading white space */ for(i = qlen; (c = fremove(i)) == ' ' || c == TAB; i++){ linsert(1, line_last = c); line_len += ((c == TAB) ? (~line_len & 0x07) + 1 : 1); } /* then digest the rest... */ ! while((c = fremove(i++)) > 0){ ! switch(c){ ! case '\n' : ! i += qlen; /* skip next quote string */ ! case TAB : ! case ' ' : ! spaces++; ! same_word = 0; ! break; ! ! default : ! if(spaces){ /* flush word? */ ! if(line_len ! && line_len + word_len + qlen + 1 > fillcol ! && (line_len = fpnewline(qstr))) ! line_last = ' '; /* no word-flush space! */ ! ! if(word_len){ /* word to write? */ ! if(line_len && !isspace((unsigned char) line_last)){ ! linsert(1, ' '); /* need padding? */ ! line_len++; } ! line_len += word_len; ! for(j = 0; j < word_len; j++) ! linsert(1, line_last = word[j]); ! if(spaces > 1 && strchr(".?!:;\")", line_last)){ ! linsert(2, line_last = ' '); ! line_len += 2; ! } ! word_len = 0; ! } ! spaces = 0; ! } ! if(word_len + 1 >= NSTRING){ ! /* Magic! Fake that we output a wrapped word */ ! if(line_len && !same_word++) ! line_len = fpnewline(qstr); ! line_len += word_len; ! for(j = 0; j < word_len; j++) ! linsert(1, word[j]); ! word_len = 0; ! line_last = ' '; ! } ! word[word_len++] = c; ! break; ! } ! } ! if(word_len){ ! if(line_len + word_len + qlen + 1 > fillcol) ! (void) fpnewline(qstr); ! else if(line_len && !isspace((unsigned char) line_last)) ! linsert(1, ' '); ! for(j = 0; j < word_len; j++) ! linsert(1, word[j]); } /* Leave cursor on first char of first line after paragraph */ --- 586,810 ---- /* ...and leading white space */ for(i = qlen; (c = fremove(i)) == ' ' || c == TAB; i++){ linsert(1, line_last = c); + cline[i - qlen] = ' '; + spaces++; line_len += ((c == TAB) ? (~line_len & 0x07) + 1 : 1); } + for (j = 0; j < len_line; j++) + cline[j] = ' '; /* if there were TABS this makes sure there + are spaces */ /* then digest the rest... */ ! /* Here's the algorithm we'll use : ! * ! * 1. Get input until we find a \n character...think about this... ! * ! * 2. Get the quote string of that line and save it, if different ! * from the one we had before, create a new line with this quote ! * string. ! * ! * 3. Get the text to write from that line and save it. ! * ! * 4. Insert all possible words that fit in the line being written, ! * if something does not fit create a new line with the quote ! * string we have saved. ! * ! * 5. Repeat step 4, until no words are leftover, save the length of ! * this line. ! * ! * 6. Repeat step 1. ! * ! */ ! qslen = qlen; /* just in case */ ! while((!finished) && (c = fremove(i++))){ ! if (!bline){ /* step 1 */ ! finished = (c <= 0) ? 1 : 0; ! c = finished ? '\n' : c; /* fake a \n if finished */ ! if ((!isspace(c) || (isspace(c) && (!spaces))) && (c != '\n')) ! cline[len_line++] = c; /* copy at most one space */ ! if (c == '\n'){ ! cline[len_line] = 0; ! bline++; ! } ! if (len_line + 2 >= NSTRING) ! bline++; ! if (bline) long_line++; ! spaces = (isspace(c)) ? 1 : 0; ! } ! if (bline){ /* step 2 */ ! bline = 0; /* so that we can go back to step 1 */ ! if (c == '\n') ! i += qlen; /* skip quote string, never mind. */ ! if ((len_line) || ((!len_line) && (line_len > qlen))){ ! if (long_line == 1){ /* for long lines, only the first part gets ! tested for quote string */ ! if (c == '\n') ! long_line = 0; /* the line was "short" */ ! k = qstr ? is_quote(cline) : 0; /* find the quote */ ! if (k >= NSTRING - 3) k = 0; /* too long quote strings */ ! len_line -= k; ! if (k == 0 && qstr){ /* no quote string found, use given */ ! j = 0; ! while (qstr[j]){ ! pstr2[j] = qstr[j]; ! j++; } + pstr2[j] = '\0'; + qslen = j; + } + if (ftime){ /* when it's the first time */ + if (!qstr) /* do not insert blanc */ + line_last = ' '; + j = 0; + while (cline[j] == ' ') /* insert leading spaces */ + j++; + while(j < k) /* and the quote string */ + linsert(1, cline[j++]); + if (k) line_last = ' '; + line_len = len_line ? (k ? qlen + k : line_len) + : fillcol; + /* lines that are string quotes remain the same */ + } + if (k && qstr){ /* record the quote string found */ + j = l = 0; + while (qstr[l]){ + pstr2[l] = qstr[l]; + l++; + } + while ((l + j < NSTRING) && (j <= k)){ + pstr2[l + j] = (char) cline[j]; + j++; + } + pstr2[l + k] = '\0'; + } + if (pstr && pstr[0]){ /* if there's already a candidate */ + j = 0; + while ((pstr[j] == pstr2[j]) && /* compare them */ + (pstr[j] != '\0') && (pstr2[j] != '\0')) + j++; + if (pstr[j] != pstr2[j]){ /* if they are different */ + j = 0; + while ((j < NSTRING) && (pstr2[j] != '\0')){ + pstr[j] = pstr2[j]; /* save it */ + j++; + } + pstr[j] = '\0'; + qslen = j; + line_len = fillcol; + } + } + else{ /* if there's no quote string recognized */ + j = 0; + if (k){ /* if we found a quote string */ + while ((j < NSTRING) && (pstr2[j] != '\0')){ + pstr[j] = pstr2[j]; /* save it */ + j++; + } + pstr[j] = '\0'; + qslen = j; + } + else{ + j = 0; + if (qstr) + while (qstr[j]){ + pstr[j] = qstr[j]; + j++; + } + pstr[j] = '\0'; + qslen = j; + } + } + if (!len_line && !ftime){ + fpnewline(pstr); + line_last = ' '; + line_len = fillcol; + } + } + else{ + if ((!isspace(line_last)) && (!isspace(cline[0]))) + line_last = ' '; /* do not insert a space */ + len_line = k = 0; /* restart all over again */ + if (c == '\n') + long_line = 0; + } + ftime = 0; + while ((c = cline[k++]) > 0){ + switch(c){ + case TAB : + case ' ' : + spaces++; + same_word = 0; + break; ! default : ! if(spaces){ /* flush word? */ ! if(line_len ! && line_len + word_len + 1 > fillcol ! && (line_len = fpnewline(pstr))) ! line_last = ' '; /* no word-flush space! */ ! if(word_len){ /* word to write? */ ! if(line_len && !isspace((unsigned char) line_last)){ ! linsert(1, ' '); /* need padding? */ ! line_len++; ! } ! line_len += word_len; ! for(j = 0; j < word_len; j++) ! linsert(1, line_last = word[j]); ! if(spaces > 1 && strchr(".?!:;\")", line_last)){ ! linsert(2, line_last = ' '); ! line_len += 2; ! } ! word_len = 0; ! } ! spaces = 0; ! } /* if spaces */ ! if(word_len + 1 >= NSTRING){ ! /* Magic! Fake that we output a wrapped word */ ! if(line_len && !same_word++){ ! line_len = fpnewline(pstr); ! } ! line_len += word_len; ! for(j = 0; j < word_len; j++) ! linsert(1, line_last = word[j]); ! word_len = 0; ! line_last = ' '; ! } ! word[word_len++] = c; ! break; ! } /* switch c */ ! } ! if(word_len){ ! if(line_len + word_len + 1 > fillcol){ ! line_len = fpnewline(pstr); ! line_last = ' '; ! } ! else if(word_len && !isspace((unsigned char) line_last)){ ! linsert(1, line_last = ' '); ! line_len++; ! } ! ! line_len += word_len; ! for(j = 0; j < word_len; j++) ! linsert(1, line_last = word[j]); ! } ! word_len = 0; ! if (isspace(cline[NSTRING - 3])){ ! linsert(1, line_last = ' '); ! cline[NSTRING - 3] = 0; ! } ! } /* if (len_line) */ ! len_line = 0; ! } } /* Leave cursor on first char of first line after paragraph */