From 1605bf39ab342ea5d904fe96df81dd0f55bd3bcf Mon Sep 17 00:00:00 2001 From: "Rafael G. Martins" Date: Mon, 23 May 2016 02:38:22 +0200 Subject: content-parser: fixed DESCRIPTION variable. it is now built as a single line variable, that contains the full unparsed content of the first paragraph found in the source file, instead of just the first line of it. this also fixes a bug that prevented creating of DESCRIPTION variable, if the source file contained only a single line paragraph. --- man/blogc-source.7.ronn | 7 +++--- src/content-parser.c | 45 ++++++++++++++++++++++++++++++++++-- src/content-parser.h | 1 + tests/check_content_parser.c | 55 ++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 98 insertions(+), 10 deletions(-) diff --git a/man/blogc-source.7.ronn b/man/blogc-source.7.ronn index 1945329..9b80eb2 100644 --- a/man/blogc-source.7.ronn +++ b/man/blogc-source.7.ronn @@ -51,9 +51,10 @@ for building permalinks in templates. This variable can't be overriden by an explicit definition in source file. Another variable, `DESCRIPTION`, will be automatically created by the source -parser. Its content is the first line of the first paragraph of the content. -Paragraphs inside blockquotes are ignored. This variable can be overriden by -an explicit definition in source file. +parser. It contains the unparsed content of the first paragraph found in the +source file. Paragraphs inside blockquotes are ignored. This variable can be +overriden by an explicit definition in source file. This is useful to add +"description" meta-tags to HTML templates. ## SOURCE CONTENT - BLOCK ELEMENTS diff --git a/src/content-parser.c b/src/content-parser.c index 4840a1d..3cb0ddb 100644 --- a/src/content-parser.c +++ b/src/content-parser.c @@ -75,6 +75,47 @@ blogc_htmlentities(const char *str) } +char* +blogc_fix_description(const char *paragraph) +{ + if (paragraph == NULL) + return NULL; + sb_string_t *rv = sb_string_new(); + bool last = false; + bool newline = false; + char *tmp = NULL; + size_t start = 0; + size_t current = 0; + while (true) { + switch (paragraph[current]) { + case '\0': + last = true; + case '\r': + case '\n': + if (newline) + break; + tmp = sb_strndup(paragraph + start, current - start); + sb_string_append(rv, sb_str_strip(tmp)); + free(tmp); + tmp = NULL; + if (!last) + sb_string_append_c(rv, ' '); + start = current + 1; + newline = true; + break; + default: + newline = false; + } + if (last) + break; + current++; + } + tmp = sb_strdup(sb_str_strip(rv->str)); + sb_string_free(rv, true); + return tmp; +} + + typedef enum { CONTENT_START_LINE = 1, CONTENT_EXCERPT, @@ -1018,8 +1059,6 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **description) state = CONTENT_PARAGRAPH_END; end = is_last && c != '\n' && c != '\r' ? src_len : (real_end != 0 ? real_end : current); - if (description != NULL && *description == NULL) - *description = sb_strndup(src + start, end - start); } if (!is_last) break; @@ -1027,6 +1066,8 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **description) case CONTENT_PARAGRAPH_END: if (c == '\n' || c == '\r' || is_last) { tmp = sb_strndup(src + start, end - start); + if (description != NULL && *description == NULL) + *description = blogc_fix_description(tmp); parsed = blogc_content_parse_inline(tmp); sb_string_append_printf(rv, "

%s

%s", parsed, line_ending); diff --git a/src/content-parser.h b/src/content-parser.h index 148d5ed..85bd063 100644 --- a/src/content-parser.h +++ b/src/content-parser.h @@ -14,6 +14,7 @@ char* blogc_slugify(const char *str); char* blogc_htmlentities(const char *str); +char* blogc_fix_description(const char *paragraph); char* blogc_content_parse_inline(const char *src); bool blogc_is_ordered_list_item(const char *str, size_t prefix_len); char* blogc_content_parse(const char *src, size_t *end_excerpt, diff --git a/tests/check_content_parser.c b/tests/check_content_parser.c index d3ef2b8..ab6853a 100644 --- a/tests/check_content_parser.c +++ b/tests/check_content_parser.c @@ -59,6 +59,50 @@ test_htmlentities(void **state) } +static void +test_fix_description(void **state) +{ + assert_null(blogc_fix_description(NULL)); + char *s = blogc_fix_description("bola"); + assert_string_equal(s, "bola"); + free(s); + s = blogc_fix_description("bola\n"); + assert_string_equal(s, "bola"); + free(s); + s = blogc_fix_description("bola\r\n"); + assert_string_equal(s, "bola"); + free(s); + s = blogc_fix_description("bola\nguda"); + assert_string_equal(s, "bola guda"); + free(s); + s = blogc_fix_description("bola\nguda\n"); + assert_string_equal(s, "bola guda"); + free(s); + s = blogc_fix_description("bola\r\nguda\r\n"); + assert_string_equal(s, "bola guda"); + free(s); + + s = blogc_fix_description("bola\n guda lol\n asd"); + assert_string_equal(s, "bola guda lol asd"); + free(s); + s = blogc_fix_description("bola\n guda lol\n asd\n"); + assert_string_equal(s, "bola guda lol asd"); + free(s); + s = blogc_fix_description("bola\r\n guda lol\r\n asd\r\n"); + assert_string_equal(s, "bola guda lol asd"); + free(s); + s = blogc_fix_description(" bola\n guda lol\n asd"); + assert_string_equal(s, "bola guda lol asd"); + free(s); + s = blogc_fix_description(" bola\n guda lol\n asd\n"); + assert_string_equal(s, "bola guda lol asd"); + free(s); + s = blogc_fix_description(" bola\r\n guda lol\r\n asd\r\n"); + assert_string_equal(s, "bola guda lol asd"); + free(s); +} + + static void test_is_ordered_list_item(void **state) { @@ -127,7 +171,7 @@ test_content_parse(void **state) assert_non_null(html); assert_int_equal(l, 0); assert_non_null(d); - assert_string_equal(d, "bola"); + assert_string_equal(d, "bola chunda"); assert_string_equal(html, "

um

\n" "

dois

\n" @@ -219,7 +263,7 @@ test_content_parse_crlf(void **state) assert_non_null(html); assert_int_equal(l, 0); assert_non_null(d); - assert_string_equal(d, "bola"); + assert_string_equal(d, "bola chunda"); assert_string_equal(html, "

um

\r\n" "

dois

\r\n" @@ -1136,7 +1180,7 @@ test_content_parse_description(void **state) "

qwe\n" "bar

\n"); assert_non_null(d); - assert_string_equal(d, "qwe"); + assert_string_equal(d, "qwe bar"); free(html); free(d); d = NULL; @@ -1219,7 +1263,7 @@ test_content_parse_description_crlf(void **state) "

qwe\r\n" "bar

\r\n"); assert_non_null(d); - assert_string_equal(d, "qwe"); + assert_string_equal(d, "qwe bar"); free(html); free(d); d = NULL; @@ -1277,7 +1321,7 @@ test_content_parse_invalid_excerpt(void **state) assert_non_null(html); assert_int_equal(l, 0); assert_non_null(d); - assert_string_equal(d, "chunda"); + assert_string_equal(d, "chunda .."); assert_string_equal(html, "

test

\n" "

chunda\n" @@ -2019,6 +2063,7 @@ main(void) const UnitTest tests[] = { unit_test(test_slugify), unit_test(test_htmlentities), + unit_test(test_fix_description), unit_test(test_is_ordered_list_item), unit_test(test_content_parse), unit_test(test_content_parse_crlf), -- cgit v1.2.3-18-g5258