pidgin/smileyparser.c

branch
soc.2013.gobjectification.plugins
changeset 37133
832cd077145e
parent 37132
f4740b6e7525
parent 35788
afa6d777bc7c
child 37134
07746c9a04bf
equal deleted inserted replaced
37132:f4740b6e7525 37133:832cd077145e
1 /* pidgin
2 *
3 * Pidgin is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
5 * source distribution.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
20 *
21 */
22
23 #include <gtk/gtk.h>
24 #include <debug.h>
25 #include "smileyparser.h"
26 #include <smiley.h>
27 #include <string.h>
28 #include "gtkthemes.h"
29
30 static char *
31 get_fullpath(const char *filename)
32 {
33 if (g_path_is_absolute(filename))
34 return g_strdup(filename);
35 else
36 return g_build_path(g_get_current_dir(), filename, NULL);
37 }
38
39 static void
40 parse_for_shortcut_plaintext(const char *text, const char *shortcut, const char *file, GString *ret)
41 {
42 const char *tmp = text;
43
44 for (;*tmp;) {
45 const char *end = strstr(tmp, shortcut);
46 char *path;
47 char *escaped_path;
48
49 if (end == NULL) {
50 g_string_append(ret, tmp);
51 break;
52 }
53 path = get_fullpath(file);
54 escaped_path = g_markup_escape_text(path, -1);
55
56 g_string_append_len(ret, tmp, end-tmp);
57 g_string_append_printf(ret,"<img alt='%s' src='%s' />",
58 shortcut, escaped_path);
59 g_free(path);
60 g_free(escaped_path);
61 g_assert(strlen(tmp) >= strlen(shortcut));
62 tmp = end + strlen(shortcut);
63 }
64 }
65
66 static char *
67 parse_for_shortcut(const char *markup, const char *shortcut, const char *file)
68 {
69 GString* ret = g_string_new("");
70 char *local_markup = g_strdup(markup);
71 char *escaped_shortcut = g_markup_escape_text(shortcut, -1);
72
73 char *temp = local_markup;
74
75 for (;*temp;) {
76 char *end = strchr(temp, '<');
77 char *end_of_tag;
78
79 if (!end) {
80 parse_for_shortcut_plaintext(temp, escaped_shortcut, file, ret);
81 break;
82 }
83
84 *end = 0;
85 parse_for_shortcut_plaintext(temp, escaped_shortcut, file, ret);
86 *end = '<';
87
88 /* if this is well-formed, then there should be no '>' within
89 * the tag. TODO: handle a comment tag better :( */
90 end_of_tag = strchr(end, '>');
91 if (!end_of_tag) {
92 g_string_append(ret, end);
93 break;
94 }
95
96 g_string_append_len(ret, end, end_of_tag - end + 1);
97
98 temp = end_of_tag + 1;
99 }
100 g_free(local_markup);
101 g_free(escaped_shortcut);
102 return g_string_free(ret, FALSE);
103 }
104
105 static char *
106 parse_for_purple_smiley(const char *markup, PurpleSmiley *smiley)
107 {
108 char *file = purple_smiley_get_full_path(smiley);
109 char *ret = parse_for_shortcut(markup, purple_smiley_get_shortcut(smiley), file);
110 g_free(file);
111 return ret;
112 }
113
114 static char *
115 parse_for_smiley_list(const char *markup, GHashTable *smileys)
116 {
117 GHashTableIter iter;
118 char *key, *value;
119 char *ret = g_strdup(markup);
120
121 g_hash_table_iter_init(&iter, smileys);
122 while (g_hash_table_iter_next(&iter, (gpointer *)&key, (gpointer *)&value))
123 {
124 char *temp = parse_for_shortcut(ret, key, value);
125 g_free(ret);
126 ret = temp;
127 }
128
129 return ret;
130 }
131
132 char *
133 pidgin_smiley_parse_markup(const char *markup, const char *proto_id)
134 {
135 GList *smileys = purple_smileys_get_all();
136 char *temp = g_strdup(markup), *temp2;
137 struct PidginSmileyList *list;
138 const char *proto_name = "default";
139
140 if (proto_id != NULL) {
141 PurpleProtocol *protocol;
142 protocol = purple_protocols_find(proto_id);
143 proto_name = purple_protocol_get_name(protocol);
144 }
145
146 /* unnecessarily slow, but lets manage for now. */
147 for (; smileys; smileys = g_list_next(smileys)) {
148 temp2 = parse_for_purple_smiley(temp, PURPLE_SMILEY(smileys->data));
149 g_free(temp);
150 temp = temp2;
151 }
152
153 /* now for each theme smiley, observe that this does look nasty */
154 if (!current_smiley_theme) {
155 purple_debug_warning("smiley", "theme does not exist\n");
156 return temp;
157 }
158
159 for (list = current_smiley_theme->list; list; list = list->next) {
160 if (g_str_equal(list->sml, "default") ||
161 g_str_equal(list->sml, proto_name))
162 {
163 temp2 = parse_for_smiley_list(temp, list->files);
164 g_free(temp);
165 temp = temp2;
166 }
167 }
168
169 return temp;
170 }
171

mercurial