32528
|
1
|
|
2 #include <gtk/gtk.h>
|
|
3 #include "smileyparser.h"
|
|
4 #include <smiley.h>
|
|
5 #include <string.h>
|
|
6 #include "gtkthemes.h"
|
|
7
|
|
8 static char* get_fullpath (const char* filename)
|
|
9 {
|
|
10 if (g_path_is_absolute (filename)) return g_strdup (filename);
|
|
11 else return g_build_path (g_get_current_dir (), filename, NULL);
|
|
12 }
|
|
13
|
|
14 static void
|
|
15 parse_for_shortcut_plaintext (const char* text, const char* shortcut, const char* file, GString* ret)
|
|
16 {
|
|
17 const char *tmp = text;
|
|
18
|
|
19 for(;*tmp;) {
|
|
20 const char *end = strstr (tmp, shortcut);
|
|
21 char *path;
|
|
22 char *escaped_path;
|
|
23
|
|
24 if (end == NULL) {
|
|
25 g_string_append (ret, tmp);
|
|
26 break;
|
|
27 }
|
|
28 path = get_fullpath (file);
|
|
29 escaped_path = g_markup_escape_text (path, -1);
|
|
30
|
|
31 g_string_append_len (ret, tmp, end-tmp);
|
|
32 g_string_append_printf (ret,"<img alt='%s' src='%s' />",
|
|
33 shortcut, escaped_path);
|
|
34 g_free (path);
|
|
35 g_free (escaped_path);
|
|
36 g_assert (strlen (tmp) >= strlen (shortcut));
|
|
37 tmp = end + strlen (shortcut);
|
|
38 }
|
|
39 }
|
|
40
|
|
41 static char*
|
|
42 parse_for_shortcut (const char* markup, const char* shortcut, const char* file)
|
|
43 {
|
|
44 GString* ret = g_string_new ("");
|
|
45 char *local_markup = g_strdup (markup);
|
|
46 char *escaped_shortcut = g_markup_escape_text (shortcut, -1);
|
|
47
|
|
48 char *temp = local_markup;
|
|
49
|
|
50 for (;*temp;) {
|
|
51 char *end = strchr (temp, '<');
|
|
52 char *end_of_tag;
|
|
53
|
|
54 if (!end) {
|
|
55 parse_for_shortcut_plaintext (temp, escaped_shortcut, file, ret);
|
|
56 break;
|
|
57 }
|
|
58
|
|
59 *end = 0;
|
|
60 parse_for_shortcut_plaintext (temp, escaped_shortcut, file, ret);
|
|
61 *end = '<';
|
|
62
|
|
63 /* if this is well-formed, then there should be no '>' within
|
|
64 * the tag. TODO: handle a comment tag better :( */
|
|
65 end_of_tag = strchr (end, '>');
|
|
66 if (!end_of_tag) {
|
|
67 g_string_append (ret, end);
|
|
68 break;
|
|
69 }
|
|
70
|
|
71 g_string_append_len (ret, end, end_of_tag-end+1);
|
|
72
|
|
73 temp = end_of_tag + 1;
|
|
74 }
|
|
75 g_free (local_markup);
|
|
76 g_free (escaped_shortcut);
|
|
77 return g_string_free (ret, FALSE);
|
|
78 }
|
|
79
|
|
80 static char*
|
|
81 parse_for_purple_smiley (const char* markup, PurpleSmiley *smiley)
|
|
82 {
|
|
83 char *file = purple_smiley_get_full_path (smiley);
|
|
84 char *ret = parse_for_shortcut (markup, purple_smiley_get_shortcut (smiley), file);
|
|
85 g_free (file);
|
|
86 return ret;
|
|
87 }
|
|
88
|
|
89 static char*
|
|
90 parse_for_smiley_list (const char* markup, GHashTable* smileys)
|
|
91 {
|
|
92 GHashTableIter iter;
|
|
93 char *key, *value;
|
|
94 char *ret = g_strdup (markup);
|
|
95
|
|
96 g_hash_table_iter_init (&iter, smileys);
|
|
97 while (g_hash_table_iter_next (&iter, (gpointer*)&key, (gpointer*)&value))
|
|
98 {
|
|
99 char* temp = parse_for_shortcut (ret, key, value);
|
|
100 g_free (ret);
|
|
101 ret = temp;
|
|
102 }
|
|
103 return ret;
|
|
104 }
|
|
105
|
|
106 char*
|
|
107 smiley_parse_markup (const char* markup, const char *proto_id)
|
|
108 {
|
|
109 GList *smileys = purple_smileys_get_all ();
|
|
110 char *temp = g_strdup (markup), *temp2;
|
|
111 struct smiley_list *list;
|
|
112 const char *proto_name = "default";
|
|
113
|
|
114 if (proto_id != NULL) {
|
|
115 PurplePlugin *proto;
|
|
116 proto = purple_find_prpl (proto_id);
|
|
117 proto_name = proto->info->name;
|
|
118 }
|
|
119
|
|
120 /* unnecessarily slow, but lets manage for now. */
|
|
121 for (; smileys; smileys = g_list_next (smileys)) {
|
|
122 temp2 = parse_for_purple_smiley (temp, PURPLE_SMILEY (smileys->data));
|
|
123 g_free (temp);
|
|
124 temp = temp2;
|
|
125 }
|
|
126
|
|
127 /* now for each theme smiley, observe that this does look nasty */
|
|
128
|
|
129 if (!current_smiley_theme || !(current_smiley_theme->list)) {
|
|
130 printf ("theme does not exist\n");
|
|
131 return temp;
|
|
132 }
|
|
133
|
|
134 for (list = current_smiley_theme->list; list; list = list->next) {
|
|
135 if (g_str_equal (list->sml, proto_name)) {
|
|
136 temp2 = parse_for_smiley_list (temp, list->files);
|
|
137 g_free (temp);
|
|
138 temp = temp2;
|
|
139 }
|
|
140 }
|
|
141
|
|
142 return temp;
|
|
143 }
|
|
144
|