[gmime: 2/10] bq: correctly calculate citation depth when no newline between quoted and unquoted line, close quote
- From: Jeffrey Stedfast <fejj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gmime: 2/10] bq: correctly calculate citation depth when no newline between quoted and unquoted line, close quote
- Date: Fri, 17 Feb 2017 20:04:20 +0000 (UTC)
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, "> ");
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]