⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wordproc.c

📁 具有IDE功能的编辑器
💻 C
字号:
/* wordproc.c - word-processor mode for the editor: does dynamic		paragraph formatting.   Copyright (C) 1996-2000 Paul Sheer   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA   02111-1307, USA. */#include <config.h>#include "edit.h"#if defined (HAVE_MAD) && ! defined (MIDNIGHT) && ! defined (GTK)#include "mad.h"#endif#ifdef MIDNIGHT#define tab_width option_tab_spacing#endifint line_is_blank (WEdit * edit, long line);#define NO_FORMAT_CHARS_START "-+*\\,.;:&>"static long line_start (WEdit * edit, long line){    static long p = -1, l = 0;    int c;    if (p == -1 || abs (l - line) > abs (edit->curs_line - line)) {	l = edit->curs_line;	p = edit->curs1;    }    if (line < l)	p = edit_move_backward (edit, p, l - line);    else if (line > l)	p = edit_move_forward (edit, p, line - l, 0);    l = line;    p = edit_bol (edit, p);    while (strchr ("\t ", c = edit_get_byte (edit, p)))	p++;    return p;}static int bad_line_start (WEdit * edit, long p){    int c;    c = edit_get_byte (edit, p);    if (c == '.') {		/* `...' is acceptable */	if (edit_get_byte (edit, p + 1) == '.')	    if (edit_get_byte (edit, p + 2) == '.')		return 0;	return 1;    }    if (c == '-') {	if (edit_get_byte (edit, p + 1) == '-')	    if (edit_get_byte (edit, p + 2) == '-')		return 0;	/* `---' is acceptable */	return 1;    }    if (strchr (NO_FORMAT_CHARS_START, c))	return 1;    return 0;}static long begin_paragraph (WEdit * edit, long p, int force){    int i;    for (i = edit->curs_line - 1; i > 0; i--) {	if (line_is_blank (edit, i)) {	    i++;	    break;	}	if (force) {	    if (bad_line_start (edit, line_start (edit, i))) {		i++;		break;	    }	}    }    return edit_move_backward (edit, edit_bol (edit, edit->curs1), edit->curs_line - i);}static long end_paragraph (WEdit * edit, long p, int force){    int i;    for (i = edit->curs_line + 1; i < edit->total_lines; i++) {	if (line_is_blank (edit, i)) {	    i--;	    break;	}	if (force)	    if (bad_line_start (edit, line_start (edit, i))) {		i--;		break;	    }    }    return edit_eol (edit, edit_move_forward (edit, edit_bol (edit, edit->curs1), i - edit->curs_line, 0));}static unsigned char *get_paragraph (WEdit * edit, long p, long q, int indent, int *size){    unsigned char *s, *t;#if 0    t = malloc ((q - p) + 2 * (q - p) / option_word_wrap_line_length + 10);#else    t = malloc (2 * (q - p) + 1024);#endif    if (!t)	return 0;    for (s = t; p < q; p++, s++) {	if (indent)	    if (edit_get_byte (edit, p - 1) == '\n')		while (strchr ("\t ", edit_get_byte (edit, p)))		    p++;	*s = edit_get_byte (edit, p);    }    *size = (unsigned long) s - (unsigned long) t;    t[*size] = '\n';    return t;}static void strip_newlines (unsigned char *t, int size){    unsigned char *p = t;    while (size--) {	*p = *p == '\n' ? ' ' : *p;	p++;    }}#ifndef MIDNIGHTint edit_width_of_long_printable (int c);#endif/*    This is a copy of the function    int calc_text_pos (WEdit * edit, long b, long *q, int l)   in propfont.c  :(   It calculates the number of chars in a line specified to length l in pixels */extern int tab_width;static inline int next_tab_pos (int x){    return x += tab_width - x % tab_width;}static int line_pixel_length (unsigned char *t, long b, int l){    int x = 0, c, xn = 0;    for (;;) {	c = t[b];	switch (c) {	case '\n':	    return b;	case '\t':	    xn = next_tab_pos (x);	    break;	default:#ifdef MIDNIGHT	    xn = x + 1;#else	    xn = x + edit_width_of_long_printable (c);#endif	    break;	}	if (xn > l)	    break;	x = xn;	b++;    }    return b;}/* find the start of a word */static int next_word_start (unsigned char *t, int q, int size){    int i;    for (i = q;; i++) {	switch (t[i]) {	case '\n':	    return -1;	case '\t':	case ' ':	    for (;; i++) {		if (t[i] == '\n')		    return -1;		if (t[i] != ' ' && t[i] != '\t')		    return i;	    }	    break;	}    }}/* find the start of a word */static int word_start (unsigned char *t, int q, int size){    int i = q;    if (t[q] == ' ' || t[q] == '\t')	return next_word_start (t, q, size);    for (;;) {	int c;	if (!i)	    return -1;	c = t[i - 1];	if (c == '\n')	    return -1;	if (c == ' ' || c == '\t')	    return i;	i--;    }}/* replaces ' ' with '\n' to properly format a paragraph */static void format_this (unsigned char *t, int size, int indent){    int q = 0, ww;    strip_newlines (t, size);    ww = option_word_wrap_line_length * FONT_MEAN_WIDTH - indent;    if (ww < FONT_MEAN_WIDTH * 2)	ww = FONT_MEAN_WIDTH * 2;    for (;;) {	int p;	q = line_pixel_length (t, q, ww);	if (q > size)	    break;	if (t[q] == '\n')	    break;	p = word_start (t, q, size);	if (p == -1)	    q = next_word_start (t, q, size);	/* Return the end of the word if the beginning 						   of the word is at the beginning of a line 						   (i.e. a very long word) */	else	    q = p;	if (q == -1)	/* end of paragraph */	    break;	if (q)	    t[q - 1] = '\n';    }}static void replace_at (WEdit * edit, long q, int c){    edit_cursor_move (edit, q - edit->curs1);    edit_delete (edit);    edit_insert_ahead (edit, c);}void edit_insert_indent (WEdit * edit, int indent);/* replaces a block of text */static void put_paragraph (WEdit * edit, unsigned char *t, long p, long q, int indent, int size){    long cursor;    int i, c = 0;    cursor = edit->curs1;    if (indent)	while (strchr ("\t ", edit_get_byte (edit, p)))	    p++;    for (i = 0; i < size; i++, p++) {	if (i && indent) {	    if (t[i - 1] == '\n' && c == '\n') {		while (strchr ("\t ", edit_get_byte (edit, p)))		    p++;	    } else if (t[i - 1] == '\n') {		long curs;		edit_cursor_move (edit, p - edit->curs1);		curs = edit->curs1;		edit_insert_indent (edit, indent);		if (cursor >= curs)		    cursor += edit->curs1 - p;		p = edit->curs1;	    } else if (c == '\n') {		edit_cursor_move (edit, p - edit->curs1);		while (strchr ("\t ", edit_get_byte (edit, p))) {		    edit_delete (edit);		    if (cursor > edit->curs1)			cursor--;		}		p = edit->curs1;	    }	}	c = edit_get_byte (edit, p);	if (c != t[i])	    replace_at (edit, p, t[i]);    }    edit_cursor_move (edit, cursor - edit->curs1);	/* restore cursor position */}int edit_indent_width (WEdit * edit, long p);static int test_indent (WEdit * edit, long p, long q){    int indent;    indent = edit_indent_width (edit, p++);    if (!indent)	return 0;    for (; p < q; p++)	if (edit_get_byte (edit, p - 1) == '\n')	    if (indent != edit_indent_width (edit, p))		return 0;    return indent;}static void new_behaviour_message (WEdit * edit){    char *filename;    int fd;    filename = catstrs (home_dir, PARMESS_FILE, 0);    if ((fd = open (filename, O_RDONLY)) < 0) {	edit_message_dialog (_(" Format Paragraph "), "\This message will not be displayed again\n\\n\The new \"format paragraph\" command will format\n\text inside the selected region if one is highlighted.\n\Otherwise it would try to find the bounds of the\n\current paragraph using heuristics.");	fd = creat (filename, 0400);    }    close (fd);}void format_paragraph (WEdit * edit, int force){    long p, q;    int size;    unsigned char *t;    int indent = 0;    if (option_word_wrap_line_length < 2)	return;    if (force)	new_behaviour_message (edit);    if (force && !eval_marks (edit, &p, &q)) {	p = edit_bol (edit, p);	q = edit_eol (edit, q);    } else {	if (line_is_blank (edit, edit->curs_line))	    return;	p = begin_paragraph (edit, edit->curs1, force);	q = end_paragraph (edit, edit->curs1, force);    }    CPushFont ("editor", 0);    indent = test_indent (edit, p, q);    t = get_paragraph (edit, p, q, indent, &size);    if (!t)	return;    if (!force) {	int i;	if (strchr (NO_FORMAT_CHARS_START, *t)) {	    free (t);	    return;	}	for (i = 0; i < size - 1; i++) {	    if (t[i] == '\n') {		if (strchr (NO_FORMAT_CHARS_START "\t ", t[i + 1])) {		    free (t);		    return;		}	    }	}    }    format_this (t, q - p, indent);    put_paragraph (edit, t, p, q, indent, size);    free (t);    CPopFont ();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -