Merge pull request #204 from wavexx/rule_allow_markup
Fix markup handling.
This commit is contained in:
commit
56b0a7c7d9
15
config.def.h
15
config.def.h
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
char *font = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*";
|
char *font = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*";
|
||||||
bool allow_markup = false;
|
bool allow_markup = false;
|
||||||
|
bool plain_text = true;
|
||||||
char *normbgcolor = "#1793D1";
|
char *normbgcolor = "#1793D1";
|
||||||
char *normfgcolor = "#DDDDDD";
|
char *normfgcolor = "#DDDDDD";
|
||||||
char *critbgcolor = "#ffaaaa";
|
char *critbgcolor = "#ffaaaa";
|
||||||
@ -90,11 +91,11 @@ keyboard_shortcut context_ks = {.str = "none",
|
|||||||
rule_t default_rules[] = {
|
rule_t default_rules[] = {
|
||||||
/* name can be any unique string. It is used to identify the rule in dunstrc to override it there */
|
/* name can be any unique string. It is used to identify the rule in dunstrc to override it there */
|
||||||
|
|
||||||
/* name, appname, summary, body, icon, category, msg_urgency, timeout, urgency, fg, bg, format, script */
|
/* name, appname, summary, body, icon, category, msg_urgency, timeout, urgency, allow_markup, plain_text, new_icon, fg, bg, format, script */
|
||||||
{ "empty", NULL, NULL, NULL, NULL, NULL, -1, -1, -1, NULL, NULL, NULL, NULL},
|
{ "empty", NULL, NULL, NULL, NULL, NULL, -1, -1, -1, -1, -1, NULL, NULL, NULL, NULL, NULL},
|
||||||
/* { "rule1", "notify-send", NULL, NULL, NULL, NULL, -1, -1, -1, NULL, NULL, "%s %b", NULL }, */
|
/* { "rule1", "notify-send", NULL, NULL, NULL, NULL, -1, -1, -1, -1, -1, NULL, NULL, NULL, "%s %b", NULL }, */
|
||||||
/* { "rule2", "Pidgin", "*says*, NULL, NULL, NULL, -1, -1, CRITICAL, NULL, NULL, NULL, NULL }, */
|
/* { "rule2", "Pidgin", "*says*, NULL, NULL, NULL, -1, -1, CRITICAL, -1, -1, NULL, NULL, NULL, NULL, NULL }, */
|
||||||
/* { "rule3", "Pidgin", "*signed on*", NULL, NULL, NULL, -1, -1, LOW, NULL, NULL, NULL, NULL }, */
|
/* { "rule3", "Pidgin", "*signed on*", NULL, NULL, NULL, -1, -1, LOW, -1, -1, NULL, NULL, NULL, NULL, NULL }, */
|
||||||
/* { "rule4", "Pidgin", "*signed off*", NULL, NULL, NULL, -1, -1, LOW, NULL, NULL, NULL, NULL }, */
|
/* { "rule4", "Pidgin", "*signed off*", NULL, NULL, NULL, -1, -1, LOW, -1, -1, NULL, NULL, NULL, NULL, NULL }, */
|
||||||
/* { "rule5", NULL, "*foobar*", NULL, NULL, NULL, -1, -1, -1, NULL, "#00FF00", NULL, NULL }, */
|
/* { "rule5", NULL, "*foobar*", NULL, NULL, NULL, -1, -1, -1, -1, -1, NULL, NULL, "#00FF00", NULL, NULL }, */
|
||||||
};
|
};
|
||||||
|
3
dbus.c
3
dbus.c
@ -9,6 +9,7 @@
|
|||||||
#include "dbus.h"
|
#include "dbus.h"
|
||||||
#include "notification.h"
|
#include "notification.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
GDBusConnection *dbus_conn;
|
GDBusConnection *dbus_conn;
|
||||||
|
|
||||||
@ -283,6 +284,8 @@ static void onNotify(GDBusConnection * connection,
|
|||||||
n->body = body;
|
n->body = body;
|
||||||
n->icon = icon;
|
n->icon = icon;
|
||||||
n->timeout = timeout;
|
n->timeout = timeout;
|
||||||
|
n->allow_markup = settings.allow_markup;
|
||||||
|
n->plain_text = settings.plain_text;
|
||||||
n->progress = (progress < 0 || progress > 100) ? 0 : progress + 1;
|
n->progress = (progress < 0 || progress > 100) ? 0 : progress + 1;
|
||||||
n->urgency = urgency;
|
n->urgency = urgency;
|
||||||
n->category = category;
|
n->category = category;
|
||||||
|
2
dunst.c
2
dunst.c
@ -327,6 +327,8 @@ int main(int argc, char *argv[])
|
|||||||
n->body = strdup("dunst is up and running");
|
n->body = strdup("dunst is up and running");
|
||||||
n->progress = 0;
|
n->progress = 0;
|
||||||
n->timeout = 10;
|
n->timeout = 10;
|
||||||
|
n->allow_markup = false;
|
||||||
|
n->plain_text = true;
|
||||||
n->urgency = LOW;
|
n->urgency = LOW;
|
||||||
n->icon = NULL;
|
n->icon = NULL;
|
||||||
n->category = NULL;
|
n->category = NULL;
|
||||||
|
5
dunstrc
5
dunstrc
@ -1,7 +1,7 @@
|
|||||||
[global]
|
[global]
|
||||||
font = Monospace 8
|
font = Monospace 8
|
||||||
|
|
||||||
# Allow a small subset of html markup:
|
# Allow a small subset of html markup in notifications and formats:
|
||||||
# <b>bold</b>
|
# <b>bold</b>
|
||||||
# <i>italic</i>
|
# <i>italic</i>
|
||||||
# <s>strikethrough</s>
|
# <s>strikethrough</s>
|
||||||
@ -13,6 +13,9 @@
|
|||||||
# message.
|
# message.
|
||||||
allow_markup = yes
|
allow_markup = yes
|
||||||
|
|
||||||
|
# Treat incoming notifications as plain text
|
||||||
|
plain_text = no
|
||||||
|
|
||||||
# The format of the message. Possible variables are:
|
# The format of the message. Possible variables are:
|
||||||
# %a appname
|
# %a appname
|
||||||
# %s summary
|
# %s summary
|
||||||
|
@ -161,8 +161,7 @@ void notification_free(notification * n)
|
|||||||
/*
|
/*
|
||||||
* Strip any markup from text
|
* Strip any markup from text
|
||||||
*/
|
*/
|
||||||
|
char *notification_strip_markup(char *str)
|
||||||
char *notification_fix_markup(char *str)
|
|
||||||
{
|
{
|
||||||
char *replace_buf, *start, *end;
|
char *replace_buf, *start, *end;
|
||||||
|
|
||||||
@ -210,9 +209,62 @@ char *notification_fix_markup(char *str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Quote a text string for rendering with pango
|
||||||
|
*/
|
||||||
|
char *notification_quote_markup(char *str)
|
||||||
|
{
|
||||||
|
if (str == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
str = string_replace_all("&", "&", str);
|
||||||
|
str = string_replace_all("\"", """, str);
|
||||||
|
str = string_replace_all("'", "'", str);
|
||||||
|
str = string_replace_all("<", "<", str);
|
||||||
|
str = string_replace_all(">", ">", str);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Replace all occurrences of "needle" with a quoted "replacement",
|
||||||
|
* according to the allow_markup/plain_text settings.
|
||||||
|
*/
|
||||||
|
char *notification_replace_format(const char *needle, const char *replacement,
|
||||||
|
char *haystack, bool allow_markup,
|
||||||
|
bool plain_text) {
|
||||||
|
char* tmp;
|
||||||
|
char* ret;
|
||||||
|
|
||||||
|
if (plain_text) {
|
||||||
|
tmp = strdup(replacement);
|
||||||
|
tmp = string_replace_all("\\n", "\n", tmp);
|
||||||
|
if (settings.ignore_newline) {
|
||||||
|
tmp = string_replace_all("\n", " ", tmp);
|
||||||
|
}
|
||||||
|
tmp = notification_quote_markup(tmp);
|
||||||
|
ret = string_replace_all(needle, tmp, haystack);
|
||||||
|
free(tmp);
|
||||||
|
} else if (!allow_markup) {
|
||||||
|
tmp = strdup(replacement);
|
||||||
|
if (!settings.ignore_newline) {
|
||||||
|
tmp = string_replace_all("<br>", "\n", tmp);
|
||||||
|
tmp = string_replace_all("<br/>", "\n", tmp);
|
||||||
|
tmp = string_replace_all("<br />", "\n", tmp);
|
||||||
|
}
|
||||||
|
tmp = notification_strip_markup(tmp);
|
||||||
|
tmp = notification_quote_markup(tmp);
|
||||||
|
ret = string_replace_all(needle, tmp, haystack);
|
||||||
|
free(tmp);
|
||||||
|
} else {
|
||||||
|
ret = string_replace_all(needle, replacement, haystack);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
char *notification_extract_markup_urls(char **str_ptr) {
|
char *notification_extract_markup_urls(char **str_ptr) {
|
||||||
char *start, *end, *replace_buf, *str, *urls = NULL, *url, *index_buf;
|
char *start, *end, *replace_buf, *str, *urls = NULL, *url, *index_buf;
|
||||||
@ -259,7 +311,6 @@ char *notification_extract_markup_urls(char **str_ptr) {
|
|||||||
*/
|
*/
|
||||||
int notification_init(notification * n, int id)
|
int notification_init(notification * n, int id)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (n == NULL)
|
if (n == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -282,35 +333,29 @@ int notification_init(notification * n, int id)
|
|||||||
|
|
||||||
n->urls = notification_extract_markup_urls(&(n->body));
|
n->urls = notification_extract_markup_urls(&(n->body));
|
||||||
|
|
||||||
n->msg = string_replace("%a", n->appname, g_strdup(n->format));
|
n->msg = string_replace_all("\\n", "\n", g_strdup(n->format));
|
||||||
n->msg = string_replace("%s", n->summary, n->msg);
|
n->msg = notification_replace_format("%a", n->appname, n->msg,
|
||||||
|
false, true);
|
||||||
|
n->msg = notification_replace_format("%s", n->summary, n->msg,
|
||||||
|
n->allow_markup, n->plain_text);
|
||||||
|
n->msg = notification_replace_format("%b", n->body, n->msg,
|
||||||
|
n->allow_markup, n->plain_text);
|
||||||
|
|
||||||
if (n->icon) {
|
if (n->icon) {
|
||||||
n->msg = string_replace("%I", basename(n->icon), n->msg);
|
n->msg = notification_replace_format("%I", basename(n->icon),
|
||||||
n->msg = string_replace("%i", n->icon, n->msg);
|
n->msg, false, true);
|
||||||
|
n->msg = notification_replace_format("%i", n->icon,
|
||||||
|
n->msg, false, true);
|
||||||
}
|
}
|
||||||
n->msg = string_replace("%b", n->body, n->msg);
|
|
||||||
if (n->progress) {
|
if (n->progress) {
|
||||||
char pg[10];
|
char pg[10];
|
||||||
sprintf(pg, "[%3d%%]", n->progress - 1);
|
sprintf(pg, "[%3d%%]", n->progress - 1);
|
||||||
n->msg = string_replace("%p", pg, n->msg);
|
n->msg = string_replace_all("%p", pg, n->msg);
|
||||||
} else {
|
} else {
|
||||||
n->msg = string_replace("%p", "", n->msg);
|
n->msg = string_replace_all("%p", "", n->msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!settings.allow_markup)
|
|
||||||
n->msg = notification_fix_markup(n->msg);
|
|
||||||
else if (!settings.ignore_newline) {
|
|
||||||
n->msg = string_replace("<br>", "\n", n->msg);
|
|
||||||
n->msg = string_replace("<br />", "\n", n->msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (strstr(n->msg, "\\n") != NULL)
|
|
||||||
n->msg = string_replace("\\n", "\n", n->msg);
|
|
||||||
|
|
||||||
if (settings.ignore_newline)
|
|
||||||
while (strstr(n->msg, "\n") != NULL)
|
|
||||||
n->msg = string_replace("\n", " ", n->msg);
|
|
||||||
|
|
||||||
n->msg = g_strstrip(n->msg);
|
n->msg = g_strstrip(n->msg);
|
||||||
|
|
||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
|
@ -27,6 +27,8 @@ typedef struct _notification {
|
|||||||
time_t timestamp;
|
time_t timestamp;
|
||||||
int timeout;
|
int timeout;
|
||||||
int urgency;
|
int urgency;
|
||||||
|
bool allow_markup;
|
||||||
|
bool plain_text;
|
||||||
bool redisplayed; /* has been displayed before? */
|
bool redisplayed; /* has been displayed before? */
|
||||||
int id;
|
int id;
|
||||||
int dup_count;
|
int dup_count;
|
||||||
@ -49,7 +51,8 @@ int notification_cmp_data(const void *a, const void *b, void *data);
|
|||||||
void notification_run_script(notification * n);
|
void notification_run_script(notification * n);
|
||||||
int notification_close(notification * n, int reason);
|
int notification_close(notification * n, int reason);
|
||||||
void notification_print(notification * n);
|
void notification_print(notification * n);
|
||||||
char *notification_fix_markup(char *str);
|
char *notification_strip_markup(char *str);
|
||||||
|
char *notification_quote_markup(char *str);
|
||||||
void notification_update_text_to_render(notification *n);
|
void notification_update_text_to_render(notification *n);
|
||||||
int notification_get_ttl(notification *n);
|
int notification_get_ttl(notification *n);
|
||||||
int notification_get_age(notification *n);
|
int notification_get_age(notification *n);
|
||||||
|
7
rules.c
7
rules.c
@ -15,6 +15,10 @@ void rule_apply(rule_t * r, notification * n)
|
|||||||
n->timeout = r->timeout;
|
n->timeout = r->timeout;
|
||||||
if (r->urgency != -1)
|
if (r->urgency != -1)
|
||||||
n->urgency = r->urgency;
|
n->urgency = r->urgency;
|
||||||
|
if (r->allow_markup != -1)
|
||||||
|
n->allow_markup = r->allow_markup;
|
||||||
|
if (r->plain_text != -1)
|
||||||
|
n->plain_text = r->plain_text;
|
||||||
if (r->new_icon)
|
if (r->new_icon)
|
||||||
n->icon = r->new_icon;
|
n->icon = r->new_icon;
|
||||||
if (r->fg)
|
if (r->fg)
|
||||||
@ -54,6 +58,8 @@ void rule_init(rule_t * r)
|
|||||||
r->msg_urgency = -1;
|
r->msg_urgency = -1;
|
||||||
r->timeout = -1;
|
r->timeout = -1;
|
||||||
r->urgency = -1;
|
r->urgency = -1;
|
||||||
|
r->allow_markup = -1;
|
||||||
|
r->plain_text = -1;
|
||||||
r->new_icon = NULL;
|
r->new_icon = NULL;
|
||||||
r->fg = NULL;
|
r->fg = NULL;
|
||||||
r->bg = NULL;
|
r->bg = NULL;
|
||||||
@ -65,7 +71,6 @@ void rule_init(rule_t * r)
|
|||||||
*/
|
*/
|
||||||
bool rule_matches_notification(rule_t * r, notification * n)
|
bool rule_matches_notification(rule_t * r, notification * n)
|
||||||
{
|
{
|
||||||
|
|
||||||
return ((!r->appname || !fnmatch(r->appname, n->appname, 0))
|
return ((!r->appname || !fnmatch(r->appname, n->appname, 0))
|
||||||
&& (!r->summary || !fnmatch(r->summary, n->summary, 0))
|
&& (!r->summary || !fnmatch(r->summary, n->summary, 0))
|
||||||
&& (!r->body || !fnmatch(r->body, n->body, 0))
|
&& (!r->body || !fnmatch(r->body, n->body, 0))
|
||||||
|
2
rules.h
2
rules.h
@ -19,6 +19,8 @@ typedef struct _rule_t {
|
|||||||
/* actions */
|
/* actions */
|
||||||
int timeout;
|
int timeout;
|
||||||
int urgency;
|
int urgency;
|
||||||
|
int allow_markup;
|
||||||
|
int plain_text;
|
||||||
char *new_icon;
|
char *new_icon;
|
||||||
char *fg;
|
char *fg;
|
||||||
char *bg;
|
char *bg;
|
||||||
|
@ -85,7 +85,10 @@ void load_settings(char *cmdline_config_path)
|
|||||||
"The font dunst should use.");
|
"The font dunst should use.");
|
||||||
settings.allow_markup =
|
settings.allow_markup =
|
||||||
option_get_bool("global", "allow_markup", "-markup", allow_markup,
|
option_get_bool("global", "allow_markup", "-markup", allow_markup,
|
||||||
"Allow markups.");
|
"Allow markups in notifications/formats.");
|
||||||
|
settings.plain_text =
|
||||||
|
option_get_bool("global", "plain_text", "-plain", plain_text,
|
||||||
|
"Treat incoming notifications as plain text.");
|
||||||
settings.format =
|
settings.format =
|
||||||
option_get_string("global", "format", "-format", format,
|
option_get_string("global", "format", "-format", format,
|
||||||
"The format template for the notifictions");
|
"The format template for the notifictions");
|
||||||
@ -352,6 +355,8 @@ void load_settings(char *cmdline_config_path)
|
|||||||
r->body = ini_get_string(cur_section, "body", r->body);
|
r->body = ini_get_string(cur_section, "body", r->body);
|
||||||
r->icon = ini_get_string(cur_section, "icon", r->icon);
|
r->icon = ini_get_string(cur_section, "icon", r->icon);
|
||||||
r->timeout = ini_get_int(cur_section, "timeout", r->timeout);
|
r->timeout = ini_get_int(cur_section, "timeout", r->timeout);
|
||||||
|
r->allow_markup = ini_get_bool(cur_section, "allow_markup", r->allow_markup);
|
||||||
|
r->plain_text = ini_get_bool(cur_section, "plain_text", r->plain_text);
|
||||||
r->urgency = ini_get_urgency(cur_section, "urgency", r->urgency);
|
r->urgency = ini_get_urgency(cur_section, "urgency", r->urgency);
|
||||||
r->msg_urgency = ini_get_urgency(cur_section, "msg_urgency", r->msg_urgency);
|
r->msg_urgency = ini_get_urgency(cur_section, "msg_urgency", r->msg_urgency);
|
||||||
r->fg = ini_get_string(cur_section, "foreground", r->fg);
|
r->fg = ini_get_string(cur_section, "foreground", r->fg);
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
typedef struct _settings {
|
typedef struct _settings {
|
||||||
bool print_notifications;
|
bool print_notifications;
|
||||||
bool allow_markup;
|
bool allow_markup;
|
||||||
|
bool plain_text;
|
||||||
bool stack_duplicates;
|
bool stack_duplicates;
|
||||||
char *font;
|
char *font;
|
||||||
char *normbgcolor;
|
char *normbgcolor;
|
||||||
|
59
utils.c
59
utils.c
@ -17,39 +17,56 @@ char *string_replace_char(char needle, char replacement, char *haystack) {
|
|||||||
return haystack;
|
return haystack;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *string_replace_all(const char *needle, const char *replacement,
|
char *string_replace_at(char *buf, int pos, int len, const char *repl)
|
||||||
char *haystack)
|
|
||||||
{
|
{
|
||||||
char *start;
|
char *tmp;
|
||||||
start = strstr(haystack, needle);
|
int size, buf_len, repl_len;
|
||||||
while (start != NULL) {
|
|
||||||
haystack = string_replace(needle, replacement, haystack);
|
buf_len = strlen(buf);
|
||||||
start = strstr(haystack, needle);
|
repl_len = strlen(repl);
|
||||||
}
|
size = (buf_len - len) + repl_len + 1;
|
||||||
return haystack;
|
tmp = malloc(size);
|
||||||
|
|
||||||
|
memcpy(tmp, buf, pos);
|
||||||
|
memcpy(tmp + pos, repl, repl_len);
|
||||||
|
memcpy(tmp + pos + repl_len, buf + pos + len, buf_len - (pos + len) + 1);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *string_replace(const char *needle, const char *replacement,
|
char *string_replace(const char *needle, const char *replacement, char *haystack)
|
||||||
char *haystack)
|
|
||||||
{
|
{
|
||||||
char *tmp, *start;
|
char *start;
|
||||||
int size;
|
|
||||||
start = strstr(haystack, needle);
|
start = strstr(haystack, needle);
|
||||||
if (start == NULL) {
|
if (start == NULL) {
|
||||||
return haystack;
|
return haystack;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = (strlen(haystack) - strlen(needle)) + strlen(replacement) + 1;
|
return string_replace_at(haystack, (start - haystack), strlen(needle), replacement);
|
||||||
tmp = calloc(sizeof(char), size);
|
}
|
||||||
memset(tmp, '\0', size);
|
|
||||||
|
|
||||||
strncpy(tmp, haystack, start - haystack);
|
char *string_replace_all(const char *needle, const char *replacement,
|
||||||
tmp[start - haystack] = '\0';
|
char *haystack)
|
||||||
|
{
|
||||||
|
char *start;
|
||||||
|
int needle_pos;
|
||||||
|
int needle_len, repl_len;
|
||||||
|
|
||||||
sprintf(tmp + strlen(tmp), "%s%s", replacement, start + strlen(needle));
|
needle_len = strlen(needle);
|
||||||
free(haystack);
|
if (needle_len == 0) {
|
||||||
|
return haystack;
|
||||||
|
}
|
||||||
|
|
||||||
return tmp;
|
start = strstr(haystack, needle);
|
||||||
|
repl_len = strlen(replacement);
|
||||||
|
|
||||||
|
while (start != NULL) {
|
||||||
|
needle_pos = start - haystack;
|
||||||
|
haystack = string_replace_at(haystack, needle_pos, needle_len, replacement);
|
||||||
|
start = strstr(haystack + needle_pos + repl_len, needle);
|
||||||
|
}
|
||||||
|
return haystack;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *string_append(char *a, const char *b, const char *sep)
|
char *string_append(char *a, const char *b, const char *sep)
|
||||||
|
2
x.c
2
x.c
@ -382,7 +382,7 @@ static colored_layout *r_create_layout_from_notification(cairo_t *c, notificatio
|
|||||||
pango_layout_set_attributes(cl->l, cl->attr);
|
pango_layout_set_attributes(cl->l, cl->attr);
|
||||||
} else {
|
} else {
|
||||||
/* remove markup and display plain message instead */
|
/* remove markup and display plain message instead */
|
||||||
n->text_to_render = notification_fix_markup(n->text_to_render);
|
n->text_to_render = notification_strip_markup(n->text_to_render);
|
||||||
cl->text = NULL;
|
cl->text = NULL;
|
||||||
cl->attr = NULL;
|
cl->attr = NULL;
|
||||||
pango_layout_set_text(cl->l, n->text_to_render, -1);
|
pango_layout_set_text(cl->l, n->text_to_render, -1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user