[evolution/449-support-markdown-in-composer] e-markdown-utils: Cover lists in conversion from HTML



commit 8c1a11ff35e6f6fad0e061cd4c958c1bb22eb2c9
Author: Milan Crha <mcrha redhat com>
Date:   Tue Feb 8 09:34:45 2022 +0100

    e-markdown-utils: Cover lists in conversion from HTML

 src/e-util/e-markdown-utils.c | 92 ++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 83 insertions(+), 9 deletions(-)
---
diff --git a/src/e-util/e-markdown-utils.c b/src/e-util/e-markdown-utils.c
index db9105a2f6..eceb067fb8 100644
--- a/src/e-util/e-markdown-utils.c
+++ b/src/e-util/e-markdown-utils.c
@@ -17,7 +17,7 @@
 
 #include "e-markdown-utils.h"
 
-#define dd(x) x
+#define dd(x)
 
 /**
  * e_markdown_utils_text_to_html:
@@ -66,10 +66,12 @@ typedef struct _HTMLToTextData {
        gint in_pre;
        gint in_paragraph;
        gboolean in_paragraph_end;
+       gboolean in_li;
        GString *quote_prefix;
        gchar *href;
        GString *link_text;
        gboolean plain_text;
+       GSList *list_index; /* gint; -1 for unordered list */
 } HTMLToTextData;
 
 static void
@@ -136,13 +138,14 @@ markdown_utils_sax_start_element_cb (gpointer ctx,
        }
 
        if (g_ascii_strcasecmp (name, "br") == 0) {
-               if (data->plain_text)
+               if (data->plain_text) {
                        g_string_append (data->buffer, "\n");
-               else
-                       g_string_append (data->buffer, "<br>");
 
-               if (data->quote_prefix->len)
-                       g_string_append (data->buffer, data->quote_prefix->str);
+                       if (data->quote_prefix->len)
+                               g_string_append (data->buffer, data->quote_prefix->str);
+               } else {
+                       g_string_append (data->buffer, "<br>");
+               }
 
                return;
        }
@@ -184,6 +187,11 @@ markdown_utils_sax_start_element_cb (gpointer ctx,
            g_ascii_strcasecmp (name, "h4") == 0 ||
            g_ascii_strcasecmp (name, "h5") == 0 ||
            g_ascii_strcasecmp (name, "h6") == 0) {
+               if (data->in_paragraph_end) {
+                       g_string_append_c (data->buffer, '\n');
+                       data->in_paragraph_end = FALSE;
+               }
+
                data->in_paragraph++;
                if (data->quote_prefix->len)
                        g_string_append (data->buffer, data->quote_prefix->str);
@@ -229,6 +237,50 @@ markdown_utils_sax_start_element_cb (gpointer ctx,
                        g_string_append (data->buffer, data->quote_prefix->str);
                return;
        }
+
+       if (g_ascii_strcasecmp (name, "ul") == 0) {
+               if (data->in_paragraph_end) {
+                       g_string_append_c (data->buffer, '\n');
+                       data->in_paragraph_end = FALSE;
+               }
+               data->list_index = g_slist_prepend (data->list_index, GINT_TO_POINTER (-1));
+               data->in_li = FALSE;
+               return;
+       }
+
+       if (g_ascii_strcasecmp (name, "ol") == 0) {
+               if (data->in_paragraph_end) {
+                       g_string_append_c (data->buffer, '\n');
+                       data->in_paragraph_end = FALSE;
+               }
+               data->list_index = g_slist_prepend (data->list_index, GINT_TO_POINTER (1));
+               data->in_li = FALSE;
+               return;
+       }
+
+       if (g_ascii_strcasecmp (name, "li") == 0) {
+               data->in_paragraph_end = FALSE;
+               data->in_li = TRUE;
+
+               if (data->list_index) {
+                       gint index = GPOINTER_TO_INT (data->list_index->data);
+                       gint level = g_slist_length (data->list_index) - 1;
+
+                       if (data->quote_prefix->len)
+                               g_string_append (data->buffer, data->quote_prefix->str);
+
+                       if (level > 0)
+                               g_string_append_printf (data->buffer, "%*s", level * 3, "");
+
+                       if (index == -1) {
+                               g_string_append (data->buffer, "- ");
+                       } else {
+                               g_string_append_printf (data->buffer, "%d. ", index);
+                               data->list_index->data = GINT_TO_POINTER (index + 1);
+                       }
+               }
+               return;
+       }
 }
 
 static void
@@ -325,6 +377,27 @@ markdown_utils_sax_end_element_cb (gpointer ctx,
                        data->in_paragraph--;
                return;
        }
+
+       if (g_ascii_strcasecmp (name, "ul") == 0 ||
+           g_ascii_strcasecmp (name, "ol") == 0) {
+               if (data->list_index)
+                       data->list_index = g_slist_remove (data->list_index, data->list_index->data);
+               data->in_paragraph_end = data->list_index == NULL;
+
+               if (!data->in_paragraph_end && data->buffer->len && data->buffer->str[data->buffer->len - 1] 
== '\n')
+                       g_string_truncate (data->buffer, data->buffer->len - 1);
+
+               return;
+       }
+
+       if (g_ascii_strcasecmp (name, "li") == 0) {
+               g_string_append_c (data->buffer, '\n');
+
+               data->in_paragraph_end = FALSE;
+               data->in_li = FALSE;
+
+               return;
+       }
 }
 
 static void
@@ -335,9 +408,9 @@ markdown_utils_sax_characters_cb (gpointer ctx,
        HTMLToTextData *data = ctx;
        const gchar *text = (const gchar *) xctext;
 
-       dd (printf ("%s: text:'%.*s' in_body:%d\n", G_STRFUNC, len, text, data->in_body);)
+       dd (printf ("%s: text:'%.*s' in_body:%d in_paragraph:%d in_li:%d\n", G_STRFUNC, len, text, 
data->in_body, data->in_paragraph, data->in_li);)
 
-       if (data->in_body && data->in_paragraph) {
+       if (data->in_body && (data->in_paragraph || data->in_li)) {
                if (data->link_text) {
                        g_string_append_len (data->link_text, text, len);
                } else {
@@ -345,7 +418,7 @@ markdown_utils_sax_characters_cb (gpointer ctx,
 
                        g_string_append_len (data->buffer, text, len);
 
-                       if (data->quote_prefix->len && strchr (data->buffer->str + from_index, '\n')) {
+                       if (data->quote_prefix->len && !data->in_li && strchr (data->buffer->str + 
from_index, '\n')) {
                                gint ii;
 
                                for (ii = from_index; ii < data->buffer->len; ii++) {
@@ -424,6 +497,7 @@ e_markdown_utils_html_to_text (const gchar *html,
                g_string_free (data.link_text, TRUE);
 
        g_string_free (data.quote_prefix, TRUE);
+       g_slist_free (data.list_index);
 
        return g_string_free (data.buffer, FALSE);
 }


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