1
0
mirror of https://github.com/weechat/weechat.git synced 2026-06-28 05:46:38 +02:00

irc: add modifier "irc_color_decode_ansi"

This commit is contained in:
Sebastien Helleu
2014-03-15 11:12:49 +01:00
parent e38f437ad7
commit d3c85c920c
7 changed files with 419 additions and 2 deletions
+6
View File
@@ -9139,6 +9139,12 @@ List of modifiers used by WeeChat and plugins:
Any string |
String with IRC colors (or IRC colors removed)
| irc_color_decode_ansi +
_(WeeChat ≥ 0.4.4)_ |
"1" to keep colors, "0" to remove colors |
Any string |
String with ANSI colors converted to IRC colors (or ANSI colors removed)
| irc_command_auth +
_(WeeChat ≥ 0.4.1)_ |
Server name |
+7
View File
@@ -9308,6 +9308,13 @@ Liste des modificateurs utilisés par WeeChat et les extensions :
Toute chaîne |
Chaîne avec les couleurs IRC (ou avec les couleurs IRC supprimées)
| irc_color_decode_ansi +
_(WeeChat ≥ 0.4.4)_ |
"1" pour garder les couleurs, "0" pour les supprimer |
Toute chaîne |
Chaîne avec les couleurs ANSI converties en couleurs IRC (ou avec les couleurs
ANSI supprimées)
| irc_command_auth +
_(WeeChat ≥ 0.4.1)_ |
Nom du serveur |
+7
View File
@@ -9368,6 +9368,13 @@ List of modifiers used by WeeChat and plugins:
Qualsiasi stringa |
String with IRC colors (or IRC colors removed)
// TRANSLATION MISSING
| irc_color_decode_ansi +
_(WeeChat ≥ 0.4.4)_ |
"1" per mantenere i colori, "0" per rimuovere i colori |
Qualsiasi stringa |
String with ANSI colors converted to IRC colors (or ANSI colors removed)
// TRANSLATION MISSING
| irc_command_auth +
_(WeeChat ≥ 0.4.1)_ |
+7
View File
@@ -9160,6 +9160,13 @@ WeeChat とプラグインが使う修飾子のリスト:
任意の文字列 |
String with IRC colors (or IRC colors removed)
// TRANSLATION MISSING
| irc_color_decode_ansi +
_(WeeChat バージョン 0.4.4 以上で利用可)_ |
色を保持する場合は "1"、削除する場合は "0" |
任意の文字列 |
String with ANSI colors converted to IRC colors (or ANSI colors removed)
| irc_command_auth +
_(WeeChat バージョン 0.4.1 以上で利用可)_ |
サーバ名 |
+378 -2
View File
@@ -23,6 +23,7 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <regex.h>
#include "../weechat-plugin.h"
#include "irc.h"
@@ -45,9 +46,29 @@ char *irc_color_to_weechat[IRC_NUM_COLORS] =
/* 11 */ "lightcyan",
/* 12 */ "lightblue",
/* 13 */ "lightmagenta",
/* 14 */ "gray",
/* 15 */ "white"
/* 14 */ "darkgray",
/* 15 */ "gray"
};
char irc_color_term2irc[IRC_COLOR_TERM2IRC_NUM_COLORS] =
{ /* term > IRC */
1, /* 0 1 (black) */
5, /* 1 5 (red) */
3, /* 2 3 (green) */
7, /* 3 7 (brown) */
2, /* 4 2 (blue) */
6, /* 5 6 (magenta) */
10, /* 6 10 (cyan) */
15, /* 7 15 (gray) */
14, /* 8 14 (darkgray) */
4, /* 9 4 (lightred) */
9, /* 10 9 (lightgreen) */
8, /* 11 8 (yellow) */
12, /* 12 12 (lightblue) */
13, /* 13 13 (lightmagenta) */
11, /* 14 11 (lightcyan) */
0, /* 15 0 (white) */
};
regex_t *irc_color_regex_ansi = NULL;
/*
@@ -361,6 +382,343 @@ irc_color_encode (const char *string, int keep_colors)
return (char *)out;
}
/*
* Converts a RGB color to IRC color.
*
* Returns a IRC color number (between 0 and 15), -1 if error.
*/
int
irc_color_convert_rgb2irc (int rgb)
{
char str_color[64], *error;
const char *info_color;
long number;
snprintf (str_color, sizeof (str_color),
"%d,%d",
rgb,
IRC_COLOR_TERM2IRC_NUM_COLORS);
info_color = weechat_info_get ("color_rgb2term", str_color);
if (!info_color || !info_color[0])
return -1;
error = NULL;
number = strtol (info_color, &error, 10);
if (!error || error[0]
|| (number < 0) || (number >= IRC_COLOR_TERM2IRC_NUM_COLORS))
{
return -1;
}
return irc_color_term2irc[number];
}
/*
* Converts a terminal color to IRC color.
*
* Returns a IRC color number (between 0 and 15), -1 if error.
*/
int
irc_color_convert_term2irc (int color)
{
char str_color[64], *error;
const char *info_color;
long number;
snprintf (str_color, sizeof (str_color), "%d", color);
info_color = weechat_info_get ("color_term2rgb", str_color);
if (!info_color || !info_color[0])
return -1;
error = NULL;
number = strtol (info_color, &error, 10);
if (!error || error[0] || (number < 0) || (number > 0xFFFFFF))
return -1;
return irc_color_convert_rgb2irc (number);
}
/*
* Replaces ANSI colors by IRC colors (or removes them).
*
* This callback is called by irc_color_decode_ansi, it must not be called
* directly.
*/
char *
irc_color_decode_ansi_cb (void *data, const char *text)
{
struct t_irc_color_ansi_state *ansi_state;
char *text2, **items, *output, str_color[128];
int i, length, num_items, value, color;
ansi_state = (struct t_irc_color_ansi_state *)data;
/* if we don't keep colors of if text is empty, just return empty string */
if (!ansi_state->keep_colors || !text || !text[0])
return strdup ("");
/* only sequences ending with 'm' are used, the others are discarded */
length = strlen (text);
if (text[length - 1] != 'm')
return strdup ("");
/* sequence "\33[m" resets color */
if (length < 4)
return strdup (weechat_color ("reset"));
text2 = NULL;
items = NULL;
output = NULL;
/* extract text between "\33[" and "m" */
text2 = weechat_strndup (text + 2, length - 3);
if (!text2)
goto end;
items = weechat_string_split (text2, ";", 0, 0, &num_items);
if (!items)
goto end;
output = malloc ((32 * num_items) + 1);
if (!output)
goto end;
output[0] = '\0';
for (i = 0; i < num_items; i++)
{
value = atoi (items[i]);
switch (value)
{
case 0: /* reset */
strcat (output, IRC_COLOR_RESET_STR);
ansi_state->bold = 0;
ansi_state->underline = 0;
ansi_state->italic = 0;
break;
case 1: /* bold */
if (!ansi_state->bold)
{
strcat (output, IRC_COLOR_BOLD_STR);
ansi_state->bold = 1;
}
break;
case 2: /* remove bold */
case 21:
case 22:
if (ansi_state->bold)
{
strcat (output, IRC_COLOR_BOLD_STR);
ansi_state->bold = 0;
}
break;
case 3: /* italic */
if (!ansi_state->italic)
{
strcat (output, IRC_COLOR_ITALIC_STR);
ansi_state->italic = 1;
}
break;
case 4: /* underline */
if (!ansi_state->underline)
{
strcat (output, IRC_COLOR_UNDERLINE_STR);
ansi_state->underline = 1;
}
break;
case 23: /* remove italic */
if (ansi_state->italic)
{
strcat (output, IRC_COLOR_ITALIC_STR);
ansi_state->italic = 0;
}
break;
case 24: /* remove underline */
if (ansi_state->underline)
{
strcat (output, IRC_COLOR_UNDERLINE_STR);
ansi_state->underline = 0;
}
break;
case 30: /* text color */
case 31:
case 32:
case 33:
case 34:
case 35:
case 36:
case 37:
snprintf (str_color, sizeof (str_color),
"%c%02d",
IRC_COLOR_COLOR_CHAR,
irc_color_term2irc[value - 30]);
strcat (output, str_color);
break;
case 38: /* text color */
if (i + 1 < num_items)
{
switch (atoi (items[i + 1]))
{
case 2: /* RGB color */
if (i + 4 < num_items)
{
color = irc_color_convert_rgb2irc (
(atoi (items[i + 2]) << 16) |
(atoi (items[i + 3]) << 8) |
atoi (items[i + 4]));
if (color >= 0)
{
snprintf (str_color, sizeof (str_color),
"%c%02d",
IRC_COLOR_COLOR_CHAR,
color);
strcat (output, str_color);
}
i += 4;
}
break;
case 5: /* terminal color (0-255) */
if (i + 2 < num_items)
{
color = irc_color_convert_term2irc (atoi (items[i + 2]));
if (color >= 0)
{
snprintf (str_color, sizeof (str_color),
"%c%02d",
IRC_COLOR_COLOR_CHAR,
color);
strcat (output, str_color);
}
i += 2;
}
break;
}
}
break;
case 39: /* default text color */
snprintf (str_color, sizeof (str_color),
"%c15",
IRC_COLOR_COLOR_CHAR);
strcat (output, str_color);
break;
case 40: /* background color */
case 41:
case 42:
case 43:
case 44:
case 45:
case 46:
case 47:
snprintf (str_color, sizeof (str_color),
"%c,%02d",
IRC_COLOR_COLOR_CHAR,
irc_color_term2irc[value - 40]);
strcat (output, str_color);
break;
case 48: /* background color */
if (i + 1 < num_items)
{
switch (atoi (items[i + 1]))
{
case 2: /* RGB color */
if (i + 4 < num_items)
{
color = irc_color_convert_rgb2irc (
(atoi (items[i + 2]) << 16) |
(atoi (items[i + 3]) << 8) |
atoi (items[i + 4]));
if (color >= 0)
{
snprintf (str_color, sizeof (str_color),
"%c,%02d",
IRC_COLOR_COLOR_CHAR,
color);
strcat (output, str_color);
}
i += 4;
}
break;
case 5: /* terminal color (0-255) */
if (i + 2 < num_items)
{
color = irc_color_convert_term2irc (atoi (items[i + 2]));
if (color >= 0)
{
snprintf (str_color, sizeof (str_color),
"%c,%02d",
IRC_COLOR_COLOR_CHAR,
color);
strcat (output, str_color);
}
i += 2;
}
break;
}
}
break;
case 49: /* default background color */
snprintf (str_color, sizeof (str_color),
"%c,01",
IRC_COLOR_COLOR_CHAR);
strcat (output, str_color);
break;
}
}
end:
if (items)
weechat_string_free_split (items);
if (text2)
free (text2);
return (output) ? output : strdup ("");
}
/*
* Replaces ANSI colors by IRC colors.
*
* If keep_colors == 0: removes any color/style in message otherwise keeps
* colors.
*
* Note: result must be freed after use.
*/
char *
irc_color_decode_ansi (const char *string, int keep_colors)
{
struct t_irc_color_ansi_state ansi_state;
/* allocate/compile regex if needed (first call) */
if (!irc_color_regex_ansi)
{
irc_color_regex_ansi = malloc (sizeof (*irc_color_regex_ansi));
if (!irc_color_regex_ansi)
return NULL;
if (weechat_string_regcomp (irc_color_regex_ansi,
weechat_info_get ("color_ansi_regex", NULL),
REG_EXTENDED) != 0)
{
free (irc_color_regex_ansi);
irc_color_regex_ansi = NULL;
return NULL;
}
}
ansi_state.keep_colors = keep_colors;
ansi_state.bold = 0;
ansi_state.underline = 0;
ansi_state.italic = 0;
return weechat_string_replace_regex (string, irc_color_regex_ansi,
"$0", '$',
&irc_color_decode_ansi_cb,
&ansi_state);
}
/*
* Callback for modifiers "irc_color_decode" and "irc_color_encode".
*
@@ -385,6 +743,9 @@ irc_color_modifier_cb (void *data, const char *modifier,
if (strcmp (modifier, "irc_color_encode") == 0)
return irc_color_encode (string, keep_colors);
if (strcmp (modifier, "irc_color_decode_ansi") == 0)
return irc_color_decode_ansi (string, keep_colors);
/* unknown modifier */
return NULL;
}
@@ -403,3 +764,18 @@ irc_color_for_tags (const char *color)
return weechat_string_replace (color, ",", ":");
}
/*
* Ends IRC colors.
*/
void
irc_color_end ()
{
if (irc_color_regex_ansi)
{
regfree (irc_color_regex_ansi);
free (irc_color_regex_ansi);
irc_color_regex_ansi = NULL;
}
}
+11
View File
@@ -59,6 +59,8 @@
#define IRC_COLOR_UNDERLINE_CHAR '\x1F' /* underlined text */
#define IRC_COLOR_UNDERLINE_STR "\x1F" /* [1F]...[1F] */
#define IRC_COLOR_TERM2IRC_NUM_COLORS 16
/* macros for WeeChat core and IRC colors */
#define IRC_COLOR_BAR_FG weechat_color("bar_fg")
@@ -92,11 +94,20 @@
#define IRC_COLOR_ITEM_LAG_COUNTING weechat_color(weechat_config_string(irc_config_color_item_lag_counting))
#define IRC_COLOR_ITEM_LAG_FINISHED weechat_color(weechat_config_string(irc_config_color_item_lag_finished))
struct t_irc_color_ansi_state
{
char keep_colors;
char bold;
char underline;
char italic;
};
extern char *irc_color_decode (const char *string, int keep_colors);
extern char *irc_color_encode (const char *string, int keep_colors);
extern char *irc_color_modifier_cb (void *data, const char *modifier,
const char *modifier_data,
const char *string);
extern char *irc_color_for_tags (const char *color);
extern void irc_color_end ();
#endif /* __WEECHAT_IRC_COLOR_H */
+3
View File
@@ -189,6 +189,7 @@ weechat_plugin_init (struct t_weechat_plugin *plugin, int argc, char *argv[])
/* modifiers */
weechat_hook_modifier ("irc_color_decode", &irc_color_modifier_cb, NULL);
weechat_hook_modifier ("irc_color_encode", &irc_color_modifier_cb, NULL);
weechat_hook_modifier ("irc_color_decode_ansi", &irc_color_modifier_cb, NULL);
/* hook completions */
irc_completion_init ();
@@ -281,5 +282,7 @@ weechat_plugin_end (struct t_weechat_plugin *plugin)
irc_redirect_end ();
irc_color_end ();
return WEECHAT_RC_OK;
}