degesch: halfplement mIRC formatting
Now for the displaying part.
This commit is contained in:
		
							parent
							
								
									095a2cc16a
								
							
						
					
					
						commit
						6deb471423
					
				
							
								
								
									
										150
									
								
								degesch.c
									
									
									
									
									
								
							
							
						
						
									
										150
									
								
								degesch.c
									
									
									
									
									
								
							| @ -1465,7 +1465,13 @@ serialize_configuration (struct app_context *ctx, struct str *output) | |||||||
| 	config_item_write (ctx->config.root, true, output); | 	config_item_write (ctx->config.root, true, output); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // --- Attributed output -------------------------------------------------------
 | // --- Terminal output ---------------------------------------------------------
 | ||||||
|  | 
 | ||||||
|  | /// Default color pair
 | ||||||
|  | #define COLOR_DEFAULT -1 | ||||||
|  | 
 | ||||||
|  | /// Bright versions of the basic color set
 | ||||||
|  | #define COLOR_BRIGHT(x) (COLOR_ ## x + 8) | ||||||
| 
 | 
 | ||||||
| static struct | static struct | ||||||
| { | { | ||||||
| @ -1721,7 +1727,14 @@ enum formatter_item_type | |||||||
| 	FORMATTER_ITEM_TEXT,                ///< Text
 | 	FORMATTER_ITEM_TEXT,                ///< Text
 | ||||||
| 	FORMATTER_ITEM_ATTR,                ///< Formatting attributes
 | 	FORMATTER_ITEM_ATTR,                ///< Formatting attributes
 | ||||||
| 	FORMATTER_ITEM_FG_COLOR,            ///< Foreground color
 | 	FORMATTER_ITEM_FG_COLOR,            ///< Foreground color
 | ||||||
| 	FORMATTER_ITEM_BG_COLOR             ///< Background color
 | 	FORMATTER_ITEM_BG_COLOR,            ///< Background color
 | ||||||
|  | 
 | ||||||
|  | 	// These are internal, for mIRC formatting only so far:
 | ||||||
|  | 
 | ||||||
|  | 	FORMATTER_ITEM_BOLD,                ///< Bold
 | ||||||
|  | 	FORMATTER_ITEM_ITALIC,              ///< Italic
 | ||||||
|  | 	FORMATTER_ITEM_UNDERLINE,           ///< Underline
 | ||||||
|  | 	FORMATTER_ITEM_INVERSE              ///< Inverse
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct formatter_item | struct formatter_item | ||||||
| @ -1850,83 +1863,104 @@ enum | |||||||
| //   without the bold/blink attributes), 88 colors (the same plus a 4^3 RGB cube
 | //   without the bold/blink attributes), 88 colors (the same plus a 4^3 RGB cube
 | ||||||
| //   and a few shades of gray), or 256 colors (best)
 | //   and a few shades of gray), or 256 colors (best)
 | ||||||
| 
 | 
 | ||||||
| #define FORMATTER_NORMAL 0 | /// Builds a color pair for 256-color terminals with a 16-color backup value
 | ||||||
| #define FORMATTER_BRIGHT 1 << 8 | #define FORMATTER_COLOR(name, c256) \ | ||||||
|  | 	(COLOR_ ## name) & 0xFFFF | ((c256 << 16) & 0xFFFF) | ||||||
| 
 | 
 | ||||||
| #define FORMATTER_MAP(name, flags, c256) \ | static const int g_mirc_to_term[] = | ||||||
| 	COLOR_ ## name | FORMATTER_ ## flags | c256 << 16 |  | ||||||
| 
 |  | ||||||
| static const uint32_t g_mirc_to_term[] = |  | ||||||
| { | { | ||||||
| 	[MIRC_WHITE]    = FORMATTER_MAP (WHITE,   BRIGHT, 231), | 	[MIRC_WHITE]    = FORMATTER_COLOR (BRIGHT (WHITE),  231), | ||||||
| 	[MIRC_BLACK]    = FORMATTER_MAP (BLACK,   NORMAL,  16), | 	[MIRC_BLACK]    = FORMATTER_COLOR         (BLACK,    16), | ||||||
| 	[MIRC_BLUE]     = FORMATTER_MAP (BLUE,    NORMAL,  19), | 	[MIRC_BLUE]     = FORMATTER_COLOR         (BLUE,     19), | ||||||
| 	[MIRC_GREEN]    = FORMATTER_MAP (GREEN,   NORMAL,  34), | 	[MIRC_GREEN]    = FORMATTER_COLOR         (GREEN,    34), | ||||||
| 	[MIRC_L_RED]    = FORMATTER_MAP (RED,     BRIGHT, 196), | 	[MIRC_L_RED]    = FORMATTER_COLOR (BRIGHT (RED),    196), | ||||||
| 	[MIRC_RED]      = FORMATTER_MAP (RED,     NORMAL, 124), | 	[MIRC_RED]      = FORMATTER_COLOR         (RED,     124), | ||||||
| 	[MIRC_PURPLE]   = FORMATTER_MAP (MAGENTA, NORMAL, 127), | 	[MIRC_PURPLE]   = FORMATTER_COLOR         (MAGENTA, 127), | ||||||
| 	[MIRC_ORANGE]   = FORMATTER_MAP (YELLOW,  BRIGHT, 214), | 	[MIRC_ORANGE]   = FORMATTER_COLOR (BRIGHT (YELLOW), 214), | ||||||
| 	[MIRC_YELLOW]   = FORMATTER_MAP (YELLOW,  BRIGHT, 226), | 	[MIRC_YELLOW]   = FORMATTER_COLOR (BRIGHT (YELLOW), 226), | ||||||
| 	[MIRC_L_GREEN]  = FORMATTER_MAP (GREEN,   BRIGHT,  46), | 	[MIRC_L_GREEN]  = FORMATTER_COLOR (BRIGHT (GREEN),   46), | ||||||
| 	[MIRC_CYAN]     = FORMATTER_MAP (CYAN,    NORMAL,  37), | 	[MIRC_CYAN]     = FORMATTER_COLOR         (CYAN,     37), | ||||||
| 	[MIRC_L_CYAN]   = FORMATTER_MAP (CYAN,    BRIGHT,  51), | 	[MIRC_L_CYAN]   = FORMATTER_COLOR (BRIGHT (CYAN),    51), | ||||||
| 	[MIRC_L_BLUE]   = FORMATTER_MAP (BLUE,    BRIGHT,  21), | 	[MIRC_L_BLUE]   = FORMATTER_COLOR (BRIGHT (BLUE),    21), | ||||||
| 	[MIRC_L_PURPLE] = FORMATTER_MAP (MAGENTA, BRIGHT, 201), | 	[MIRC_L_PURPLE] = FORMATTER_COLOR (BRIGHT (MAGENTA),201), | ||||||
| 	[MIRC_GRAY]     = FORMATTER_MAP (BLACK,   BRIGHT, 244), | 	[MIRC_GRAY]     = FORMATTER_COLOR (BRIGHT (BLACK),  244), | ||||||
| 	[MIRC_L_GRAY]   = FORMATTER_MAP (WHITE,   NORMAL, 252), | 	[MIRC_L_GRAY]   = FORMATTER_COLOR         (WHITE,   252), | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | static void | ||||||
|  | formatter_add_simple (struct formatter *self, enum formatter_item_type type) | ||||||
|  | { | ||||||
|  | 	if (!self->ignore_new_attributes) | ||||||
|  | 		formatter_add_blank (self)->type = type; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const char * | ||||||
|  | formatter_parse_mirc_color (struct formatter *self, const char *s) | ||||||
|  | { | ||||||
|  | 	if (!isdigit_ascii (*s)) | ||||||
|  | 		return s; | ||||||
|  | 
 | ||||||
|  | 	int fg = *s++ - '0'; | ||||||
|  | 	if (isdigit_ascii (*s)) | ||||||
|  | 		fg = fg * 10 + (*s++ - '0'); | ||||||
|  | 	if (fg >= 0 && fg < 16) | ||||||
|  | 		formatter_add_fg_color (self, g_mirc_to_term[fg]); | ||||||
|  | 
 | ||||||
|  | 	if (*s != ',' || !isdigit_ascii (s[1])) | ||||||
|  | 		return s; | ||||||
|  | 
 | ||||||
|  | 	int bg = *++s - '0'; | ||||||
|  | 	if (isdigit_ascii (s[1])) | ||||||
|  | 		bg = bg * 10 + (*++s - '0'); | ||||||
|  | 	if (bg >= 0 && bg < 16) | ||||||
|  | 		formatter_add_bg_color (self, g_mirc_to_term[bg]); | ||||||
|  | 
 | ||||||
|  | 	return s; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void | static void | ||||||
| formatter_parse_mirc (struct formatter *self, const char *s) | formatter_parse_mirc (struct formatter *self, const char *s) | ||||||
| { | { | ||||||
| 	struct str buffer; | 	struct str buf; | ||||||
| 	str_init (&buffer); | 	str_init (&buf); | ||||||
| 
 |  | ||||||
| #define FLUSH if (buffer.len) \ |  | ||||||
| 	{ formatter_add_text (self, buffer.str); str_reset (&buffer); } |  | ||||||
| 
 | 
 | ||||||
| 	formatter_add_reset (self); | 	formatter_add_reset (self); | ||||||
| 
 | 
 | ||||||
| 	char c; | 	char c; | ||||||
| 	while ((c = *s++)) | 	while ((c = *s++)) | ||||||
| 	{ | 	{ | ||||||
|  | 		if (buf.len && c < 0x20) | ||||||
|  | 		{ | ||||||
|  | 			formatter_add_text (self, buf.str); | ||||||
|  | 			str_reset (&buf); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | #define SIMPLE(type) formatter_add_simple (self, FORMATTER_ITEM_ ## type) | ||||||
|  | 
 | ||||||
| 		switch (c) | 		switch (c) | ||||||
| 		{ | 		{ | ||||||
| 		case '\x02': | 		case '\x02': SIMPLE (BOLD);      break; | ||||||
| 			FLUSH | 		case '\x1d': SIMPLE (ITALIC);    break; | ||||||
| 			// TODO: bold
 | 		case '\x1f': SIMPLE (UNDERLINE); break; | ||||||
| 			break; | 		case '\x16': SIMPLE (INVERSE);   break; | ||||||
|  | 
 | ||||||
|  | #undef SIMPLE | ||||||
|  | 
 | ||||||
| 		case '\x03': | 		case '\x03': | ||||||
| 			FLUSH | 			s = formatter_parse_mirc_color (self, s); | ||||||
| 			// TODO: color
 |  | ||||||
| 			// TODO: parse \d(\d(,\d(\d)?)?)?
 |  | ||||||
| 			break; |  | ||||||
| 		case '\x1d': |  | ||||||
| 			FLUSH |  | ||||||
| 			// TODO: italic
 |  | ||||||
| 			break; |  | ||||||
| 		case '\x1f': |  | ||||||
| 			FLUSH |  | ||||||
| 			// TODO: underline
 |  | ||||||
| 			break; |  | ||||||
| 		case '\x16': |  | ||||||
| 			FLUSH |  | ||||||
| 			// TODO: swap background/foreground
 |  | ||||||
| 			break; | 			break; | ||||||
| 		case '\x0f': | 		case '\x0f': | ||||||
| 			FLUSH |  | ||||||
| 			formatter_add_reset (self); | 			formatter_add_reset (self); | ||||||
| 			break; | 			break; | ||||||
| 		default: | 		default: | ||||||
| 			str_append_c (&buffer, c); | 			str_append_c (&buf, c); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	FLUSH | 	if (buf.len) | ||||||
| 	str_free (&buffer); | 		formatter_add_text (self, buf.str); | ||||||
| 
 |  | ||||||
| #undef FLUSH |  | ||||||
| 
 | 
 | ||||||
|  | 	str_free (&buf); | ||||||
| 	formatter_add_reset (self); | 	formatter_add_reset (self); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -1953,10 +1987,6 @@ restart: | |||||||
| 			str_append_c (buf, ' '); | 			str_append_c (buf, ' '); | ||||||
| 		str_append (buf, s); | 		str_append (buf, s); | ||||||
| 		break; | 		break; | ||||||
| 	case 'm': |  | ||||||
| 		s = va_arg (*ap, char *); |  | ||||||
| 		formatter_parse_mirc (self, s); |  | ||||||
| 		break; |  | ||||||
| 	case 'd': | 	case 'd': | ||||||
| 		s = xstrdup_printf ("%d", va_arg (*ap, int)); | 		s = xstrdup_printf ("%d", va_arg (*ap, int)); | ||||||
| 		for (size_t len = strlen (s); len < width; len++) | 		for (size_t len = strlen (s); len < width; len++) | ||||||
| @ -1965,6 +1995,10 @@ restart: | |||||||
| 		free (s); | 		free (s); | ||||||
| 		break; | 		break; | ||||||
| 
 | 
 | ||||||
|  | 	case 'm': | ||||||
|  | 		formatter_parse_mirc   (self, va_arg (*ap, char *)); | ||||||
|  | 		break; | ||||||
|  | 
 | ||||||
| 	case 'a': | 	case 'a': | ||||||
| 		formatter_add_attr     (self, va_arg (*ap, int)); | 		formatter_add_attr     (self, va_arg (*ap, int)); | ||||||
| 		break; | 		break; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user