From 07d3a1f7a2bdfa4f5918b515d617eecbd6e081db Mon Sep 17 00:00:00 2001 From: "Rafael G. Martins" Date: Thu, 13 Aug 2015 22:05:20 -0300 Subject: content-parser: implemented multiline support for lists --- src/content-parser.c | 170 ++++++++++++++++++++++++++++++++++++++------------- src/content-parser.h | 2 + 2 files changed, 128 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/content-parser.c b/src/content-parser.c index e5bb16c..9052aec 100644 --- a/src/content-parser.c +++ b/src/content-parser.c @@ -17,7 +17,7 @@ #include "content-parser.h" // this is a half ass implementation of a markdown-like syntax. bugs are -// expected. feel free to improve the parser and and new features. +// expected. feel free to improve the parser and add new features. typedef enum { @@ -356,6 +356,33 @@ blogc_content_parse_inline(const char *src) } +bool +blogc_is_ordered_list_item(const char *str, size_t prefix_len) +{ + if (str == NULL) + return false; + + if (strlen(str) < 2) + return false; + + size_t i; + + for (i = 0; str[i] >= '0' && str[i] <= '9'; i++); + + if (i == 0) + return false; + if (str[i] != '.') + return false; + + for (i++; i < prefix_len && (str[i] == ' ' || str[i] == '\t'); i++); + + if (str[i] == '\0') + return false; + + return i == prefix_len; +} + + char* blogc_content_parse(const char *src, size_t *end_excerpt) { @@ -373,13 +400,12 @@ blogc_content_parse(const char *src, size_t *end_excerpt) size_t prefix_len = 0; char *tmp = NULL; char *tmp2 = NULL; - char *tmp3 = NULL; char *parsed = NULL; - char **tmpv = NULL; char d = '\0'; b_slist_t *lines = NULL; + b_slist_t *lines2 = NULL; b_string_t *rv = b_string_new(); b_string_t *tmp_str = NULL; @@ -664,22 +690,39 @@ hr: if (c == '\n' || c == '\r' || is_last) { end = is_last && c != '\n' && c != '\r' ? src_len : current; tmp = b_strndup(src + start2, end - start2); + tmp2 = b_strdup_printf("%-*s", strlen(prefix), ""); if (b_str_starts_with(tmp, prefix)) { - tmp3 = b_strdup(tmp + strlen(prefix)); - parsed = blogc_content_parse_inline(tmp3); - free(tmp3); - tmp3 = NULL; - lines = b_slist_append(lines, b_strdup(parsed)); - free(parsed); - parsed = NULL; + if (lines2 != NULL) { + tmp_str = b_string_new(); + for (b_slist_t *l = lines2; l != NULL; l = l->next) { + 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_slist_free_full(lines2, free); + lines2 = NULL; + parsed = blogc_content_parse_inline(tmp_str->str); + b_string_free(tmp_str, true); + lines = b_slist_append(lines, b_strdup(parsed)); + free(parsed); + parsed = NULL; + } + lines2 = b_slist_append(lines2, b_strdup(tmp + strlen(prefix))); + } + else if (b_str_starts_with(tmp, tmp2)) { + lines2 = b_slist_append(lines2, b_strdup(tmp + strlen(prefix))); } else { state = CONTENT_PARAGRAPH_END; free(tmp); tmp = NULL; + free(tmp2); + tmp2 = NULL; free(prefix); prefix = NULL; b_slist_free_full(lines, free); + b_slist_free_full(lines2, free); lines = NULL; if (is_last) goto para; @@ -687,6 +730,8 @@ hr: } free(tmp); tmp = NULL; + free(tmp2); + tmp2 = NULL; state = CONTENT_UNORDERED_LIST_END; } if (!is_last) @@ -694,6 +739,23 @@ hr: case CONTENT_UNORDERED_LIST_END: if (c == '\n' || c == '\r' || is_last) { + if (lines2 != NULL) { + // FIXME: avoid repeting the code below + tmp_str = b_string_new(); + for (b_slist_t *l = lines2; l != NULL; l = l->next) { + 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_slist_free_full(lines2, free); + lines2 = NULL; + parsed = blogc_content_parse_inline(tmp_str->str); + b_string_free(tmp_str, true); + lines = b_slist_append(lines, b_strdup(parsed)); + free(parsed); + parsed = NULL; + } b_string_append(rv, "