]> git.0d.be Git - empathy.git/blobdiff - libempathy-gtk/empathy-theme-adium.c
add myself to AUTHORS
[empathy.git] / libempathy-gtk / empathy-theme-adium.c
index 78a218ad60f3e6ea4fee1b8223351fb0bfd9ad0f..0a9fb98301edbf08dfc8d9fc005061a9a182e17a 100644 (file)
@@ -192,11 +192,13 @@ theme_adium_open_address_cb (GtkMenuItem *menuitem,
 }
 
 static void
-theme_adium_parser_newline (GString *string,
-                           const gchar *text,
-                           gssize len,
-                           gpointer user_data)
+theme_adium_match_newline (const gchar *text,
+                          gssize len,
+                          EmpathyStringReplace replace_func,
+                          EmpathyStringParser *sub_parsers,
+                          gpointer user_data)
 {
+       GString *string = user_data;
        gint i;
        gint prev = 0;
 
@@ -207,97 +209,106 @@ theme_adium_parser_newline (GString *string,
        /* Replace \n by <br/> */
        for (i = 0; i < len && text[i] != '\0'; i++) {
                if (text[i] == '\n') {
-                       empathy_string_parser_substr (string, text + prev,
-                                                     i - prev, user_data);
+                       empathy_string_parser_substr (text + prev,
+                                                     i - prev, sub_parsers,
+                                                     user_data);
                        g_string_append (string, "<br/>");
                        prev = i + 1;
                }
        }
-       empathy_string_parser_substr (string, text + prev, i - prev, user_data);
+       empathy_string_parser_substr (text + prev, i - prev,
+                                     sub_parsers, user_data);
 }
 
-static gboolean use_smileys = FALSE;
-
 static void
-theme_adium_parser_smiley (GString *string,
-                          const gchar *text,
-                          gssize len,
-                          gpointer user_data)
+theme_adium_replace_link (const gchar *text,
+                         gssize len,
+                         gpointer match_data,
+                         gpointer user_data)
 {
-       guint last = 0;
+       GString *string = user_data;
+       gchar *real_url;
+       gchar *escaped;
 
-       if (use_smileys) {
-               EmpathySmileyManager *smiley_manager;
-               GSList *hits, *l;
+       real_url = empathy_make_absolute_url_len (text, len);
 
-               smiley_manager = empathy_smiley_manager_dup_singleton ();
-               hits = empathy_smiley_manager_parse_len (smiley_manager, text, len);
+       /* The thing we are making a link of may contain
+        * characters which need escaping */
+       escaped = g_markup_escape_text (text, len);
 
-               for (l = hits; l; l = l->next) {
-                       EmpathySmileyHit *hit = l->data;
+       /* Append the link inside <a href=""></a> tag */
+       g_string_append_printf (string, "<a href=\"%s\">%s</a>",
+                               real_url, escaped);
 
-                       if (hit->start > last) {
-                               /* Append the text between last smiley (or the
-                                * start of the message) and this smiley */
-                               empathy_string_parser_substr (string, text + last,
-                                                             hit->start - last,
-                                                             user_data);
-                       }
+       g_free (real_url);
+       g_free (escaped);
+}
 
-                       /* Replace smileys by a <img/> tag */
-                       g_string_append (string, "<abbr title=\"");
-                       g_string_append_len (string, text + hit->start,
-                                            hit->end - hit->start);
-                       g_string_append_printf (string, "\"><img src=\"%s\" alt=\"",
-                                               hit->path);
-                       g_string_append_len (string, text + hit->start,
-                                            hit->end - hit->start);
-                       g_string_append (string, "\"/></abbr>");
+static void
+theme_adium_replace_smiley (const gchar *text,
+                           gssize len,
+                           gpointer match_data,
+                           gpointer user_data)
+{
+       EmpathySmileyHit *hit = match_data;
+       GString *string = user_data;
 
-                       last = hit->end;
+       /* Replace smiley by a <img/> tag */
+       g_string_append_printf (string,
+                               "<img src=\"%s\" alt=\"%.*s\" title=\"%.*s\"/>",
+                               hit->path, (int)len, text, (int)len, text);
+}
 
-                       empathy_smiley_hit_free (hit);
-               }
-               g_slist_free (hits);
-               g_object_unref (smiley_manager);
-       }
+static void
+theme_adium_replace_escaped (const gchar *text,
+                            gssize len,
+                            gpointer match_data,
+                            gpointer user_data)
+{
+       GString *string = user_data;
+       gchar *escaped;
 
-       empathy_string_parser_substr (string, text + last, len - last, user_data);
+       escaped = g_markup_escape_text (text, len);
+       g_string_append (string, escaped);
+       g_free (escaped);
 }
 
 static EmpathyStringParser string_parsers[] = {
-       empathy_string_parser_link,
-       theme_adium_parser_smiley,
-       theme_adium_parser_newline,
-       empathy_string_parser_escape,
-       NULL,
+       {empathy_string_match_link, theme_adium_replace_link},
+       {theme_adium_match_newline, NULL},
+       {empathy_string_match_all, theme_adium_replace_escaped},
+       {NULL, NULL}
+};
+
+static EmpathyStringParser string_parsers_with_smiley[] = {
+       {empathy_string_match_link, theme_adium_replace_link},
+       {empathy_string_match_smiley, theme_adium_replace_smiley},
+       {theme_adium_match_newline, NULL},
+       {empathy_string_match_all, theme_adium_replace_escaped},
+       {NULL, NULL}
 };
 
 static gchar *
 theme_adium_parse_body (const gchar *text)
 {
+       EmpathyStringParser *parsers;
        GString *string;
+       gboolean use_smileys;
 
+       /* Check if we have to parse smileys */
        empathy_conf_get_bool (empathy_conf_get (),
                               EMPATHY_PREFS_CHAT_SHOW_SMILEYS,
                               &use_smileys);
-
-       /* We parse text in 4 steps: url, smiley, newline, escape.
-        * For each step, we detect the position of tokens in the text, and
-        * we give text between each token to the next level parser.
-        *
-        * For example the string "Hello :)\n www.test.com"
-        * 1) The url parser detects "www.test.com" and gives "Hello :)\n " to
-        *    the smiley parser, then insert the <a> tag for the link.
-        * 2) The smiley parser will detect ":)". It first gives "Hello "
-        *    to the newline parser, then insert the <img/> tag for the smiley,
-        *    and finally give "\n " to the newline parser.
-        * 3a) The newline parser gets "Hello " and escape it.
-        * 3b) The newline parser gets "\n " and replace to "<br/> ".
-        */
-
+       if (use_smileys)
+               parsers = string_parsers_with_smiley;
+       else
+               parsers = string_parsers;
+
+       /* Parse text and construct string with links and smileys replaced
+        * by html tags. Also escape text to make sure html code is
+        * displayed verbatim. */
        string = g_string_sized_new (strlen (text));
-       empathy_string_parser_substr (string, text, -1, string_parsers);
+       empathy_string_parser_substr (text, -1, parsers, string);
 
        return g_string_free (string, FALSE);
 }
@@ -427,6 +438,28 @@ theme_adium_append_html (EmpathyThemeAdium *theme,
        g_free (script);
 }
 
+static void
+theme_adium_append_event_escaped (EmpathyChatView *view,
+                                 const gchar     *escaped)
+{
+       EmpathyThemeAdium     *theme = EMPATHY_THEME_ADIUM (view);
+       EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
+
+       if (priv->data->status_html) {
+               theme_adium_append_html (theme, "appendMessage",
+                                        priv->data->status_html,
+                                        priv->data->status_len,
+                                        escaped, NULL, NULL, NULL, NULL,
+                                        "event", empathy_time_get_current ());
+       }
+
+       /* There is no last contact */
+       if (priv->last_contact) {
+               g_object_unref (priv->last_contact);
+               priv->last_contact = NULL;
+       }
+}
+
 static void
 theme_adium_append_message (EmpathyChatView *view,
                            EmpathyMessage  *msg)
@@ -474,7 +507,8 @@ theme_adium_append_message (EmpathyChatView *view,
                gchar *str;
 
                str = g_strdup_printf ("%s %s", name, body_escaped);
-               empathy_chat_view_append_event (view, str);
+               theme_adium_append_event_escaped (view, str);
+
                g_free (str);
                g_free (body_escaped);
                return;
@@ -621,26 +655,11 @@ static void
 theme_adium_append_event (EmpathyChatView *view,
                          const gchar     *str)
 {
-       EmpathyThemeAdium     *theme = EMPATHY_THEME_ADIUM (view);
-       EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
-
-       if (priv->data->status_html) {
-               gchar *str_escaped;
-
-               str_escaped = g_markup_escape_text (str, -1);
-               theme_adium_append_html (theme, "appendMessage",
-                                        priv->data->status_html,
-                                        priv->data->status_len,
-                                        str_escaped, NULL, NULL, NULL, NULL,
-                                        "event", empathy_time_get_current ());
-               g_free (str_escaped);
-       }
+       gchar *str_escaped;
 
-       /* There is no last contact */
-       if (priv->last_contact) {
-               g_object_unref (priv->last_contact);
-               priv->last_contact = NULL;
-       }
+       str_escaped = g_markup_escape_text (str, -1);
+       theme_adium_append_event_escaped (view, str_escaped);
+       g_free (str_escaped);
 }
 
 static void