From: Aki Tuomi Date: Tue, 29 Oct 2019 10:39:16 +0000 (+0200) Subject: lib-mail: Include blockquotes as quotes in plain text X-Git-Tag: 2.3.9~85 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b02574e0eb1660b32bfac0adbbdb6e2e144292e9;p=thirdparty%2Fdovecot%2Fcore.git lib-mail: Include blockquotes as quotes in plain text
This is now preserved
which is fine renders as > this is now preserved which is fine --- diff --git a/src/lib-mail/mail-html2text.c b/src/lib-mail/mail-html2text.c index 0297269fd6..3d9f9beb4f 100644 --- a/src/lib-mail/mail-html2text.c +++ b/src/lib-mail/mail-html2text.c @@ -41,6 +41,7 @@ struct mail_html2text { enum html_state state; buffer_t *input; unsigned int quote_level; + bool add_newline; }; static struct { @@ -86,18 +87,18 @@ parse_tag_name(struct mail_html2text *ht, return 8 + 1; } - if ((ht->flags & MAIL_HTML2TEXT_FLAG_SKIP_QUOTED) != 0) { - if (size >= 10 && i_memcasecmp(data, "blockquote", 10) == 0 && - (HTML_WHITESPACE(data[10]) || data[10] == '>')) { - ht->quote_level++; - ht->state = HTML_STATE_TAG; - return 1; - } else if (ht->quote_level > 0 && - size >= 12 && i_memcasecmp(data, "/blockquote>", 12) == 0) { - ht->quote_level--; - ht->state = HTML_STATE_TAG; - return 1; - } + if (size >= 10 && i_memcasecmp(data, "blockquote", 10) == 0 && + (HTML_WHITESPACE(data[10]) || data[10] == '>')) { + ht->quote_level++; + ht->state = HTML_STATE_TAG; + return 1; + } else if (ht->quote_level > 0 && + size >= 12 && i_memcasecmp(data, "/blockquote>", 12) == 0) { + ht->quote_level--; + if ((ht->flags & MAIL_HTML2TEXT_FLAG_SKIP_QUOTED) == 0) + ht->add_newline = TRUE; + ht->state = HTML_STATE_TAG; + return 1; } if (size < 12) { /* can we see the whole tag name? */ @@ -191,15 +192,16 @@ parse_data(struct mail_html2text *ht, if (ret == 0) return i; i += ret - 1; - } else if (ht->quote_level == 0) { - if (c == '&') { - ret = parse_entity(data+i+1, size-i-1, output); - if (ret == 0) - return i; - i += ret - 1; - } else { - buffer_append_c(output, c); - } + } else if (ht->quote_level > 0 && + (ht->flags & MAIL_HTML2TEXT_FLAG_SKIP_QUOTED) != 0) { + break; + } else if (c == '&') { + ret = parse_entity(data+i+1, size-i-1, output); + if (ret == 0) + return i; + i += ret - 1; + } else { + buffer_append_c(output, c); } break; case HTML_STATE_TAG: @@ -209,6 +211,13 @@ parse_data(struct mail_html2text *ht, ht->state = HTML_STATE_TAG_SQUOTED; else if (c == '>') { ht->state = HTML_STATE_TEXT; + if (ht->quote_level > 0 && + (ht->flags & MAIL_HTML2TEXT_FLAG_SKIP_QUOTED) == 0) { + buffer_append(output, "\n>", 2); + } else if (ht->add_newline) { + buffer_append_c(output, '\n'); + } + ht->add_newline = FALSE; mail_html2text_add_space(output); } break; @@ -284,7 +293,8 @@ parse_data(struct mail_html2text *ht, break; } } - if (ht->quote_level == 0) + if (ht->quote_level == 0 || + (ht->flags & MAIL_HTML2TEXT_FLAG_SKIP_QUOTED) == 0) buffer_append_c(output, c); break; } diff --git a/src/lib-mail/test-mail-html2text.c b/src/lib-mail/test-mail-html2text.c index cbb0a6630f..73e93f70b2 100644 --- a/src/lib-mail/test-mail-html2text.c +++ b/src/lib-mail/test-mail-html2text.c @@ -44,9 +44,17 @@ static const struct { { "&#deee;", "" }, // invalid codepoint }; -static const char *test_blockquote_input = - "a
b
c
d
e
f"; -static const char *test_blockquote_output = "a b c d e f"; +static const char *test_blockquote_input[] = { + "a
b
c
d
e
f", + "a&
b&
&
&c
d&
&e
f&", + NULL +}; + +static const char *test_blockquote_output[] = { + "a\n> b\n> \n> c\n> d\n> e\nf", + "a&\n> b&\n> &\n> &c\n> d&\n> &e\nf&", + NULL +}; static void test_mail_html2text(void) { @@ -67,11 +75,14 @@ static void test_mail_html2text(void) } /* test without skipping quoted */ - ht = mail_html2text_init(0); - mail_html2text_more(ht, (const void *)test_blockquote_input, - strlen(test_blockquote_input), str); - test_assert(strcmp(str_c(str), test_blockquote_output) == 0); - mail_html2text_deinit(&ht); + for (unsigned int i = 0; test_blockquote_input[i] != NULL; i++) { + str_truncate(str, 0); + ht = mail_html2text_init(0); + mail_html2text_more(ht, (const void *)test_blockquote_input[i], + strlen(test_blockquote_input[i]), str); + test_assert_idx(strcmp(str_c(str), test_blockquote_output[i]) == 0, i); + mail_html2text_deinit(&ht); + } test_end(); }