From 4e1b97f3ccc35672d5588be1b4f801b3532358c6 Mon Sep 17 00:00:00 2001 From: Nikos Tsipinakis Date: Sat, 4 Feb 2017 16:36:43 +0200 Subject: [PATCH] Merge allow_markup and plain_text into markup Merge the allow_markup and plain_text settings into a single setting. These 2 settings had a similar function, allow_markup controlled whether markup was parsed or stripped and plain_text whether the notification was escaped and displayed as is. To cover all the possible combinations of the settings mentioned above `markup` can take the following values: full: The equivalent of allow_markup yes, plain_text no. Passes the text straight to pango with minimal parsing. All valid pango tags will be parsed. strip: The equivalent of allow_markup no, plain_text no. Strips the markup using string_strip_delimited. The parsing is simplistic and if there are any unescaped '<' and/or '>' characters it might get tripped and strip out actual text. According to the GNOME notification specification, if a server doesn't support markup(and we don't advertise that we do if it is turned off) it should be stripped clientside, so this setting should rarely be used. It is mainly left in for compatibility with broken clients that don't follow the specification. no: The equivalent of allow_markup [yes/no](any value), plain_text yes. Makes the notification content be rendered as plain text regardless if it contains markup. Any Markup will be shown as regular text. Markup inside 'format' will still be parsed regardless of what markup is set to. Closes #279 --- config.def.h | 17 ++++++++--------- dunstrc | 35 +++++++++++++++++++++------------- src/dbus.c | 8 +++++--- src/dunst.c | 3 +-- src/notification.c | 19 +++++++++---------- src/notification.h | 4 ++-- src/rules.c | 9 +++------ src/rules.h | 4 ++-- src/settings.c | 47 ++++++++++++++++++++++++++++++++++------------ src/settings.h | 4 ++-- 10 files changed, 89 insertions(+), 61 deletions(-) diff --git a/config.def.h b/config.def.h index d91e495..aa469c6 100644 --- a/config.def.h +++ b/config.def.h @@ -1,8 +1,7 @@ /* see example dunstrc for additional explanations about these options */ char *font = "-*-terminus-medium-r-*-*-16-*-*-*-*-*-*-*"; -bool allow_markup = false; -bool plain_text = true; +char *markup = "no"; char *normbgcolor = "#1793D1"; char *normfgcolor = "#DDDDDD"; char *critbgcolor = "#ffaaaa"; @@ -94,11 +93,11 @@ keyboard_shortcut context_ks = {.str = "none", rule_t default_rules[] = { /* 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, allow_markup, plain_text, new_icon, fg, bg, format, script */ - { "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, -1, -1, NULL, NULL, NULL, "%s %b", 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, -1, -1, NULL, 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, -1, -1, NULL, NULL, "#00FF00", NULL, NULL }, */ + /* name, appname, summary, body, icon, category, msg_urgency, timeout, urgency, markup, new_icon, fg, bg, format, script */ + { "empty", NULL, NULL, NULL, NULL, NULL, -1, -1, -1, -1, NULL, NULL, NULL, NULL, NULL}, + /* { "rule1", "notify-send", NULL, NULL, NULL, NULL, -1, -1, -1, -1, NULL, NULL, NULL, "%s %b", NULL }, */ + /* { "rule2", "Pidgin", "*says*, NULL, NULL, NULL, -1, -1, CRITICAL, -1, NULL, NULL, NULL, NULL, NULL }, */ + /* { "rule3", "Pidgin", "*signed on*", NULL, NULL, NULL, -1, -1, LOW, -1, NULL, NULL, NULL, NULL, NULL }, */ + /* { "rule4", "Pidgin", "*signed off*", NULL, NULL, NULL, -1, -1, LOW, -1, NULL, NULL, NULL, NULL, NULL }, */ + /* { "rule5", NULL, "*foobar*", NULL, NULL, NULL, -1, -1, -1, -1, NULL, NULL, "#00FF00", NULL, NULL }, */ }; diff --git a/dunstrc b/dunstrc index c95382b..ded3283 100644 --- a/dunstrc +++ b/dunstrc @@ -1,20 +1,29 @@ [global] font = Monospace 8 - # Allow a small subset of html markup in notifications and formats: - # bold - # italic - # strikethrough - # underline + # Possible values are: + # full: Allow a small subset of html markup in notifications: + # bold + # italic + # strikethrough + # underline # - # For a complete reference see - # . - # If markup is not allowed, those tags will be stripped out of the - # message. - allow_markup = yes - - # Treat incoming notifications as plain text - plain_text = no + # For a complete reference see + # . + # + # strip: This setting is provided for compatibility with some broken + # clients that send markup even though it's not enabled on the + # server. Dunst will try to strip the markup but the parsing is + # simplistic so using this option outside of matching rules for + # specific applications *IS GREATLY DISCOURAGED*. + # + # no: Disable markup parsing, incoming notifications will be treated as + # plain text. Dunst will not advertise that it has the body-markup + # capability if this is set as a global setting. + # + # It's important to note that markup inside the format option will be parsed + # regardless of what this is set to. + markup = full # The format of the message. Possible variables are: # %a appname diff --git a/src/dbus.c b/src/dbus.c index 0595b88..44aeaf1 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -110,7 +110,10 @@ static void on_get_capabilities(GDBusConnection * connection, builder = g_variant_builder_new(G_VARIANT_TYPE("as")); g_variant_builder_add(builder, "s", "actions"); g_variant_builder_add(builder, "s", "body"); - g_variant_builder_add(builder, "s", "body-markup"); + + if(settings.markup != MARKUP_NO) + g_variant_builder_add(builder, "s", "body-markup"); + value = g_variant_new("(as)", builder); g_variant_builder_unref(builder); g_dbus_method_invocation_return_value(invocation, value); @@ -301,8 +304,7 @@ static void on_notify(GDBusConnection * connection, n->icon = icon; n->raw_icon = raw_icon; n->timeout = timeout; - n->allow_markup = settings.allow_markup; - n->plain_text = settings.plain_text; + n->markup = settings.markup; n->progress = (progress < 0 || progress > 100) ? 0 : progress + 1; n->urgency = urgency; n->category = category; diff --git a/src/dunst.c b/src/dunst.c index 9364a00..422b39d 100644 --- a/src/dunst.c +++ b/src/dunst.c @@ -349,8 +349,7 @@ int dunst_main(int argc, char *argv[]) n->body = strdup("dunst is up and running"); n->progress = 0; n->timeout = 10; - n->allow_markup = false; - n->plain_text = true; + n->markup = MARKUP_NO; n->urgency = LOW; notification_init(n, 0); } diff --git a/src/notification.c b/src/notification.c index 4239763..9e8de86 100644 --- a/src/notification.c +++ b/src/notification.c @@ -236,15 +236,14 @@ char *notification_quote_markup(char *str) /* * Replace all occurrences of "needle" with a quoted "replacement", - * according to the allow_markup/plain_text settings. + * according to the markup settings. */ char *notification_replace_format(const char *needle, const char *replacement, - char *haystack, bool allow_markup, - bool plain_text) { + char *haystack, enum markup_mode markup_mode) { char* tmp; char* ret; - if (plain_text) { + if (markup_mode == MARKUP_NO) { tmp = strdup(replacement); tmp = string_replace_all("\\n", "\n", tmp); if (settings.ignore_newline) { @@ -265,7 +264,7 @@ char *notification_replace_format(const char *needle, const char *replacement, tmp = string_replace_all("
", "\n", tmp); } - if (!allow_markup) { + if (markup_mode != MARKUP_FULL ) { tmp = notification_strip_markup(tmp); tmp = notification_quote_markup(tmp); } @@ -373,17 +372,17 @@ int notification_init(notification * n, int id) n->msg = string_replace_all("\\n", "\n", g_strdup(n->format)); n->msg = notification_replace_format("%a", n->appname, n->msg, - false, true); + MARKUP_NO); n->msg = notification_replace_format("%s", n->summary, n->msg, - n->allow_markup, n->plain_text); + n->markup); n->msg = notification_replace_format("%b", n->body, n->msg, - n->allow_markup, n->plain_text); + n->markup); if (n->icon) { n->msg = notification_replace_format("%I", basename(n->icon), - n->msg, false, true); + n->msg, MARKUP_NO); n->msg = notification_replace_format("%i", n->icon, - n->msg, false, true); + n->msg, MARKUP_NO); } if (n->progress) { diff --git a/src/notification.h b/src/notification.h index 94639be..ccf2b47 100644 --- a/src/notification.h +++ b/src/notification.h @@ -3,6 +3,7 @@ #define DUNST_NOTIFICATION_H #include "x.h" +#include "settings.h" #define LOW 0 #define NORM 1 @@ -39,8 +40,7 @@ typedef struct _notification { time_t timestamp; int timeout; int urgency; - bool allow_markup; - bool plain_text; + enum markup_mode markup; bool redisplayed; /* has been displayed before? */ int id; int dup_count; diff --git a/src/rules.c b/src/rules.c index d568218..b0d1df4 100644 --- a/src/rules.c +++ b/src/rules.c @@ -15,10 +15,8 @@ void rule_apply(rule_t * r, notification * n) n->timeout = r->timeout; if (r->urgency != -1) 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->markup != -1) + n->markup = r->markup; if (r->new_icon) { if(n->icon) g_free(n->icon); @@ -61,8 +59,7 @@ void rule_init(rule_t * r) r->msg_urgency = -1; r->timeout = -1; r->urgency = -1; - r->allow_markup = -1; - r->plain_text = -1; + r->markup = -1; r->new_icon = NULL; r->fg = NULL; r->bg = NULL; diff --git a/src/rules.h b/src/rules.h index bebe1e0..c800a7c 100644 --- a/src/rules.h +++ b/src/rules.h @@ -6,6 +6,7 @@ #include "dunst.h" #include "notification.h" +#include "settings.h" typedef struct _rule_t { char *name; @@ -20,8 +21,7 @@ typedef struct _rule_t { /* actions */ int timeout; int urgency; - int allow_markup; - int plain_text; + enum markup_mode markup; char *new_icon; char *fg; char *bg; diff --git a/src/settings.c b/src/settings.c index ca0e222..34994ab 100644 --- a/src/settings.c +++ b/src/settings.c @@ -30,7 +30,20 @@ static void parse_follow_mode(const char *mode) fprintf(stderr, "Warning: unknown follow mode: \"%s\"\n", mode); settings.f_mode = FOLLOW_NONE; } +} +static enum markup_mode parse_markup_mode(const char *mode) +{ + if (strcmp(mode, "strip") == 0) { + return MARKUP_STRIP; + } else if (strcmp(mode, "no") == 0) { + return MARKUP_NO; + } else if (strcmp(mode, "full") == 0) { + return MARKUP_FULL; + } else { + fprintf(stderr, "Warning: unknown markup mode: \"%s\"\n", mode); + return MARKUP_NO; + } } static int ini_get_urgency(char *section, char *key, int def) @@ -89,17 +102,16 @@ void load_settings(char *cmdline_config_path) "The font dunst should use." ); - settings.allow_markup = option_get_bool( - "global", - "allow_markup", "-markup", allow_markup, - "Allow markups in notifications/formats." - ); + { + char *c = option_get_string( + "global", + "markup", "-markup", markup, + "Specify how markup should be handled" + ); - settings.plain_text = option_get_bool( - "global", - "plain_text", "-plain", plain_text, - "Treat incoming notifications as plain text." - ); + settings.markup = parse_markup_mode(c); + free(c); + } settings.format = option_get_string( "global", @@ -530,8 +542,19 @@ void load_settings(char *cmdline_config_path) r->icon = ini_get_string(cur_section, "icon", r->icon); r->category = ini_get_string(cur_section, "category", r->category); 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); + + { + char *c = ini_get_string( + cur_section, + "markup", "" + ); + + if (strlen(c) > 0) { + r->markup = parse_markup_mode(c); + free(c); + } + } + r->urgency = ini_get_urgency(cur_section, "urgency", r->urgency); r->msg_urgency = ini_get_urgency(cur_section, "msg_urgency", r->msg_urgency); r->fg = ini_get_string(cur_section, "foreground", r->fg); diff --git a/src/settings.h b/src/settings.h index eb780b6..a1b7f89 100644 --- a/src/settings.h +++ b/src/settings.h @@ -6,11 +6,11 @@ enum alignment { left, center, right }; enum icon_position_t { icons_left, icons_right, icons_off }; enum separator_color { FOREGROUND, AUTO, FRAME, CUSTOM }; enum follow_mode { FOLLOW_NONE, FOLLOW_MOUSE, FOLLOW_KEYBOARD }; +enum markup_mode { MARKUP_NO, MARKUP_STRIP, MARKUP_FULL }; typedef struct _settings { bool print_notifications; - bool allow_markup; - bool plain_text; + enum markup_mode markup; bool stack_duplicates; bool hide_duplicates_count; char *font;