[gmime: 2/10] bq: correctly calculate citation depth when no newline between quoted and unquoted line, close quote



commit 4b782c6b578401db7b6b421890d817f78a1e888e
Author: Gaute Hope <eg gaute vetsj com>
Date:   Mon May 2 10:24:15 2016 +0200

    bq: correctly calculate citation depth when no newline between quoted and unquoted line, close quotes at 
beginning of line

 gmime/gmime-filter-html.c |  156 +++++++++++++++++++++++----------------------
 1 files changed, 81 insertions(+), 75 deletions(-)
---
diff --git a/gmime/gmime-filter-html.c b/gmime/gmime-filter-html.c
index 098d032..6996423 100644
--- a/gmime/gmime-filter-html.c
+++ b/gmime/gmime-filter-html.c
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*  GMime
  *  Copyright (C) 2000-2014 Jeffrey Stedfast
+ *  Copyright (C) 2016      Gaute Hope
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public License
@@ -94,7 +95,7 @@ GType
 g_mime_filter_html_get_type (void)
 {
        static GType type = 0;
-       
+
        if (!type) {
                static const GTypeInfo info = {
                        sizeof (GMimeFilterHTMLClass),
@@ -120,7 +121,7 @@ g_mime_filter_html_class_init (GMimeFilterHTMLClass *klass)
 {
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
        GMimeFilterClass *filter_class = GMIME_FILTER_CLASS (klass);
-       
+
        parent_class = g_type_class_ref (GMIME_TYPE_FILTER);
        
        object_class->finalize = g_mime_filter_html_finalize;
@@ -134,8 +135,9 @@ g_mime_filter_html_class_init (GMimeFilterHTMLClass *klass)
 static void
 g_mime_filter_html_init (GMimeFilterHTML *filter, GMimeFilterHTMLClass *klass)
 {
+  (void) (klass);
        filter->scanner = url_scanner_new ();
-       
+
        filter->flags = 0;
        filter->colour = 0;
        filter->column = 0;
@@ -149,7 +151,7 @@ g_mime_filter_html_finalize (GObject *object)
        GMimeFilterHTML *html = (GMimeFilterHTML *) object;
        
        url_scanner_free (html->scanner);
-       
+
        G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -167,16 +169,16 @@ check_size (GMimeFilter *filter, char *outptr, char **outend, size_t len)
 {
        size_t outleft = (size_t) (*outend - outptr);
        size_t offset;
-       
+
        if (outleft >= len)
                return outptr;
-       
+
        offset = outptr - filter->outbuf;
-       
+
        g_mime_filter_set_size (filter, filter->outsize + len, TRUE);
-       
+
        *outend = filter->outbuf + filter->outsize;
-       
+
        return filter->outbuf + offset;
 }
 
@@ -184,25 +186,22 @@ static int
 citation_depth (const char *in, const char *inend)
 {
        register const char *inptr = in;
-       int depth = 1;
-       
-       if (*inptr++ != '>')
-               return 0;
-       
+       int depth = 0;
+
        /* check that it isn't an escaped From line */
-       if (!strncmp (inptr, "From", 4))
+       if (!strncmp (inptr, ">From", 5))
                return 0;
-       
+
        while (inptr < inend && *inptr != '\n') {
                if (*inptr == ' ')
                        inptr++;
-               
+
                if (inptr >= inend || *inptr++ != '>')
                        break;
-               
+
                depth++;
        }
-       
+
        return depth;
 }
 
@@ -212,10 +211,10 @@ html_utf8_getc (const unsigned char **in, const unsigned char *inend)
        register const unsigned char *inptr = *in;
        register unsigned char c, r;
        register gunichar u, m;
-       
+
        if (inptr == inend)
                return 0;
-       
+
        while (inptr < inend) {
                r = *inptr++;
        loop:
@@ -228,26 +227,26 @@ html_utf8_getc (const unsigned char **in, const unsigned char *inend)
                        do {
                                if (inptr >= inend)
                                        return 0xffff;
-                               
+
                                c = *inptr++;
                                if ((c & 0xc0) != 0x80) {
                                        r = c;
                                        goto loop;
                                }
-                               
+
                                u = (u << 6) | (c & 0x3f);
                                r <<= 1;
                                m <<= 5;
                        } while (r & 0x40);
-                       
+
                        *in = inptr;
-                       
+
                        u &= ~m;
-                       
+
                        return u;
                }
        }
-       
+
        return 0xffff;
 }
 
@@ -258,12 +257,12 @@ writeln (GMimeFilter *filter, const char *in, const char *end, char *outptr, cha
        const unsigned char *instart = (const unsigned char *) in;
        const unsigned char *inend = (const unsigned char *) end;
        const unsigned char *inptr = instart;
-       
+
        while (inptr < inend) {
                gunichar u;
-               
+
                outptr = check_size (filter, outptr, outend, 16);
-               
+
                u = html_utf8_getc (&inptr, inend);
                switch (u) {
                case 0xffff:
@@ -318,7 +317,7 @@ writeln (GMimeFilter *filter, const char *in, const char *end, char *outptr, cha
                        break;
                }
        }
-       
+
        return outptr;
 }
 
@@ -326,34 +325,35 @@ static void
 html_convert (GMimeFilter *filter, char *in, size_t inlen, size_t prespace,
              char **out, size_t *outlen, size_t *outprespace, gboolean flush)
 {
+  (void) (prespace);
        GMimeFilterHTML *html = (GMimeFilterHTML *) filter;
        register char *inptr, *outptr;
        char *start, *outend;
        const char *inend;
        int depth;
-       
+
        g_mime_filter_set_size (filter, inlen * 2 + 6, FALSE);
-       
+
        start = inptr = in;
        inend = in + inlen;
        outptr = filter->outbuf;
        outend = filter->outbuf + filter->outsize;
-       
+
        if (html->flags & GMIME_FILTER_HTML_PRE && !html->pre_open) {
                outptr = g_stpcpy (outptr, "<pre>");
                html->pre_open = TRUE;
        }
-       
+
        do {
                while (inptr < inend && *inptr != '\n')
                        inptr++;
-               
+
                if (inptr == inend && !flush)
                        break;
-               
+
                html->column = 0;
                depth = citation_depth (start, inend);
-               
+
                if (html->flags & GMIME_FILTER_HTML_BLOCKQUOTE_CITATION) {
                        if (html->prev_cit_depth < depth) {
         while (html->prev_cit_depth < depth) {
@@ -362,25 +362,39 @@ html_convert (GMimeFilter *filter, char *in, size_t inlen, size_t prespace,
           char bq[33];
           int ldepth = html->prev_cit_depth > 999 ? 999 : html->prev_cit_depth;
 
-          g_snprintf (bq, 33, "<blockquote class=\"level_%03d\">", ldepth);
+          g_snprintf (bq, 31, "<blockquote class=\"level_%03d\">", ldepth);
 
-          outptr = check_size (filter, outptr, &outend, 33);
+          outptr = check_size (filter, outptr, &outend, 31);
           outptr = g_stpcpy (outptr, bq);
         }
 
         /* remove '>' */
-        while (*start == '>' && start < inend) start++;
+        while (*start == '>' && start < inptr) start++;
 
         /* remove leading space */
-        if (*start == ' ' && start < inend) start++;
+        if (*start == ' ' && start < inptr) start++;
+
+      } else if (html->prev_cit_depth > depth) {
+
+        /* close quotes */
+        while (html->prev_cit_depth > depth) {
+          outptr = check_size (filter, outptr, &outend, 14);
+          outptr = g_stpcpy (outptr, "</blockquote>");
+          html->prev_cit_depth--;
+        }
+
+        /* remove '>' */
+        while (*start == '>' && start < inptr) start++;
 
+        /* remove leading space */
+        if (*start == ' ' && start < inptr) start++;
 
       } else if (depth > 0) {
-        /* we are still at the same depth or lower: remove '>' */
-        while (*start == '>' && start < inend) start++;
+        /* we are still at the same depth: remove '>' */
+        while (*start == '>' && start < inptr) start++;
 
         /* remove leading space */
-        if (*start == ' ' && start < inend) start++;
+        if (*start == ' ' && start < inptr) start++;
 
                        } else if (*start == '>') {
                                /* >From line */
@@ -390,11 +404,11 @@ html_convert (GMimeFilter *filter, char *in, size_t inlen, size_t prespace,
     } else if (html->flags & GMIME_FILTER_HTML_MARK_CITATION) {
                        if (depth > 0) {
                                char font[25];
-                               
+
                                /* FIXME: we could easily support multiple colour depths here */
-                               
+
                                g_snprintf (font, 25, "<font color=\"#%06x\">", (html->colour & 0xffffff));
-                               
+
                                outptr = check_size (filter, outptr, &outend, 25);
                                outptr = g_stpcpy (outptr, font);
                        } else if (*start == '>') {
@@ -406,42 +420,42 @@ html_convert (GMimeFilter *filter, char *in, size_t inlen, size_t prespace,
                        outptr = g_stpcpy (outptr, "&gt; ");
                        html->column += 2;
                }
-               
+
 #define CONVERT_URLS_OR_ADDRESSES (GMIME_FILTER_HTML_CONVERT_URLS | GMIME_FILTER_HTML_CONVERT_ADDRESSES)
                if (html->flags & CONVERT_URLS_OR_ADDRESSES) {
                        size_t matchlen, buflen, len;
                        urlmatch_t match;
-                       
+
                        len = inptr - start;
-                       
+
                        do {
                                if (url_scanner_scan (html->scanner, start, len, &match)) {
                                        /* write out anything before the first regex match */
                                        outptr = writeln (filter, start, start + match.um_so,
                                                          outptr, &outend);
-                                       
+
                                        start += match.um_so;
                                        len -= match.um_so;
-                                       
+
                                        matchlen = match.um_eo - match.um_so;
-                                       
+
                                        buflen = 20 + strlen (match.prefix) + matchlen + matchlen;
                                        outptr = check_size (filter, outptr, &outend, buflen);
-                                       
+
                                        /* write out the href tag */
                                        outptr = g_stpcpy (outptr, "<a href=\"");
                                        outptr = g_stpcpy (outptr, match.prefix);
                                        memcpy (outptr, start, matchlen);
                                        outptr += matchlen;
                                        outptr = g_stpcpy (outptr, "\">");
-                                       
+
                                        /* now write the matched string */
                                        memcpy (outptr, start, matchlen);
                                        html->column += matchlen;
                                        outptr += matchlen;
                                        start += matchlen;
                                        len -= matchlen;
-                                       
+
                                        /* close the href tag */
                                        outptr = g_stpcpy (outptr, "</a>");
                                } else {
@@ -454,31 +468,23 @@ html_convert (GMimeFilter *filter, char *in, size_t inlen, size_t prespace,
                        outptr = writeln (filter, start, inptr, outptr, &outend);
                }
 
-               if ((html->flags & GMIME_FILTER_HTML_BLOCKQUOTE_CITATION) &&
-        (depth < html->prev_cit_depth)) {
-      while (html->prev_cit_depth > depth) {
-        outptr = check_size (filter, outptr, &outend, 14);
-        outptr = g_stpcpy (outptr, "</blockquote>");
-        html->prev_cit_depth--;
-      }
-    }
-               
-               if ((html->flags & GMIME_FILTER_HTML_MARK_CITATION) && depth > 0) {
+               if (!(html->flags & GMIME_FILTER_HTML_BLOCKQUOTE_CITATION) &&
+         (html->flags & GMIME_FILTER_HTML_MARK_CITATION) && (depth > 0)) {
                        outptr = check_size (filter, outptr, &outend, 8);
                        outptr = g_stpcpy (outptr, "</font>");
                }
-               
+
                if (html->flags & GMIME_FILTER_HTML_CONVERT_NL) {
                        outptr = check_size (filter, outptr, &outend, 5);
                        outptr = g_stpcpy (outptr, "<br>");
                }
-               
+
                if (inptr < inend)
                        *outptr++ = '\n';
-               
+
                start = ++inptr;
        } while (inptr < inend);
-       
+
        if (flush) {
                if (html->pre_open) {
                        /* close the pre-tag */
@@ -499,7 +505,7 @@ html_convert (GMimeFilter *filter, char *in, size_t inlen, size_t prespace,
                /* backup */
                g_mime_filter_backup (filter, start, (unsigned) (inend - start));
        }
-       
+
        *out = filter->outbuf;
        *outlen = outptr - filter->outbuf;
        *outprespace = filter->outpre;
@@ -512,7 +518,7 @@ filter_filter (GMimeFilter *filter, char *in, size_t len, size_t prespace,
        html_convert (filter, in, len, prespace, out, outlen, outprespace, FALSE);
 }
 
-static void 
+static void
 filter_complete (GMimeFilter *filter, char *in, size_t len, size_t prespace,
                 char **out, size_t *outlen, size_t *outprespace)
 {
@@ -549,11 +555,11 @@ g_mime_filter_html_new (guint32 flags, guint32 colour)
        filter = g_object_newv (GMIME_TYPE_FILTER_HTML, 0, NULL);
        filter->flags = flags;
        filter->colour = colour;
-       
+
        for (i = 0; i < NUM_URL_PATTERNS; i++) {
                if (patterns[i].mask & flags)
                        url_scanner_add (filter->scanner, &patterns[i].pattern);
        }
-       
+
        return (GMimeFilter *) filter;
 }


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