📄 wordwrap.c
字号:
int tab_size;long old_rline;int old_cline;int words, cols; if (window->ll->len == EOF) return( ERROR ); if (un_copy_line( window->ll, window, TRUE, TRUE ) == ERROR) return( ERROR ); tabs = window->file_info->inflate_tabs; tab_size = window->file_info->ptab_size; if (!is_line_blank( window->ll->line, window->ll->len, tabs )) { old_ww = mode.word_wrap; if (old_ww == NO_WRAP) mode.word_wrap = FIXED_WRAP; dup_window_info( &w, window ); g_status.screen_display = FALSE; old_rline = window->rline; old_cline = window->cline; /* * find the beginning of the paragraph. */ p = w.ll->prev; if (g_status.command == FormatParagraph) { while (p->prev != NULL && !is_line_blank( p->line, p->len, tabs )) { dec_line( &w, FALSE ); p = p->prev; } pm = mode.parg_margin; /* * if format text, don't find the beginning of the paragraph. * but we need to know if this is the first line in a paragraph. */ } else if (g_status.command == FormatText) { if (p->prev == NULL || is_line_blank( p->line, p->len, tabs )) pm = mode.parg_margin; else pm = mode.left_margin; } else pm = mode.left_margin; g_status.command = WordWrap; /* * determine the current position relative to the beginning of * the format, to be able to restore the correct position. */ dup_window_info( &u, &w ); u.rcol = first_non_blank( u.ll->line, u.ll->len, tabs, tab_size ); words = cols = 0; eop = FALSE; while (u.rline < old_rline || (u.rline == old_rline && u.rcol < window->rcol)) { if (word_right( &u ) == ERROR) { eop = TRUE; break; } ++words; } if (u.rline != old_rline || u.rcol != window->rcol) { if (!eop) { word_left( &u ); --words; } cols = window->rcol - u.rcol; } dup_window_info( &u, &w ); p = w.ll; if (mode.word_wrap == FIXED_WRAP) lm = mode.left_margin; else lm = pm = find_left_margin( p, mode.word_wrap, tabs, tab_size ); rm = mode.right_margin; eop = FALSE; /* * do the paragraph */ for (first_line=TRUE; p != NULL && !is_line_blank( p->line, p->len, tabs ) && eop == FALSE && !g_status.control_break;) { /* * find out what margin to use */ if (first_line) { margin = pm; first_line = FALSE; } else margin = lm; /* * line up the margin */ w.ll->type |= DIRTY; copy_line( w.ll, &w, TRUE ); remove_spaces( 0 ); rcol = find_word( g_status.line_buff, g_status.line_buff_len, 0 ); if (rcol != ERROR && rcol != margin) { /* * must add spaces to get the indentation right */ if (rcol < margin) { source = g_status.line_buff; spaces = margin - rcol; dest = source + spaces; assert( g_status.line_buff_len >= 0 ); assert( g_status.line_buff_len < MAX_LINE_LENGTH ); memmove( dest, source, g_status.line_buff_len ); g_status.line_buff_len += spaces; while (spaces--) *source++ = ' '; } else { w.rcol = margin; word_delete( &w ); un_copy_line( p, &w, TRUE, TRUE ); copy_line( w.ll, &w, TRUE ); remove_spaces( margin ); } } /* * now make sure rest of line is formatted */ source = g_status.line_buff; len = g_status.line_buff_len; for (; len < rm+1 && eop == FALSE;) { pp = p->next; if (is_line_blank( pp->line, pp->len, tabs )) eop = TRUE; else { w.ll = p; w.rcol = len + 1; if (*(p->line+len-1) == '.') ++w.rcol; if (w.rcol + pp->len >= MAX_LINE_LENGTH) { /* * the line below is too long to join with current line. */ eop = TRUE; error( WARNING, window->bottom_line, ww2 ); } else { word_delete( &w ); un_copy_line( p, &w, TRUE, TRUE ); copy_line( p, &w, TRUE ); remove_spaces( margin ); len = g_status.line_buff_len; } } } if (len <= rm+1) { un_copy_line( p, &w, TRUE, TRUE ); p = p->next; if (is_line_blank( p->line, p->len, tabs )) eop = TRUE; else inc_line( &w, TRUE ); } else { w.rcol = rm; g_status.key_pressed = *(w.ll->line + rm); rline = w.rline; word_wrap( &w ); if (rline == w.rline) inc_line( &w, TRUE ); } g_status.copied = FALSE; p = w.ll; } mode.word_wrap = old_ww; g_status.copied = FALSE; w.file_info->dirty = GLOBAL; /* * restore the current position. */ u.rcol = first_non_blank( u.ll->line, u.ll->len, tabs, tab_size ); for (; words > 0; words--) word_right( &u ); u.rcol += cols; g_status.screen_display = TRUE; if (window->rline != old_rline ) { move_to_line( window, old_rline, FALSE ); window->cline = old_cline; } move_display( window, &u ); } return( OK );}/* * Name: combine_wrap_spill * Purpose: combine word wrap lines so we don't push each word onto a * separate line. * Date: November 27, 1991 * Passed: window: pointer to current window * wrap_col: col to combine next line * lm: left margin * rm: right margin * side: left or right margin to insert spaces * new_line: boolean, should we insert a new line? */void combine_wrap_spill( TDE_WIN *window, int wrap_col, int lm, int rm, int side, int new_line ){line_list_ptr p; /* line we wrapped */line_list_ptr pp; /* pointer to next line after wrapped line */int p_len; /* length of line we just word wrapped */int non_blank; /* first non-blank column on next line */int control_t; /* number of times to call word_delete */int next_line_len; /* length of next line counting from 1st word */TDE_WIN w; /* scratch window */int tabs;int tab_size; dup_window_info( &w, window ); g_status.command = WordWrap; w.rcol = wrap_col; tabs = window->file_info->inflate_tabs; tab_size = window->file_info->ptab_size; if (new_line) { insert_newline( &w ); if (mode.right_justify == TRUE) justify_right_margin( &w, w.ll->prev, mode.word_wrap == FIXED_WRAP ? find_left_margin( w.ll->prev, mode.word_wrap, tabs, tab_size ) : lm, rm, side ); p = window->ll->next; } else p = window->ll; if (p != NULL) { p_len = find_end( p->line, p->len, tabs, tab_size ); pp = p->next; if (pp != NULL) { non_blank = first_non_blank( pp->line, pp->len, tabs, tab_size ); next_line_len = find_end( pp->line, pp->len, tabs, tab_size ) - non_blank; if (!is_line_blank( pp->line, pp->len, tabs ) && p_len+next_line_len <= rm) { control_t = 1; if (w.file_info->inflate_tabs) { if (*pp->line == ' ' || *pp->line == '\t') ++control_t; } else if (*pp->line == ' ') ++control_t; w.ll = p; w.rcol = p_len + 1; if (*(p->line+p_len-1) == '.') ++w.rcol; while (control_t--) word_delete( &w ); remove_spaces( lm ); un_copy_line( w.ll, &w, TRUE, FALSE ); } window->file_info->dirty = GLOBAL; } }}/* * Name: justify_right_margin * Purpose: distribute blanks in line to justify right margin * Date: December 30, 1992 * Passed: window: pointer to current window * ll: current node pointing to current line * lm: left margin * rm: right margin * side: which side to start inserting space? LEFT or RIGHT * Notes: this routine is based on the spread function by * Kernighan and Plauger in _Software Tools_, Addison-Wesly, * Reading, Mass., 1976, ISBN 0-201-03669-X, pp 240-241. * * jmh 990501: test for tabs. * jmh 010621: fixed a bug with the word count. */void justify_right_margin( TDE_WIN *window, line_list_ptr ll, int lm, int rm, int side ){int len;int i;int word_count;int holes;int nb;int spaces;text_ptr s;int tabs;int tab_size; tabs = window->file_info->inflate_tabs; tab_size = window->file_info->ptab_size; /* * make sure line is longer than the left margin and less than the right. */ len = find_end( ll->line, ll->len, tabs, tab_size ); if (len <= lm || len >= rm+1) return; /* * now, count the number of words in line. */ i = tabs ? entab_adjust_rcol( ll->line, ll->len, lm, tab_size ) : lm; s = ll->line + i; len -= i; word_count = 0; while (len > 0) { while (len > 0 && (*s == ' ' || (*s == '\t' && tabs))) s++, len--; if (len == 0) break; ++word_count; while (len > 0 && *s != ' ' && (*s != '\t' || !tabs)) s++, len--; } /* * can't justify right margin with one word or less. */ if (word_count <= 1) return; holes = word_count - 1; copy_line( ll, window, TRUE ); remove_spaces( lm ); /* * find out how many spaces we need. if spaces <= 0, then get out. */ i = g_status.line_buff_len - 1; spaces = rm - i; if (spaces <= 0) return; g_status.line_buff_len += spaces; /* * this while loop is based on the while loop on page 241 in * _Software Tools_, Kernighan and Plauger. I added a while loop * to skip extra blanks after a period or other space intentionally * inserted into the text. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -