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:
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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)_ |
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user