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-*-*-*-*-*-*-*"; | ||||
| bool allow_markup = false; | ||||
| bool plain_text = true; | ||||
| char *normbgcolor = "#1793D1"; | ||||
| char *normfgcolor = "#DDDDDD"; | ||||
| char *critbgcolor = "#ffaaaa"; | ||||
| @ -90,11 +91,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,  fg,    bg,        format,  script */ | ||||
|         {    "empty", NULL,           NULL,            NULL,  NULL, NULL, -1,          -1,       -1,       NULL,  NULL,      NULL,    NULL}, | ||||
|         /* { "rule1", "notify-send",  NULL,            NULL,  NULL, NULL, -1,          -1,       -1,       NULL,  NULL,      "%s %b", NULL }, */ | ||||
|         /* { "rule2", "Pidgin",       "*says*,         NULL,  NULL, NULL, -1,          -1,       CRITICAL, NULL,  NULL,      NULL,    NULL    }, */ | ||||
|         /* { "rule3", "Pidgin",       "*signed on*",   NULL,  NULL, NULL, -1,          -1,       LOW,      NULL,  NULL,      NULL,    NULL    }, */ | ||||
|         /* { "rule4", "Pidgin",       "*signed off*",  NULL,  NULL, NULL, -1,          -1,       LOW,      NULL,  NULL,      NULL,    NULL    }, */ | ||||
|         /* { "rule5", NULL,           "*foobar*",      NULL,  NULL, NULL, -1,          -1,       -1,       NULL,  "#00FF00", NULL,    NULL }, */ | ||||
|         /*   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 }, */ | ||||
| }; | ||||
|  | ||||
							
								
								
									
										3
									
								
								dbus.c
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								dbus.c
									
									
									
									
									
								
							| @ -9,6 +9,7 @@ | ||||
| #include "dbus.h" | ||||
| #include "notification.h" | ||||
| #include "utils.h" | ||||
| #include "settings.h" | ||||
| 
 | ||||
| GDBusConnection *dbus_conn; | ||||
| 
 | ||||
| @ -283,6 +284,8 @@ static void onNotify(GDBusConnection * connection, | ||||
|         n->body = body; | ||||
|         n->icon = icon; | ||||
|         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->urgency = urgency; | ||||
|         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->progress = 0; | ||||
|                 n->timeout = 10; | ||||
|                 n->allow_markup = false; | ||||
|                 n->plain_text = true; | ||||
|                 n->urgency = LOW; | ||||
|                 n->icon = NULL; | ||||
|                 n->category = NULL; | ||||
|  | ||||
							
								
								
									
										5
									
								
								dunstrc
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								dunstrc
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | ||||
| [global] | ||||
|     font = Monospace 8 | ||||
| 
 | ||||
|     # Allow a small subset of html markup: | ||||
|     # Allow a small subset of html markup in notifications and formats: | ||||
|     #   <b>bold</b> | ||||
|     #   <i>italic</i> | ||||
|     #   <s>strikethrough</s> | ||||
| @ -13,6 +13,9 @@ | ||||
|     # message. | ||||
|     allow_markup = yes | ||||
| 
 | ||||
|     # Treat incoming notifications as plain text | ||||
|     plain_text = no | ||||
| 
 | ||||
|     # The format of the message.  Possible variables are: | ||||
|     #   %a  appname | ||||
|     #   %s  summary | ||||
|  | ||||
| @ -161,8 +161,7 @@ void notification_free(notification * n) | ||||
|         /*
 | ||||
|          * Strip any markup from text | ||||
|          */ | ||||
| 
 | ||||
| char *notification_fix_markup(char *str) | ||||
| char *notification_strip_markup(char *str) | ||||
| { | ||||
|         char *replace_buf, *start, *end; | ||||
| 
 | ||||
| @ -210,9 +209,62 @@ char *notification_fix_markup(char *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 *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) | ||||
| { | ||||
| 
 | ||||
|         if (n == NULL) | ||||
|                 return -1; | ||||
| 
 | ||||
| @ -282,35 +333,29 @@ int notification_init(notification * n, int id) | ||||
| 
 | ||||
|         n->urls = notification_extract_markup_urls(&(n->body)); | ||||
| 
 | ||||
|         n->msg = string_replace("%a", n->appname, g_strdup(n->format)); | ||||
|         n->msg = string_replace("%s", n->summary, n->msg); | ||||
|         n->msg = string_replace_all("\\n", "\n", g_strdup(n->format)); | ||||
|         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) { | ||||
|                 n->msg = string_replace("%I", basename(n->icon), n->msg); | ||||
|                 n->msg = string_replace("%i", n->icon, n->msg); | ||||
|                 n->msg = notification_replace_format("%I", basename(n->icon), | ||||
|                         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) { | ||||
|                 char pg[10]; | ||||
|                 sprintf(pg, "[%3d%%]", n->progress - 1); | ||||
|                 n->msg = string_replace("%p", pg, n->msg); | ||||
|                 n->msg = string_replace_all("%p", pg, n->msg); | ||||
|         } 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); | ||||
| 
 | ||||
|         if (id == 0) { | ||||
|  | ||||
| @ -27,6 +27,8 @@ typedef struct _notification { | ||||
|         time_t timestamp; | ||||
|         int timeout; | ||||
|         int urgency; | ||||
|         bool allow_markup; | ||||
|         bool plain_text; | ||||
|         bool redisplayed;       /* has been displayed before? */ | ||||
|         int id; | ||||
|         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); | ||||
| int notification_close(notification * n, int reason); | ||||
| 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); | ||||
| int notification_get_ttl(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; | ||||
|         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->new_icon) | ||||
|                 n->icon = r->new_icon; | ||||
|         if (r->fg) | ||||
| @ -54,6 +58,8 @@ 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->new_icon = NULL; | ||||
|         r->fg = NULL; | ||||
|         r->bg = NULL; | ||||
| @ -65,7 +71,6 @@ void rule_init(rule_t * r) | ||||
|  */ | ||||
| bool rule_matches_notification(rule_t * r, notification * n) | ||||
| { | ||||
| 
 | ||||
|         return ((!r->appname || !fnmatch(r->appname, n->appname, 0)) | ||||
|                 && (!r->summary || !fnmatch(r->summary, n->summary, 0)) | ||||
|                 && (!r->body || !fnmatch(r->body, n->body, 0)) | ||||
|  | ||||
							
								
								
									
										2
									
								
								rules.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								rules.h
									
									
									
									
									
								
							| @ -19,6 +19,8 @@ typedef struct _rule_t { | ||||
|         /* actions */ | ||||
|         int timeout; | ||||
|         int urgency; | ||||
|         int allow_markup; | ||||
|         int plain_text; | ||||
|         char *new_icon; | ||||
|         char *fg; | ||||
|         char *bg; | ||||
|  | ||||
| @ -85,7 +85,10 @@ 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."); | ||||
|                                 "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 = | ||||
|             option_get_string("global", "format", "-format", format, | ||||
|                               "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->icon = ini_get_string(cur_section, "icon", r->icon); | ||||
|                 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->msg_urgency = ini_get_urgency(cur_section, "msg_urgency", r->msg_urgency); | ||||
|                 r->fg = ini_get_string(cur_section, "foreground", r->fg); | ||||
|  | ||||
| @ -4,6 +4,7 @@ | ||||
| typedef struct _settings { | ||||
|         bool print_notifications; | ||||
|         bool allow_markup; | ||||
|         bool plain_text; | ||||
|         bool stack_duplicates; | ||||
|         char *font; | ||||
|         char *normbgcolor; | ||||
|  | ||||
							
								
								
									
										59
									
								
								utils.c
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								utils.c
									
									
									
									
									
								
							| @ -17,39 +17,56 @@ char *string_replace_char(char needle, char replacement, char *haystack) { | ||||
|     return haystack; | ||||
| } | ||||
| 
 | ||||
| char *string_replace_all(const char *needle, const char *replacement, | ||||
|                          char *haystack) | ||||
| char *string_replace_at(char *buf, int pos, int len, const char *repl) | ||||
| { | ||||
|         char *start; | ||||
|         start = strstr(haystack, needle); | ||||
|         while (start != NULL) { | ||||
|                 haystack = string_replace(needle, replacement, haystack); | ||||
|                 start = strstr(haystack, needle); | ||||
|         } | ||||
|         return haystack; | ||||
|         char *tmp; | ||||
|         int size, buf_len, repl_len; | ||||
| 
 | ||||
|         buf_len = strlen(buf); | ||||
|         repl_len = strlen(repl); | ||||
|         size = (buf_len - len) + repl_len + 1; | ||||
|         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 *haystack) | ||||
| char *string_replace(const char *needle, const char *replacement, char *haystack) | ||||
| { | ||||
|         char *tmp, *start; | ||||
|         int size; | ||||
|         char *start; | ||||
|         start = strstr(haystack, needle); | ||||
|         if (start == NULL) { | ||||
|                 return haystack; | ||||
|         } | ||||
| 
 | ||||
|         size = (strlen(haystack) - strlen(needle)) + strlen(replacement) + 1; | ||||
|         tmp = calloc(sizeof(char), size); | ||||
|         memset(tmp, '\0', size); | ||||
|         return string_replace_at(haystack, (start - haystack), strlen(needle), replacement); | ||||
| } | ||||
| 
 | ||||
|         strncpy(tmp, haystack, start - haystack); | ||||
|         tmp[start - haystack] = '\0'; | ||||
| char *string_replace_all(const char *needle, const char *replacement, | ||||
|     char *haystack) | ||||
| { | ||||
|         char *start; | ||||
|         int needle_pos; | ||||
|         int needle_len, repl_len; | ||||
| 
 | ||||
|         sprintf(tmp + strlen(tmp), "%s%s", replacement, start + strlen(needle)); | ||||
|         free(haystack); | ||||
|         needle_len = strlen(needle); | ||||
|         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) | ||||
|  | ||||
							
								
								
									
										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); | ||||
|         } else { | ||||
|                 /* 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->attr = NULL; | ||||
|                 pango_layout_set_text(cl->l, n->text_to_render, -1); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Sascha Kruse
						Sascha Kruse