[evolution/449-support-markdown-in-composer] MarkdownHTMLToText: Add 'composer quirks' flag



commit b4c8925b6dde5206c00e2585f0dc93b9b459b709
Author: Milan Crha <mcrha redhat com>
Date:   Tue Feb 8 18:16:49 2022 +0100

    MarkdownHTMLToText: Add 'composer quirks' flag
    
    To enable composer-related text pre-processing.

 src/e-util/e-markdown-editor.c |  2 +-
 src/e-util/e-markdown-utils.c  | 92 +++++++++++++++++++++++++++++++++++-------
 src/e-util/e-util-enums.h      |  8 ++--
 3 files changed, 84 insertions(+), 18 deletions(-)
---
diff --git a/src/e-util/e-markdown-editor.c b/src/e-util/e-markdown-editor.c
index 29a2b80718..959eaada03 100644
--- a/src/e-util/e-markdown-editor.c
+++ b/src/e-util/e-markdown-editor.c
@@ -231,7 +231,7 @@ e_markdown_editor_insert_content (EContentEditor *cnt_editor,
        self = E_MARKDOWN_EDITOR (cnt_editor);
 
        if ((flags & E_CONTENT_EDITOR_INSERT_TEXT_HTML) != 0) {
-               text = e_markdown_utils_html_to_text (content, -1, E_MARKDOWN_HTML_TO_TEXT_FLAG_NONE);
+               text = e_markdown_utils_html_to_text (content, -1, 
E_MARKDOWN_HTML_TO_TEXT_FLAG_COMPOSER_QUIRKS);
                content = text;
        }
 
diff --git a/src/e-util/e-markdown-utils.c b/src/e-util/e-markdown-utils.c
index eceb067fb8..3a0a13b3af 100644
--- a/src/e-util/e-markdown-utils.c
+++ b/src/e-util/e-markdown-utils.c
@@ -59,6 +59,55 @@ e_markdown_utils_text_to_html (const gchar *plain_text,
        #endif
 }
 
+static const gchar *
+markdown_utils_get_attribute_value (const xmlChar **xcattrs,
+                                   const gchar *name)
+{
+       gint ii;
+
+       if (!xcattrs)
+               return NULL;
+
+       for (ii = 0; xcattrs[ii] && xcattrs[ii + 1]; ii += 2) {
+               if (g_ascii_strcasecmp (name, (const gchar *) xcattrs[ii]) == 0)
+                       return (const gchar *) xcattrs[ii + 1];
+       }
+
+       return NULL;
+}
+
+struct _ComposerQuirks {
+       gboolean enabled;
+       gchar *to_body_credits;
+       gboolean cite_body;
+};
+
+static void
+markdown_utils_apply_composer_quirks (GString *buffer,
+                                     struct _ComposerQuirks *quirks)
+{
+       if (!quirks || !quirks->enabled)
+               return;
+
+       if (quirks->cite_body) {
+               gint ii;
+
+               g_string_insert (buffer, 0, "> ");
+
+               for (ii = 0; ii < buffer->len; ii++) {
+                       if (buffer->str[ii] == '\n' && ii + 1 < buffer->len) {
+                               g_string_insert (buffer, ii + 1, "> ");
+                               ii += 2;
+                       }
+               }
+       }
+
+       if (quirks->to_body_credits) {
+               g_string_insert (buffer, 0, "\n");
+               g_string_insert (buffer, 0, quirks->to_body_credits);
+       }
+}
+
 typedef struct _HTMLToTextData {
        GString *buffer;
        gboolean in_body;
@@ -70,8 +119,9 @@ typedef struct _HTMLToTextData {
        GString *quote_prefix;
        gchar *href;
        GString *link_text;
-       gboolean plain_text;
        GSList *list_index; /* gint; -1 for unordered list */
+       gboolean plain_text;
+       struct _ComposerQuirks composer_quirks;
 } HTMLToTextData;
 
 static void
@@ -92,6 +142,25 @@ markdown_utils_sax_start_element_cb (gpointer ctx,
        }
        #endif
 
+       if (data->composer_quirks.enabled && g_ascii_strcasecmp (name, "span") == 0) {
+               const gchar *value;
+
+               value = markdown_utils_get_attribute_value (xcattrs, "class");
+
+               if (value && g_ascii_strcasecmp (value, "-x-evo-cite-body") == 0) {
+                       data->composer_quirks.cite_body = TRUE;
+                       return;
+               } else if (value && g_ascii_strcasecmp (value, "-x-evo-to-body") == 0) {
+                       value = markdown_utils_get_attribute_value (xcattrs, "data-credits");
+
+                       if (value && *value) {
+                               g_free (data->composer_quirks.to_body_credits);
+                               data->composer_quirks.to_body_credits = g_strdup (value);
+                               return;
+                       }
+               }
+       }
+
        if (g_ascii_strcasecmp (name, "body") == 0) {
                data->in_body = TRUE;
                return;
@@ -102,22 +171,13 @@ markdown_utils_sax_start_element_cb (gpointer ctx,
 
        if (g_ascii_strcasecmp (name, "a") == 0) {
                if (!data->plain_text && !data->href) {
-                       gchar *href = NULL;
-                       gint ii;
-
-                       for (ii = 0; xcattrs && xcattrs[ii]; ii++) {
-                               if (g_ascii_strcasecmp ((const gchar *) xcattrs[ii], "href") == 0 &&
-                                   xcattrs[ii + 1]) {
-                                       href = g_strdup ((const gchar *) xcattrs[ii + 1]);
-                                       break;
-                               }
-                       }
+                       const gchar *href;
+
+                       href = markdown_utils_get_attribute_value (xcattrs, "href");
 
                        if (href && *href) {
-                               data->href = href;
+                               data->href = g_strdup (href);
                                data->link_text = g_string_new (NULL);
-                       } else {
-                               g_free (href);
                        }
                }
                return;
@@ -476,6 +536,7 @@ e_markdown_utils_html_to_text (const gchar *html,
        data.buffer = g_string_new (NULL);
        data.quote_prefix = g_string_new (NULL);
        data.plain_text = (flags & E_MARKDOWN_HTML_TO_TEXT_FLAG_PLAIN_TEXT) != 0;
+       data.composer_quirks.enabled = (flags & E_MARKDOWN_HTML_TO_TEXT_FLAG_COMPOSER_QUIRKS) != 0;
 
        memset (&sax, 0, sizeof (htmlSAXHandler));
 
@@ -491,6 +552,8 @@ e_markdown_utils_html_to_text (const gchar *html,
 
        htmlFreeParserCtxt (ctxt);
 
+       markdown_utils_apply_composer_quirks (data.buffer, &data.composer_quirks);
+
        g_free (data.href);
 
        if (data.link_text)
@@ -498,6 +561,7 @@ e_markdown_utils_html_to_text (const gchar *html,
 
        g_string_free (data.quote_prefix, TRUE);
        g_slist_free (data.list_index);
+       g_free (data.composer_quirks.to_body_credits);
 
        return g_string_free (data.buffer, FALSE);
 }
diff --git a/src/e-util/e-util-enums.h b/src/e-util/e-util-enums.h
index 8c13745a7f..18cd855ca0 100644
--- a/src/e-util/e-util-enums.h
+++ b/src/e-util/e-util-enums.h
@@ -645,15 +645,17 @@ typedef enum {
 /**
  * EMarkdownHTMLToTextFlags:
  * @E_MARKDOWN_HTML_TO_TEXT_FLAG_NONE: no flag set
- * @E_MARKDOWN_HTML_TO_TEXT_FLAG_PLAIN_TEXT: disallow any HTML, save in plain text
+ * @E_MARKDOWN_HTML_TO_TEXT_FLAG_PLAIN_TEXT: disallow any HTML, save in pure plain text
+ * @E_MARKDOWN_HTML_TO_TEXT_FLAG_COMPOSER_QUIRKS: enable composer quirks to post-process the text
  *
  * Flags used in e_markdown_util_html_to_text().
  *
  * Since: 3.44
  **/
 typedef enum { /*< flags >*/
-       E_MARKDOWN_HTML_TO_TEXT_FLAG_NONE       = 0,
-       E_MARKDOWN_HTML_TO_TEXT_FLAG_PLAIN_TEXT = 1 << 0
+       E_MARKDOWN_HTML_TO_TEXT_FLAG_NONE               = 0,
+       E_MARKDOWN_HTML_TO_TEXT_FLAG_PLAIN_TEXT         = 1 << 0,
+       E_MARKDOWN_HTML_TO_TEXT_FLAG_COMPOSER_QUIRKS    = 1 << 1
 } EMarkdownHTMLToTextFlags;
 
 G_END_DECLS


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]