Merge pull request #309 from LukeShu/tidy-markup
Tidy and fix markup handling.
This commit is contained in:
		
						commit
						96ebb4625a
					
				
							
								
								
									
										110
									
								
								src/markup.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								src/markup.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,110 @@ | ||||
| /* copyright 2013 Sascha Kruse and contributors (see LICENSE for licensing information) */ | ||||
| 
 | ||||
| #define _GNU_SOURCE | ||||
| #include "markup.h" | ||||
| 
 | ||||
| #include <assert.h> | ||||
| #include <stdbool.h> | ||||
| 
 | ||||
| #include "settings.h" | ||||
| #include "utils.h" | ||||
| 
 | ||||
| static char *markup_quote(char *str) | ||||
| { | ||||
|         assert(str != 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; | ||||
| } | ||||
| 
 | ||||
| static char *markup_unquote(char *str) | ||||
| { | ||||
|         assert(str != 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; | ||||
| } | ||||
| 
 | ||||
| static char *markup_br2nl(char *str) | ||||
| { | ||||
|         assert(str != NULL); | ||||
| 
 | ||||
|         str = string_replace_all("<br>", "\n", str); | ||||
|         str = string_replace_all("<br/>", "\n", str); | ||||
|         str = string_replace_all("<br />", "\n", str); | ||||
|         return str; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Strip any markup from text; turn it in to plain text. | ||||
|  * | ||||
|  * For well-formed markup, the following two commands should be | ||||
|  * roughly equivalent: | ||||
|  * | ||||
|  *     out = markup_strip(in); | ||||
|  *     pango_parse_markup(in, -1, 0, NULL, &out, NULL, NULL); | ||||
|  * | ||||
|  * However, `pango_parse_markup()` balks at invalid markup; | ||||
|  * `markup_strip()` shouldn't care if there is invalid markup. | ||||
|  */ | ||||
| char *markup_strip(char *str) | ||||
| { | ||||
|         if (str == NULL) { | ||||
|                 return NULL; | ||||
|         } | ||||
| 
 | ||||
|         /* strip all tags */ | ||||
|         string_strip_delimited(str, '<', '>'); | ||||
| 
 | ||||
|         /* unquote the remainder */ | ||||
|         str = markup_unquote(str); | ||||
| 
 | ||||
|         return str; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Transform the string in accordance with `markup_mode` and | ||||
|  * `settings.ignore_newline` | ||||
|  */ | ||||
| char *markup_transform(char *str, enum markup_mode markup_mode) | ||||
| { | ||||
|         if (str == NULL) { | ||||
|                 return NULL; | ||||
|         } | ||||
| 
 | ||||
|         switch (markup_mode) { | ||||
|         case MARKUP_NULL: | ||||
|                 /* `assert(false)`, but with a meaningful error message */ | ||||
|                 assert(markup_mode != MARKUP_NULL); | ||||
|                 break; | ||||
|         case MARKUP_NO: | ||||
|                 str = markup_quote(str); | ||||
|                 break; | ||||
|         case MARKUP_STRIP: | ||||
|                 str = markup_br2nl(str); | ||||
|                 str = markup_strip(str); | ||||
|                 str = markup_quote(str); | ||||
|                 break; | ||||
|         case MARKUP_FULL: | ||||
|                 str = markup_br2nl(str); | ||||
|                 break; | ||||
|         } | ||||
| 
 | ||||
|         if (settings.ignore_newline) { | ||||
|                 str = string_replace_all("\n", " ", str); | ||||
|         } | ||||
| 
 | ||||
|         return str; | ||||
| } | ||||
| 
 | ||||
| /* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */ | ||||
							
								
								
									
										11
									
								
								src/markup.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/markup.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| /* copyright 2013 Sascha Kruse and contributors (see LICENSE for licensing information) */ | ||||
| #ifndef DUNST_MARKUP_H | ||||
| #define DUNST_MARKUP_H | ||||
| 
 | ||||
| #include "settings.h" | ||||
| 
 | ||||
| char *markup_strip(char *str); | ||||
| char *markup_transform(char *str, enum markup_mode markup_mode); | ||||
| 
 | ||||
| #endif | ||||
| /* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */ | ||||
| @ -16,6 +16,7 @@ | ||||
| 
 | ||||
| #include "dbus.h" | ||||
| #include "dunst.h" | ||||
| #include "markup.h" | ||||
| #include "menu.h" | ||||
| #include "rules.h" | ||||
| #include "settings.h" | ||||
| @ -196,46 +197,6 @@ void notification_free(notification * n) | ||||
|         g_free(n); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Strip any markup from text | ||||
|  */ | ||||
| char *notification_strip_markup(char *str) | ||||
| { | ||||
|         if (str == NULL) { | ||||
|                 return NULL; | ||||
|         } | ||||
| 
 | ||||
|         /* strip all tags */ | ||||
|         string_strip_delimited(str, '<', '>'); | ||||
| 
 | ||||
|         /* unquote the remainder */ | ||||
|         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; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * 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 markup settings. | ||||
| @ -245,32 +206,7 @@ char *notification_replace_format(const char *needle, const char *replacement, | ||||
|         char* tmp; | ||||
|         char* ret; | ||||
| 
 | ||||
|         if (markup_mode == MARKUP_NO) { | ||||
|                 tmp = g_strdup(replacement); | ||||
|                 tmp = notification_quote_markup(tmp); | ||||
|         } else { | ||||
|                 tmp = g_strdup(replacement); | ||||
|                 if (settings.ignore_newline) { | ||||
|                         tmp = string_replace_all("<br>", " ", tmp); | ||||
|                         tmp = string_replace_all("<br/>", " ", tmp); | ||||
|                         tmp = string_replace_all("<br />", " ", tmp); | ||||
|                 } else { | ||||
|                         tmp = string_replace_all("<br>", "\n", tmp); | ||||
|                         tmp = string_replace_all("<br/>", "\n", tmp); | ||||
|                         tmp = string_replace_all("<br />", "\n", tmp); | ||||
|                 } | ||||
| 
 | ||||
|                 if (markup_mode != MARKUP_FULL ) { | ||||
|                         tmp = notification_strip_markup(tmp); | ||||
|                         tmp = notification_quote_markup(tmp); | ||||
|                 } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         if (settings.ignore_newline) { | ||||
|                 tmp = string_replace_all("\n", " ", tmp); | ||||
|         } | ||||
| 
 | ||||
|         tmp = markup_transform(g_strdup(replacement), markup_mode); | ||||
|         ret = string_replace_all(needle, tmp, haystack); | ||||
|         g_free(tmp); | ||||
| 
 | ||||
|  | ||||
| @ -69,8 +69,6 @@ int notification_is_duplicate(const notification *a, const notification *b); | ||||
| void notification_run_script(notification * n); | ||||
| int notification_close(notification * n, int reason); | ||||
| void notification_print(notification * n); | ||||
| char *notification_strip_markup(char *str); | ||||
| char *notification_quote_markup(char *str); | ||||
| char *notification_replace_format(const char *needle, const char *replacement, char *haystack, enum markup_mode markup); | ||||
| void notification_update_text_to_render(notification *n); | ||||
| int notification_get_ttl(notification *n); | ||||
|  | ||||
							
								
								
									
										3
									
								
								src/x.c
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								src/x.c
									
									
									
									
									
								
							| @ -22,6 +22,7 @@ | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| #include "dunst.h" | ||||
| #include "markup.h" | ||||
| #include "notification.h" | ||||
| #include "settings.h" | ||||
| #include "utils.h" | ||||
| @ -475,7 +476,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_strip_markup(n->text_to_render); | ||||
|                 n->text_to_render = markup_strip(n->text_to_render); | ||||
|                 cl->text = NULL; | ||||
|                 cl->attr = NULL; | ||||
|                 pango_layout_set_text(cl->l, n->text_to_render, -1); | ||||
|  | ||||
							
								
								
									
										57
									
								
								test/markup.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								test/markup.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | ||||
| #include "greatest.h" | ||||
| 
 | ||||
| #include <stdbool.h> | ||||
| #include <glib.h> | ||||
| 
 | ||||
| #include "src/markup.h" | ||||
| 
 | ||||
| TEST test_markup_strip(void) | ||||
| { | ||||
|         char *ptr; | ||||
| 
 | ||||
|         ASSERT_STR_EQ(""", (ptr=markup_strip(g_strdup("&quot;")))); | ||||
|         g_free(ptr); | ||||
|         ASSERT_STR_EQ("'", (ptr=markup_strip(g_strdup("&apos;")))); | ||||
|         g_free(ptr); | ||||
|         ASSERT_STR_EQ("<", (ptr=markup_strip(g_strdup("&lt;")))); | ||||
|         g_free(ptr); | ||||
|         ASSERT_STR_EQ(">", (ptr=markup_strip(g_strdup("&gt;")))); | ||||
|         g_free(ptr); | ||||
|         ASSERT_STR_EQ("&", (ptr=markup_strip(g_strdup("&amp;")))); | ||||
|         g_free(ptr); | ||||
|         ASSERT_STR_EQ(">A  ", (ptr=markup_strip(g_strdup(">A <img> <string")))); | ||||
|         g_free(ptr); | ||||
| 
 | ||||
|         PASS(); | ||||
| } | ||||
| 
 | ||||
| TEST test_markup_transform(void) | ||||
| { | ||||
|         char *ptr; | ||||
| 
 | ||||
|         settings.ignore_newline = false; | ||||
|         ASSERT_STR_EQ("<i>foo</i><br>bar\nbaz", (ptr=markup_transform(g_strdup("<i>foo</i><br>bar\nbaz"), MARKUP_NO))); | ||||
|         g_free(ptr); | ||||
|         ASSERT_STR_EQ("foo\nbar\nbaz", (ptr=markup_transform(g_strdup("<i>foo</i><br>bar\nbaz"), MARKUP_STRIP))); | ||||
|         g_free(ptr); | ||||
|         ASSERT_STR_EQ("<i>foo</i>\nbar\nbaz", (ptr=markup_transform(g_strdup("<i>foo</i><br>bar\nbaz"), MARKUP_FULL))); | ||||
|         g_free(ptr); | ||||
| 
 | ||||
|         settings.ignore_newline = true; | ||||
|         ASSERT_STR_EQ("<i>foo</i><br>bar baz", (ptr=markup_transform(g_strdup("<i>foo</i><br>bar\nbaz"), MARKUP_NO))); | ||||
|         g_free(ptr); | ||||
|         ASSERT_STR_EQ("foo bar baz", (ptr=markup_transform(g_strdup("<i>foo</i><br>bar\nbaz"), MARKUP_STRIP))); | ||||
|         g_free(ptr); | ||||
|         ASSERT_STR_EQ("<i>foo</i> bar baz", (ptr=markup_transform(g_strdup("<i>foo</i><br>bar\nbaz"), MARKUP_FULL))); | ||||
|         g_free(ptr); | ||||
| 
 | ||||
|         PASS(); | ||||
| } | ||||
| 
 | ||||
| SUITE(suite_markup) | ||||
| { | ||||
|         RUN_TEST(test_markup_strip); | ||||
|         RUN_TEST(test_markup_transform); | ||||
| } | ||||
| 
 | ||||
| /* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */ | ||||
| @ -3,6 +3,7 @@ | ||||
| SUITE_EXTERN(suite_utils); | ||||
| SUITE_EXTERN(suite_option_parser); | ||||
| SUITE_EXTERN(suite_notification); | ||||
| SUITE_EXTERN(suite_markup); | ||||
| 
 | ||||
| GREATEST_MAIN_DEFS(); | ||||
| 
 | ||||
| @ -11,6 +12,7 @@ int main(int argc, char *argv[]) { | ||||
|         RUN_SUITE(suite_utils); | ||||
|         RUN_SUITE(suite_option_parser); | ||||
|         RUN_SUITE(suite_notification); | ||||
|         RUN_SUITE(suite_markup); | ||||
|         GREATEST_MAIN_END(); | ||||
| } | ||||
| /* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Nikos Tsipinakis
						Nikos Tsipinakis