Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion cpp/parser/GumboNormalizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,11 @@ static void flatten_bq_node(GumboNode *node, buffer_t *ib, buffer_t *out) {
return;
}
if (is_br_node(node)) {
flush_inline_p(ib, out, NULL);
// Emit the canonical <br> so it is not silently dropped.
// With buffered inline content it just terminates the current paragraph.
if (!flush_inline_p(ib, out, NULL)) {
buffer_append_str(out, "<br>");
}
return;
}
if (is_block_producing(node) || is_blockquote_node(node)) {
Expand Down
16 changes: 12 additions & 4 deletions cpp/tests/GumboParserTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ TEST(GumboParserTest, DivRemappings) {
"</b>hello<div><br></div><div>hi</div></li></ul></div></div></"
"blockquote></span>"),
"<p>what do you think of this craziness</p><blockquote><p><b>another one "
"</b>hello</p><p>hi</p></blockquote>");
"</b>hello</p><br><p>hi</p></blockquote>");
}

TEST(GumboParserTest, ListFlattening) {
Expand Down Expand Up @@ -508,6 +508,13 @@ TEST(GumboParserTest, BrRemappings) {
"href='https://google.com'>Net</a></p>"),
"<p><b>Asdasdasd</b></p><br><br><p>Sent with <a "
"href=\"https://google.com\">Net</a></p>");
// A <br> between blockquote paragraphs is preserved.
EXPECT_EQ(
GumboParser::normalizeHtml(
"<blockquote><p>this is a pretty short blockquote.</p><br><p>This is "
"a line after an empty line.</p></blockquote>"),
"<blockquote><p>this is a pretty short blockquote.</p><br><p>This is a "
"line after an empty line.</p></blockquote>");
}

// Preserve text alignment
Expand Down Expand Up @@ -581,9 +588,10 @@ TEST(GumboParserTest, InterBlockWhitespace) {
EXPECT_EQ(GumboParser::normalizeHtml(
"<p>Asdasd</p>\n\n<p>Asdasd</p>\n\n<p>Asdasda</p>"),
"<p>Asdasd</p><p>Asdasd</p><p>Asdasda</p>");
EXPECT_EQ(GumboParser::normalizeHtml(
"<html>\n<p>Asdasd</p>\n<p>Asdasd</p>\n<p>Asdasda</p>\n</html>"),
"<p>Asdasd</p><p>Asdasd</p><p>Asdasda</p>");
EXPECT_EQ(
GumboParser::normalizeHtml(
"<html>\n<p>Asdasd</p>\n<p>Asdasd</p>\n<p>Asdasda</p>\n</html>"),
"<p>Asdasd</p><p>Asdasd</p><p>Asdasda</p>");
EXPECT_EQ(GumboParser::normalizeHtml("<p>Asdasd</p> <p>Asdasd</p>"),
"<p>Asdasd</p><p>Asdasd</p>");

Expand Down
12 changes: 11 additions & 1 deletion src/web/__tests__/htmlNormalizer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ describe('htmlNormalizer', () => {
],
[
'<div>what do you think of this craziness</div><span><blockquote><div><div><ul><li><b>another one </b>hello<div><br></div><div>hi</div></li></ul></div></div></blockquote></span>',
'<p>what do you think of this craziness</p><blockquote><p><b>another one </b>hello</p><p>hi</p></blockquote>',
'<p>what do you think of this craziness</p><blockquote><p><b>another one </b>hello</p><br><p>hi</p></blockquote>',
],
])('%s → %s', (input, expected) => {
expect(normalizeHtml(input)).toBe(expected);
Expand Down Expand Up @@ -477,6 +477,16 @@ describe('htmlNormalizer', () => {
'<p><b>Asdasdasd</b></p><br><br><p>Sent with <a href="https://google.com">Net</a></p>'
);
});

test('<br> between blockquote paragraphs is preserved', () => {
expect(
normalizeHtml(
'<blockquote><p>this is a pretty short blockquote.</p><br><p>This is a line after an empty line.</p></blockquote>'
)
).toBe(
'<blockquote><p>this is a pretty short blockquote.</p><br><p>This is a line after an empty line.</p></blockquote>'
);
});
});

describe('character escaping', () => {
Expand Down
6 changes: 5 additions & 1 deletion src/web/normalization/htmlNormalizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,11 @@ function flattenBqNode(
}
if (!isElement(node)) return;
if (isBrNode(node)) {
flushInlineP(ib, out);
// Emit the canonical <br> so it is not silently dropped.
// With buffered inline content it just terminates the current paragraph.
if (!flushInlineP(ib, out)) {
out.buf += '<br>';
}
return;
}
if (isBlockProducing(node) || isBlockquoteNode(node)) {
Expand Down
Loading