예제 #1
0
/* Formats every line of the current text */
static void txt_format_text(SpaceText *st) 
{
	TextLine *linep;

	if (!st->text) return;

	for (linep = st->text->lines.first; linep; linep = linep->next)
		txt_format_line(st, linep, 0);
}
예제 #2
0
static void txt_format_line(SpaceText *st, TextLine *line, int do_next)
{
	FlattenString fs;
	char *str, *fmt, orig, cont, find, prev = ' ';
	int len, i;

	/* Get continuation from previous line */
	if(line->prev && line->prev->format != NULL) {
		fmt= line->prev->format;
		cont = fmt[strlen(fmt)+1]; /* Just after the null-terminator */
	}
	else cont = 0;

	/* Get original continuation from this line */
	if(line->format != NULL) {
		fmt= line->format;
		orig = fmt[strlen(fmt)+1]; /* Just after the null-terminator */
	}
	else orig = 0xFF;

	flatten_string(st, &fs, line->line);
	str = fs.buf;
	len = strlen(str);
	if(!text_check_format_len(line, len)) {
		flatten_string_free(&fs);
		return;
	}
	fmt = line->format;

	while(*str) {
		/* Handle escape sequences by skipping both \ and next char */
		if(*str == '\\') {
			*fmt = prev; fmt++; str++;
			if(*str == '\0') break;
			*fmt = prev; fmt++; str++;
			continue;
		}
		/* Handle continuations */
		else if(cont) {
			/* Triple strings ("""...""" or '''...''') */
			if(cont & TXT_TRISTR) {
				find = (cont & TXT_DBLQUOTSTR) ? '"' : '\'';
				if(*str==find && *(str+1)==find && *(str+2)==find) {
					*fmt = 'l'; fmt++; str++;
					*fmt = 'l'; fmt++; str++;
					cont = 0;
				}
			/* Handle other strings */
			}
			else {
				find = (cont & TXT_DBLQUOTSTR) ? '"' : '\'';
				if(*str == find) cont = 0;
			}

			*fmt = 'l';
		}
		/* Not in a string... */
		else {
			/* Deal with comments first */
			if(prev == '#' || *str == '#')
				*fmt = '#';
			/* Strings */
			else if(*str == '"' || *str == '\'') {
				find = *str;
				cont = (*str== '"') ? TXT_DBLQUOTSTR : TXT_SNGQUOTSTR;
				if(*(str+1) == find && *(str+2) == find) {
					*fmt = 'l'; fmt++; str++;
					*fmt = 'l'; fmt++; str++;
					cont |= TXT_TRISTR;
				}
				*fmt = 'l';
			}
			/* Whitespace (all ws. has been converted to spaces) */
			else if(*str == ' ')
				*fmt = '_';
			/* Numbers (digits not part of an identifier and periods followed by digits) */
			else if((prev != 'q' && text_check_digit(*str)) || (*str == '.' && text_check_digit(*(str+1))))
				*fmt = 'n';
			/* Booleans */
			else if(prev != 'q' && (i=find_bool(str)) != -1)
				if(i>0) {
					while(i>1) {
						*fmt = 'n'; fmt++; str++;
						i--;
					}
					*fmt = 'n';
				}
				else
					*fmt = 'q';
			/* Punctuation */
			else if(text_check_delim(*str))
				*fmt = '!';
			/* Identifiers and other text (no previous ws. or delims. so text continues) */
			else if(prev == 'q')
				*fmt = 'q';
			/* Not ws, a digit, punct, or continuing text. Must be new, check for special words */
			else {
				/* Special vars(v) or built-in keywords(b) */
				if((i=find_specialvar(str)) != -1)
					prev = 'v';
				else if((i=find_builtinfunc(str)) != -1)
					prev = 'b';
				else if((i=find_decorator(str)) != -1)
					prev = 'v'; /* could have a new color for this */
				if(i>0) {
					while(i>1) {
						*fmt = prev; fmt++; str++;
						i--;
					}
					*fmt = prev;
				}
				else
					*fmt = 'q';
			}
		}
		prev = *fmt;
		fmt++;
		str++;
	}

	/* Terminate and add continuation char */
	*fmt = '\0'; fmt++;
	*fmt = cont;

	/* Debugging */
	//print_format(st, line);

	/* If continuation has changed and we're allowed, process the next line */
	if(cont!=orig && do_next && line->next) {
		txt_format_line(st, line->next, do_next);
	}

	flatten_string_free(&fs);
}
예제 #3
0
void draw_text_main(SpaceText *st, ARegion *ar)
{
	Text *text= st->text;
	TextLine *tmp;
	rcti scroll, back;
	char linenr[12];
	int i, x, y, winx, linecount= 0, lineno= 0;
	int wraplinecount= 0, wrap_skip= 0;

	/* if no text, nothing to do */
	if(!text)
		return;
	
	text_update_drawcache(st, ar);

	/* make sure all the positional pointers exist */
	if(!text->curl || !text->sell || !text->lines.first || !text->lines.last)
		txt_clean_text(text);
	
	if(st->lheight) st->viewlines= (int)ar->winy/st->lheight;
	else st->viewlines= 0;
	
	/* update rects for scroll */
	calc_text_rcts(st, ar, &scroll, &back);	/* scroll will hold the entire bar size */

	/* update syntax formatting if needed */
	tmp= text->lines.first;
	lineno= 0;
	for(i= 0; i<st->top && tmp; i++) {
		if(st->showsyntax && !tmp->format)
			txt_format_line(st, tmp, 0);

		if(st->wordwrap) {
			int lines= text_get_visible_lines_no(st, lineno);

			if (wraplinecount+lines>st->top) {
				wrap_skip= st->top-wraplinecount;
				break;
			} else {
				wraplinecount+= lines;
				tmp= tmp->next;
				linecount++;
			}
		} else {
			tmp= tmp->next;
			linecount++;
		}

		lineno++;
	}

	text_font_begin(st);
	st->cwidth= BLF_fixed_width(mono);
	st->cwidth= MAX2(st->cwidth, 1);

	/* draw line numbers background */
	if(st->showlinenrs) {
		x= TXT_OFFSET + TEXTXLOC;

		UI_ThemeColor(TH_GRID);
		glRecti((TXT_OFFSET-12), 0, (TXT_OFFSET-5) + TEXTXLOC, ar->winy - 2);
	}
	else {
		st->linenrs_tot= 0; /* not used */
		x= TXT_OFFSET;
	}
	y= ar->winy-st->lheight;
	winx= ar->winx - TXT_SCROLL_WIDTH;
	
	/* draw cursor */
	draw_cursor(st, ar);

	/* draw the text */
	UI_ThemeColor(TH_TEXT);

	for(i=0; y>0 && i<st->viewlines && tmp; i++, tmp= tmp->next) {
		if(st->showsyntax && !tmp->format)
			txt_format_line(st, tmp, 0);

		if(st->showlinenrs && !wrap_skip) {
			/* draw line number */
			if(tmp == text->curl)
				UI_ThemeColor(TH_HILITE);
			else
				UI_ThemeColor(TH_TEXT);

			sprintf(linenr, "%d", i + linecount + 1);
			/* itoa(i + linecount + 1, linenr, 10); */ /* not ansi-c :/ */
			text_font_draw(st, TXT_OFFSET - 7, y, linenr);

			UI_ThemeColor(TH_TEXT);
		}

		if(st->wordwrap) {
			/* draw word wrapped text */
			int lines = text_draw_wrapped(st, tmp->line, x, y, winx-x, tmp->format, wrap_skip);
			y -= lines*st->lheight;
		}
		else {
			/* draw unwrapped text */
			text_draw(st, tmp->line, st->left, ar->winx/st->cwidth, 1, x, y, tmp->format);
			y -= st->lheight;
		}

		wrap_skip= 0;
	}
	
	/* draw other stuff */
	draw_brackets(st, ar);
	draw_markers(st, ar);
	glTranslatef(0.375f, 0.375f, 0.0f); /* XXX scroll requires exact pixel space */
	draw_textscroll(st, &scroll, &back);
	draw_documentation(st, ar);
	draw_suggestion_list(st, ar);
	
	text_font_end(st);
}