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);
|
||||
}
|
||||
|
||||
// --- 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
|
||||
{
|
||||
@ -1721,7 +1727,14 @@ enum formatter_item_type
|
||||
FORMATTER_ITEM_TEXT, ///< Text
|
||||
FORMATTER_ITEM_ATTR, ///< Formatting attributes
|
||||
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
|
||||
@ -1850,83 +1863,104 @@ enum
|
||||
// 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)
|
||||
|
||||
#define FORMATTER_NORMAL 0
|
||||
#define FORMATTER_BRIGHT 1 << 8
|
||||
/// Builds a color pair for 256-color terminals with a 16-color backup value
|
||||
#define FORMATTER_COLOR(name, c256) \
|
||||
(COLOR_ ## name) & 0xFFFF | ((c256 << 16) & 0xFFFF)
|
||||
|
||||
#define FORMATTER_MAP(name, flags, c256) \
|
||||
COLOR_ ## name | FORMATTER_ ## flags | c256 << 16
|
||||
|
||||
static const uint32_t g_mirc_to_term[] =
|
||||
static const int g_mirc_to_term[] =
|
||||
{
|
||||
[MIRC_WHITE] = FORMATTER_MAP (WHITE, BRIGHT, 231),
|
||||
[MIRC_BLACK] = FORMATTER_MAP (BLACK, NORMAL, 16),
|
||||
[MIRC_BLUE] = FORMATTER_MAP (BLUE, NORMAL, 19),
|
||||
[MIRC_GREEN] = FORMATTER_MAP (GREEN, NORMAL, 34),
|
||||
[MIRC_L_RED] = FORMATTER_MAP (RED, BRIGHT, 196),
|
||||
[MIRC_RED] = FORMATTER_MAP (RED, NORMAL, 124),
|
||||
[MIRC_PURPLE] = FORMATTER_MAP (MAGENTA, NORMAL, 127),
|
||||
[MIRC_ORANGE] = FORMATTER_MAP (YELLOW, BRIGHT, 214),
|
||||
[MIRC_YELLOW] = FORMATTER_MAP (YELLOW, BRIGHT, 226),
|
||||
[MIRC_L_GREEN] = FORMATTER_MAP (GREEN, BRIGHT, 46),
|
||||
[MIRC_CYAN] = FORMATTER_MAP (CYAN, NORMAL, 37),
|
||||
[MIRC_L_CYAN] = FORMATTER_MAP (CYAN, BRIGHT, 51),
|
||||
[MIRC_L_BLUE] = FORMATTER_MAP (BLUE, BRIGHT, 21),
|
||||
[MIRC_L_PURPLE] = FORMATTER_MAP (MAGENTA, BRIGHT, 201),
|
||||
[MIRC_GRAY] = FORMATTER_MAP (BLACK, BRIGHT, 244),
|
||||
[MIRC_L_GRAY] = FORMATTER_MAP (WHITE, NORMAL, 252),
|
||||
[MIRC_WHITE] = FORMATTER_COLOR (BRIGHT (WHITE), 231),
|
||||
[MIRC_BLACK] = FORMATTER_COLOR (BLACK, 16),
|
||||
[MIRC_BLUE] = FORMATTER_COLOR (BLUE, 19),
|
||||
[MIRC_GREEN] = FORMATTER_COLOR (GREEN, 34),
|
||||
[MIRC_L_RED] = FORMATTER_COLOR (BRIGHT (RED), 196),
|
||||
[MIRC_RED] = FORMATTER_COLOR (RED, 124),
|
||||
[MIRC_PURPLE] = FORMATTER_COLOR (MAGENTA, 127),
|
||||
[MIRC_ORANGE] = FORMATTER_COLOR (BRIGHT (YELLOW), 214),
|
||||
[MIRC_YELLOW] = FORMATTER_COLOR (BRIGHT (YELLOW), 226),
|
||||
[MIRC_L_GREEN] = FORMATTER_COLOR (BRIGHT (GREEN), 46),
|
||||
[MIRC_CYAN] = FORMATTER_COLOR (CYAN, 37),
|
||||
[MIRC_L_CYAN] = FORMATTER_COLOR (BRIGHT (CYAN), 51),
|
||||
[MIRC_L_BLUE] = FORMATTER_COLOR (BRIGHT (BLUE), 21),
|
||||
[MIRC_L_PURPLE] = FORMATTER_COLOR (BRIGHT (MAGENTA),201),
|
||||
[MIRC_GRAY] = FORMATTER_COLOR (BRIGHT (BLACK), 244),
|
||||
[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
|
||||
formatter_parse_mirc (struct formatter *self, const char *s)
|
||||
{
|
||||
struct str buffer;
|
||||
str_init (&buffer);
|
||||
|
||||
#define FLUSH if (buffer.len) \
|
||||
{ formatter_add_text (self, buffer.str); str_reset (&buffer); }
|
||||
struct str buf;
|
||||
str_init (&buf);
|
||||
|
||||
formatter_add_reset (self);
|
||||
|
||||
char c;
|
||||
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)
|
||||
{
|
||||
case '\x02':
|
||||
FLUSH
|
||||
// TODO: bold
|
||||
break;
|
||||
case '\x02': SIMPLE (BOLD); break;
|
||||
case '\x1d': SIMPLE (ITALIC); break;
|
||||
case '\x1f': SIMPLE (UNDERLINE); break;
|
||||
case '\x16': SIMPLE (INVERSE); break;
|
||||
|
||||
#undef SIMPLE
|
||||
|
||||
case '\x03':
|
||||
FLUSH
|
||||
// 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
|
||||
s = formatter_parse_mirc_color (self, s);
|
||||
break;
|
||||
case '\x0f':
|
||||
FLUSH
|
||||
formatter_add_reset (self);
|
||||
break;
|
||||
default:
|
||||
str_append_c (&buffer, c);
|
||||
str_append_c (&buf, c);
|
||||
}
|
||||
}
|
||||
|
||||
FLUSH
|
||||
str_free (&buffer);
|
||||
|
||||
#undef FLUSH
|
||||
if (buf.len)
|
||||
formatter_add_text (self, buf.str);
|
||||
|
||||
str_free (&buf);
|
||||
formatter_add_reset (self);
|
||||
}
|
||||
|
||||
@ -1953,10 +1987,6 @@ restart:
|
||||
str_append_c (buf, ' ');
|
||||
str_append (buf, s);
|
||||
break;
|
||||
case 'm':
|
||||
s = va_arg (*ap, char *);
|
||||
formatter_parse_mirc (self, s);
|
||||
break;
|
||||
case 'd':
|
||||
s = xstrdup_printf ("%d", va_arg (*ap, int));
|
||||
for (size_t len = strlen (s); len < width; len++)
|
||||
@ -1965,6 +1995,10 @@ restart:
|
||||
free (s);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
formatter_parse_mirc (self, va_arg (*ap, char *));
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
formatter_add_attr (self, va_arg (*ap, int));
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user