diff options
-rw-r--r-- | man/blogc-source.7.ronn | 4 | ||||
-rw-r--r-- | src/content-parser.c | 110 | ||||
-rw-r--r-- | tests/check_content_parser.c | 502 |
3 files changed, 579 insertions, 37 deletions
diff --git a/man/blogc-source.7.ronn b/man/blogc-source.7.ronn index 83baf8c..8f43413 100644 --- a/man/blogc-source.7.ronn +++ b/man/blogc-source.7.ronn @@ -225,10 +225,6 @@ The source content is handled by handwritten parsers, that even being well tested, may be subject of parsing bugs. Please report any issues to: <https://github.com/blogc/blogc> -At least one bug is known at this point: ``\r\n`` character sequences are -handled like 2 line breaks. The parsers won't work properly with files edited -on Windows editors like Notepad. - ## AUTHOR Rafael G. Martins <<rafael@rafaelmartins.eng.br>> diff --git a/src/content-parser.c b/src/content-parser.c index 3b661a8..e8d3143 100644 --- a/src/content-parser.c +++ b/src/content-parser.c @@ -305,10 +305,10 @@ blogc_content_parse_inline(const char *src) case '\r': if (state == LINK_CLOSED) { if (spaces >= 2) { - b_string_append(rv, "<br />\n"); + b_string_append(rv, "<br />"); spaces = 0; } - else if (c == '\n' || c == '\r') + if (c == '\n' || c == '\r') b_string_append_c(rv, c); } break; @@ -403,6 +403,7 @@ blogc_content_parse(const char *src, size_t *end_excerpt) size_t start2 = 0; size_t end = 0; size_t eend = 0; + size_t real_end = 0; unsigned int header_level = 0; char *prefix = NULL; @@ -412,6 +413,12 @@ blogc_content_parse(const char *src, size_t *end_excerpt) char *parsed = NULL; char *slug = NULL; + // this isn't empty because we need some reasonable default value in the + // unlikely case when we need to print some line ending before evaluating + // the "real" value. + char line_ending[3] = "\n"; + char l[2] = {0, 0}; + char d = '\0'; b_slist_t *lines = NULL; @@ -426,6 +433,30 @@ blogc_content_parse(const char *src, size_t *end_excerpt) char c = src[current]; bool is_last = current == src_len - 1; + if (c == '\n' || c == '\r') { + if ((current + 1) < src_len) { + if ((c == '\n' && src[current + 1] == '\r') || + (c == '\r' && src[current + 1] == '\n')) + { + if (l[0] == 0) { + l[0] = c; + l[1] = src[current + 1]; + line_ending[0] = c; + line_ending[1] = src[current + 1]; + line_ending[2] = '\0'; + } + real_end = current; + c = src[++current]; + is_last = current == src_len - 1; + } + } + if (l[0] == 0) { + l[0] = c; + line_ending[0] = c; + line_ending[1] = '\0'; + } + } + switch (state) { case CONTENT_START_LINE: @@ -520,16 +551,18 @@ blogc_content_parse(const char *src, size_t *end_excerpt) case CONTENT_HEADER_TITLE: if (c == '\n' || c == '\r' || is_last) { - end = is_last && c != '\n' && c != '\r' ? src_len : current; + end = is_last && c != '\n' && c != '\r' ? src_len : + (real_end != 0 ? real_end : current); tmp = b_strndup(src + start, end - start); parsed = blogc_content_parse_inline(tmp); slug = blogc_slugify(tmp); if (slug == NULL) - b_string_append_printf(rv, "<h%d>%s</h%d>\n", - header_level, parsed, header_level); + b_string_append_printf(rv, "<h%d>%s</h%d>%s", + header_level, parsed, header_level, line_ending); else - b_string_append_printf(rv, "<h%d id=\"%s\">%s</h%d>\n", - header_level, slug, parsed, header_level); + b_string_append_printf(rv, "<h%d id=\"%s\">%s</h%d>%s", + header_level, slug, parsed, header_level, + line_ending); free(slug); free(parsed); parsed = NULL; @@ -543,7 +576,8 @@ blogc_content_parse(const char *src, size_t *end_excerpt) case CONTENT_HTML: if (c == '\n' || c == '\r' || is_last) { state = CONTENT_HTML_END; - end = is_last && c != '\n' && c != '\r' ? src_len : current; + end = is_last && c != '\n' && c != '\r' ? src_len : + (real_end != 0 ? real_end : current); } if (!is_last) break; @@ -551,7 +585,7 @@ blogc_content_parse(const char *src, size_t *end_excerpt) case CONTENT_HTML_END: if (c == '\n' || c == '\r' || is_last) { tmp = b_strndup(src + start, end - start); - b_string_append_printf(rv, "%s\n", tmp); + b_string_append_printf(rv, "%s%s", tmp, line_ending); free(tmp); tmp = NULL; state = CONTENT_START_LINE; @@ -570,7 +604,8 @@ blogc_content_parse(const char *src, size_t *end_excerpt) case CONTENT_BLOCKQUOTE_START: if (c == '\n' || c == '\r' || is_last) { - end = is_last && c != '\n' && c != '\r' ? src_len : current; + end = is_last && c != '\n' && c != '\r' ? src_len : + (real_end != 0 ? real_end : current); tmp = b_strndup(src + start2, end - start2); if (b_str_starts_with(tmp, prefix)) { lines = b_slist_append(lines, b_strdup(tmp + strlen(prefix))); @@ -596,11 +631,12 @@ blogc_content_parse(const char *src, size_t *end_excerpt) if (l->next == NULL) b_string_append_printf(tmp_str, "%s", l->data); else - b_string_append_printf(tmp_str, "%s\n", l->data); + b_string_append_printf(tmp_str, "%s%s", l->data, + line_ending); } tmp = blogc_content_parse(tmp_str->str, NULL); - b_string_append_printf(rv, "<blockquote>%s</blockquote>\n", - tmp); + b_string_append_printf(rv, "<blockquote>%s</blockquote>%s", + tmp, line_ending); free(tmp); tmp = NULL; b_string_free(tmp_str, true); @@ -627,7 +663,8 @@ blogc_content_parse(const char *src, size_t *end_excerpt) case CONTENT_CODE_START: if (c == '\n' || c == '\r' || is_last) { - end = is_last && c != '\n' && c != '\r' ? src_len : current; + end = is_last && c != '\n' && c != '\r' ? src_len : + (real_end != 0 ? real_end : current); tmp = b_strndup(src + start2, end - start2); if (b_str_starts_with(tmp, prefix)) { lines = b_slist_append(lines, b_strdup(tmp + strlen(prefix))); @@ -656,9 +693,10 @@ blogc_content_parse(const char *src, size_t *end_excerpt) if (l->next == NULL) b_string_append_printf(rv, "%s", l->data); else - b_string_append_printf(rv, "%s\n", l->data); + b_string_append_printf(rv, "%s%s", l->data, + line_ending); } - b_string_append(rv, "</code></pre>\n"); + b_string_append_printf(rv, "</code></pre>%s", line_ending); b_slist_free_full(lines, free); lines = NULL; free(prefix); @@ -691,7 +729,7 @@ blogc_content_parse(const char *src, size_t *end_excerpt) } hr: if (c == '\n' || c == '\r' || is_last) { - b_string_append(rv, "<hr />\n"); + b_string_append_printf(rv, "<hr />%s", line_ending); state = CONTENT_START_LINE; start = current; d = '\0'; @@ -702,7 +740,8 @@ hr: case CONTENT_UNORDERED_LIST_START: if (c == '\n' || c == '\r' || is_last) { - end = is_last && c != '\n' && c != '\r' ? src_len : current; + end = is_last && c != '\n' && c != '\r' ? src_len : + (real_end != 0 ? real_end : current); tmp = b_strndup(src + start2, end - start2); tmp2 = b_strdup_printf("%-*s", strlen(prefix), ""); if (b_str_starts_with(tmp, prefix)) { @@ -712,7 +751,8 @@ hr: if (l->next == NULL) b_string_append_printf(tmp_str, "%s", l->data); else - b_string_append_printf(tmp_str, "%s\n", l->data); + b_string_append_printf(tmp_str, "%s%s", l->data, + line_ending); } b_slist_free_full(lines2, free); lines2 = NULL; @@ -760,7 +800,8 @@ hr: if (l->next == NULL) b_string_append_printf(tmp_str, "%s", l->data); else - b_string_append_printf(tmp_str, "%s\n", l->data); + b_string_append_printf(tmp_str, "%s%s", l->data, + line_ending); } b_slist_free_full(lines2, free); lines2 = NULL; @@ -770,10 +811,11 @@ hr: free(parsed); parsed = NULL; } - b_string_append(rv, "<ul>\n"); + b_string_append_printf(rv, "<ul>%s", line_ending); for (b_slist_t *l = lines; l != NULL; l = l->next) - b_string_append_printf(rv, "<li>%s</li>\n", l->data); - b_string_append(rv, "</ul>\n"); + b_string_append_printf(rv, "<li>%s</li>%s", l->data, + line_ending); + b_string_append_printf(rv, "</ul>%s", line_ending); b_slist_free_full(lines, free); lines = NULL; free(prefix); @@ -807,7 +849,8 @@ hr: case CONTENT_ORDERED_LIST_START: if (c == '\n' || c == '\r' || is_last) { - end = is_last && c != '\n' && c != '\r' ? src_len : current; + end = is_last && c != '\n' && c != '\r' ? src_len : + (real_end != 0 ? real_end : current); tmp = b_strndup(src + start2, end - start2); tmp2 = b_strdup_printf("%-*s", prefix_len, ""); if (blogc_is_ordered_list_item(tmp, prefix_len)) { @@ -817,7 +860,8 @@ hr: if (l->next == NULL) b_string_append_printf(tmp_str, "%s", l->data); else - b_string_append_printf(tmp_str, "%s\n", l->data); + b_string_append_printf(tmp_str, "%s%s", l->data, + line_ending); } b_slist_free_full(lines2, free); lines2 = NULL; @@ -865,7 +909,8 @@ hr: if (l->next == NULL) b_string_append_printf(tmp_str, "%s", l->data); else - b_string_append_printf(tmp_str, "%s\n", l->data); + b_string_append_printf(tmp_str, "%s%s", l->data, + line_ending); } b_slist_free_full(lines2, free); lines2 = NULL; @@ -875,10 +920,11 @@ hr: free(parsed); parsed = NULL; } - b_string_append(rv, "<ol>\n"); + b_string_append_printf(rv, "<ol>%s", line_ending); for (b_slist_t *l = lines; l != NULL; l = l->next) - b_string_append_printf(rv, "<li>%s</li>\n", l->data); - b_string_append(rv, "</ol>\n"); + b_string_append_printf(rv, "<li>%s</li>%s", l->data, + line_ending); + b_string_append_printf(rv, "</ol>%s", line_ending); b_slist_free_full(lines, free); lines = NULL; free(prefix); @@ -895,7 +941,8 @@ hr: case CONTENT_PARAGRAPH: if (c == '\n' || c == '\r' || is_last) { state = CONTENT_PARAGRAPH_END; - end = is_last && c != '\n' && c != '\r' ? src_len : current; + end = is_last && c != '\n' && c != '\r' ? src_len : + (real_end != 0 ? real_end : current); } if (!is_last) break; @@ -905,7 +952,8 @@ para: if (c == '\n' || c == '\r' || is_last) { tmp = b_strndup(src + start, end - start); parsed = blogc_content_parse_inline(tmp); - b_string_append_printf(rv, "<p>%s</p>\n", parsed); + b_string_append_printf(rv, "<p>%s</p>%s", parsed, + line_ending); free(parsed); parsed = NULL; free(tmp); diff --git a/tests/check_content_parser.c b/tests/check_content_parser.c index 37c1761..994e900 100644 --- a/tests/check_content_parser.c +++ b/tests/check_content_parser.c @@ -145,6 +145,84 @@ test_content_parse(void **state) static void +test_content_parse_crlf(void **state) +{ + size_t l = 0; + char *html = blogc_content_parse( + "# um\r\n" + "## dois\r\n" + "### tres\r\n" + "#### quatro\r\n" + "##### cinco\r\n" + "###### seis\r\n" + "\r\n" + "bola\r\n" + "chunda\r\n" + "\r\n" + "> bola \r\n" + "> guda\r\n" + "> buga\r\n" + "> \r\n" + "> asd\r\n" + "\r\n" + " bola\r\n" + " asd\r\n" + " qwewer\r\n" + "\r\n" + "+++\r\n" + "1. chunda\r\n" + "3. fuuuu\r\n" + "\r\n" + "+ chunda2\r\n" + "+ fuuuu2\r\n" + "\r\n" + "<style>\r\n" + " chunda\r\n" + "</style>\r\n" + "\r\n" + "guda\r\n" + "yay\r\n" + "\r\n" + "**bola**\r\n", &l); + assert_non_null(html); + assert_int_equal(l, 0); + assert_string_equal(html, + "<h1 id=\"um\">um</h1>\r\n" + "<h2 id=\"dois\">dois</h2>\r\n" + "<h3 id=\"tres\">tres</h3>\r\n" + "<h4 id=\"quatro\">quatro</h4>\r\n" + "<h5 id=\"cinco\">cinco</h5>\r\n" + "<h6 id=\"seis\">seis</h6>\r\n" + "<p>bola\r\n" + "chunda</p>\r\n" + "<blockquote><p>bola <br />\r\n" + "guda\r\n" + "buga</p>\r\n" + "<pre><code>asd</code></pre>\r\n" + "</blockquote>\r\n" + "<pre><code>bola\r\n" + " asd\r\n" + "qwewer</code></pre>\r\n" + "<hr />\r\n" + "<ol>\r\n" + "<li>chunda</li>\r\n" + "<li>fuuuu</li>\r\n" + "</ol>\r\n" + "<ul>\r\n" + "<li>chunda2</li>\r\n" + "<li>fuuuu2</li>\r\n" + "</ul>\r\n" + "<style>\r\n" + " chunda\r\n" + "</style>\r\n" + "<p>guda\r\n" + "yay</p>\r\n" + "<p><strong>bola</strong></p>\r\n"); + free(html); +} + + +static void test_content_parse_with_excerpt(void **state) { size_t l = 0; @@ -187,6 +265,48 @@ test_content_parse_with_excerpt(void **state) static void +test_content_parse_with_excerpt_crlf(void **state) +{ + size_t l = 0; + char *html = blogc_content_parse( + "# test\r\n" + "\r\n" + "chunda\r\n" + "\r\n" + "..\r\n" + "\r\n" + "guda\r\n" + "lol", &l); + assert_non_null(html); + assert_int_equal(l, 40); + assert_string_equal(html, + "<h1 id=\"test\">test</h1>\r\n" + "<p>chunda</p>\r\n" + "<p>guda\r\n" + "lol</p>\r\n"); + free(html); + l = 0; + html = blogc_content_parse( + "# test\r\n" + "\r\n" + "chunda\r\n" + "\r\n" + "...\r\n" + "\r\n" + "guda\r\n" + "lol", &l); + assert_non_null(html); + assert_int_equal(l, 40); + assert_string_equal(html, + "<h1 id=\"test\">test</h1>\r\n" + "<p>chunda</p>\r\n" + "<p>guda\r\n" + "lol</p>\r\n"); + free(html); +} + + +static void test_content_parse_header(void **state) { char *html = blogc_content_parse("## bola", NULL); @@ -213,6 +333,32 @@ test_content_parse_header(void **state) static void +test_content_parse_header_crlf(void **state) +{ + char *html = blogc_content_parse("## bola", NULL); + assert_non_null(html); + assert_string_equal(html, "<h2 id=\"bola\">bola</h2>\n"); + free(html); + html = blogc_content_parse("## bola\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, "<h2 id=\"bola\">bola</h2>\r\n"); + free(html); + html = blogc_content_parse( + "bola\r\n" + "\r\n" + "## bola\r\n" + "\r\n" + "guda\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>bola</p>\r\n" + "<h2 id=\"bola\">bola</h2>\r\n" + "<p>guda</p>\r\n"); + free(html); +} + + +static void test_content_parse_html(void **state) { char *html = blogc_content_parse("<div>\n</div>", NULL); @@ -240,6 +386,33 @@ test_content_parse_html(void **state) static void +test_content_parse_html_crlf(void **state) +{ + char *html = blogc_content_parse("<div>\r\n</div>", NULL); + assert_non_null(html); + assert_string_equal(html, "<div>\r\n</div>\r\n"); + free(html); + html = blogc_content_parse("<div>\r\n</div>\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, "<div>\r\n</div>\r\n"); + free(html); + html = blogc_content_parse( + "bola\r\n" + "\r\n" + "<div>\r\n" + "</div>\r\n" + "\r\n" + "chunda\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>bola</p>\r\n" + "<div>\r\n</div>\r\n" + "<p>chunda</p>\r\n"); + free(html); +} + + +static void test_content_parse_blockquote(void **state) { char *html = blogc_content_parse("> bola\n> guda", NULL); @@ -275,6 +448,41 @@ test_content_parse_blockquote(void **state) static void +test_content_parse_blockquote_crlf(void **state) +{ + char *html = blogc_content_parse("> bola\r\n> guda", NULL); + assert_non_null(html); + assert_string_equal(html, + "<blockquote><p>bola\r\n" + "guda</p>\r\n" + "</blockquote>\r\n"); + free(html); + html = blogc_content_parse("> bola\r\n> guda\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<blockquote><p>bola\r\n" + "guda</p>\r\n" + "</blockquote>\r\n"); + free(html); + html = blogc_content_parse( + "bola\r\n" + "\r\n" + "> bola\r\n" + "> guda\r\n" + "\r\n" + "chunda\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>bola</p>\r\n" + "<blockquote><p>bola\r\n" + "guda</p>\r\n" + "</blockquote>\r\n" + "<p>chunda</p>\r\n"); + free(html); +} + + +static void test_content_parse_code(void **state) { char *html = blogc_content_parse(" bola\n guda", NULL); @@ -307,6 +515,38 @@ test_content_parse_code(void **state) static void +test_content_parse_code_crlf(void **state) +{ + char *html = blogc_content_parse(" bola\r\n guda", NULL); + assert_non_null(html); + assert_string_equal(html, + "<pre><code>bola\r\n" + "guda</code></pre>\r\n"); + free(html); + html = blogc_content_parse(" bola\r\n guda\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<pre><code>bola\r\n" + "guda</code></pre>\r\n"); + free(html); + html = blogc_content_parse( + "bola\r\n" + "\r\n" + " bola\r\n" + " guda\r\n" + "\r\n" + "chunda\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>bola</p>\r\n" + "<pre><code>bola\r\n" + "guda</code></pre>\r\n" + "<p>chunda</p>\r\n"); + free(html); +} + + +static void test_content_parse_horizontal_rule(void **state) { char *html = blogc_content_parse("bola\nguda\n\n**", NULL); @@ -365,6 +605,64 @@ test_content_parse_horizontal_rule(void **state) static void +test_content_parse_horizontal_rule_crlf(void **state) +{ + char *html = blogc_content_parse("bola\r\nguda\r\n\r\n**", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>bola\r\n" + "guda</p>\r\n" + "<hr />\r\n"); + free(html); + html = blogc_content_parse("bola\r\nguda\r\n\r\n++++", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>bola\r\n" + "guda</p>\r\n" + "<hr />\r\n"); + free(html); + html = blogc_content_parse("bola\r\nguda\r\n\r\n--\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>bola\r\n" + "guda</p>\r\n" + "<hr />\r\n"); + free(html); + html = blogc_content_parse("bola\r\nguda\r\n\r\n****\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>bola\r\n" + "guda</p>\r\n" + "<hr />\r\n"); + free(html); + html = blogc_content_parse( + "bola\r\n" + "\r\n" + "**\r\n" + "\r\n" + "chunda\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>bola</p>\r\n" + "<hr />\r\n" + "<p>chunda</p>\r\n"); + free(html); + html = blogc_content_parse( + "bola\r\n" + "\r\n" + "----\r\n" + "\r\n" + "chunda\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>bola</p>\r\n" + "<hr />\r\n" + "<p>chunda</p>\r\n"); + free(html); +} + + +static void test_content_parse_unordered_list(void **state) { char *html = blogc_content_parse( @@ -453,6 +751,94 @@ test_content_parse_unordered_list(void **state) static void +test_content_parse_unordered_list_crlf(void **state) +{ + char *html = blogc_content_parse( + "lol\r\n" + "\r\n" + "* asd\r\n" + "* qwe\r\n" + "* zxc", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>lol</p>\r\n" + "<ul>\r\n" + "<li>asd</li>\r\n" + "<li>qwe</li>\r\n" + "<li>zxc</li>\r\n" + "</ul>\r\n"); + free(html); + html = blogc_content_parse( + "lol\r\n" + "\r\n" + "* asd\r\n" + "* qwe\r\n" + "* zxc\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>lol</p>\r\n" + "<ul>\r\n" + "<li>asd</li>\r\n" + "<li>qwe</li>\r\n" + "<li>zxc</li>\r\n" + "</ul>\r\n"); + free(html); + html = blogc_content_parse( + "lol\r\n" + "\r\n" + "* asd\r\n" + "* qwe\r\n" + "* zxc\r\n" + "\r\n" + "fuuuu\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>lol</p>\r\n" + "<ul>\r\n" + "<li>asd</li>\r\n" + "<li>qwe</li>\r\n" + "<li>zxc</li>\r\n" + "</ul>\r\n" + "<p>fuuuu</p>\r\n"); + free(html); + html = blogc_content_parse( + "lol\r\n" + "\r\n" + "* asd\r\n" + " cvb\r\n" + "* qwe\r\n" + "* zxc\r\n" + " 1234\r\n" + "\r\n" + "fuuuu\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>lol</p>\r\n" + "<ul>\r\n" + "<li>asd\r\n" + "cvb</li>\r\n" + "<li>qwe</li>\r\n" + "<li>zxc\r\n" + "1234</li>\r\n" + "</ul>\r\n" + "<p>fuuuu</p>\r\n"); + free(html); + html = blogc_content_parse( + "* asd\r\n" + "* qwe\r\n" + "* zxc", NULL); + assert_non_null(html); + assert_string_equal(html, + "<ul>\r\n" + "<li>asd</li>\r\n" + "<li> qwe</li>\r\n" + "<li> zxc</li>\r\n" + "</ul>\r\n"); + free(html); +} + + +static void test_content_parse_ordered_list(void **state) { char *html = blogc_content_parse( @@ -541,6 +927,94 @@ test_content_parse_ordered_list(void **state) static void +test_content_parse_ordered_list_crlf(void **state) +{ + char *html = blogc_content_parse( + "lol\r\n" + "\r\n" + "1. asd\r\n" + "2. qwe\r\n" + "3. zxc", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>lol</p>\r\n" + "<ol>\r\n" + "<li>asd</li>\r\n" + "<li>qwe</li>\r\n" + "<li>zxc</li>\r\n" + "</ol>\r\n"); + free(html); + html = blogc_content_parse( + "lol\r\n" + "\r\n" + "1. asd\r\n" + "2. qwe\r\n" + "3. zxc\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>lol</p>\r\n" + "<ol>\r\n" + "<li>asd</li>\r\n" + "<li>qwe</li>\r\n" + "<li>zxc</li>\r\n" + "</ol>\r\n"); + free(html); + html = blogc_content_parse( + "lol\r\n" + "\r\n" + "1. asd\r\n" + "2. qwe\r\n" + "3. zxc\r\n" + "\r\n" + "fuuuu\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>lol</p>\r\n" + "<ol>\r\n" + "<li>asd</li>\r\n" + "<li>qwe</li>\r\n" + "<li>zxc</li>\r\n" + "</ol>\r\n" + "<p>fuuuu</p>\r\n"); + free(html); + html = blogc_content_parse( + "lol\r\n" + "\r\n" + "1. asd\r\n" + " cvb\r\n" + "2. qwe\r\n" + "3. zxc\r\n" + " 1234\r\n" + "\r\n" + "fuuuu\r\n", NULL); + assert_non_null(html); + assert_string_equal(html, + "<p>lol</p>\r\n" + "<ol>\r\n" + "<li>asd\r\n" + "cvb</li>\r\n" + "<li>qwe</li>\r\n" + "<li>zxc\r\n" + "1234</li>\r\n" + "</ol>\r\n" + "<p>fuuuu</p>\r\n"); + free(html); + html = blogc_content_parse( + "1. asd\r\n" + "2. qwe\r\n" + "3. zxc", NULL); + assert_non_null(html); + assert_string_equal(html, + "<ol>\r\n" + "<li>asd</li>\r\n" + "<li> qwe</li>\r\n" + "<li> zxc</li>\r\n" + "</ol>\r\n"); + free(html); +} + + +static void test_content_parse_invalid_excerpt(void **state) { size_t l = 0; @@ -1126,11 +1600,11 @@ test_content_parse_inline_line_break(void **state) free(html); html = blogc_content_parse_inline("asd "); assert_non_null(html); - assert_string_equal(html, "asd <br />\n"); + assert_string_equal(html, "asd <br />"); free(html); html = blogc_content_parse_inline("asd "); assert_non_null(html); - assert_string_equal(html, "asd <br />\n"); + assert_string_equal(html, "asd <br />"); free(html); // invalid html = blogc_content_parse_inline("asd "); @@ -1144,6 +1618,20 @@ test_content_parse_inline_line_break(void **state) } +static void +test_content_parse_inline_line_break_crlf(void **state) +{ + char *html = blogc_content_parse_inline("asd \r\n"); + assert_non_null(html); + assert_string_equal(html, "asd <br />\r\n"); + free(html); + html = blogc_content_parse_inline("asd \r\n"); + assert_non_null(html); + assert_string_equal(html, "asd \r\n"); + free(html); +} + + int main(void) { @@ -1151,14 +1639,23 @@ main(void) unit_test(test_slugify), unit_test(test_is_ordered_list_item), unit_test(test_content_parse), + unit_test(test_content_parse_crlf), unit_test(test_content_parse_with_excerpt), + unit_test(test_content_parse_with_excerpt_crlf), unit_test(test_content_parse_header), + unit_test(test_content_parse_header_crlf), unit_test(test_content_parse_html), + unit_test(test_content_parse_html_crlf), unit_test(test_content_parse_blockquote), + unit_test(test_content_parse_blockquote_crlf), unit_test(test_content_parse_code), + unit_test(test_content_parse_code_crlf), unit_test(test_content_parse_horizontal_rule), + unit_test(test_content_parse_horizontal_rule_crlf), unit_test(test_content_parse_unordered_list), + unit_test(test_content_parse_unordered_list_crlf), unit_test(test_content_parse_ordered_list), + unit_test(test_content_parse_ordered_list_crlf), unit_test(test_content_parse_invalid_excerpt), unit_test(test_content_parse_invalid_header), unit_test(test_content_parse_invalid_header_empty), @@ -1175,6 +1672,7 @@ main(void) unit_test(test_content_parse_inline_link_auto), unit_test(test_content_parse_inline_image), unit_test(test_content_parse_inline_line_break), + unit_test(test_content_parse_inline_line_break_crlf), }; return run_tests(tests); } |