diff options
-rw-r--r-- | man/blogc-template.7.ronn | 16 | ||||
-rw-r--r-- | man/blogc.1.ronn | 7 | ||||
-rw-r--r-- | src/blogc/main.c | 33 | ||||
-rw-r--r-- | src/blogc/renderer.c | 10 | ||||
-rw-r--r-- | src/blogc/renderer.h | 2 | ||||
-rwxr-xr-x | tests/blogc/check_blogc.sh.in | 109 | ||||
-rw-r--r-- | tests/blogc/check_renderer.c | 131 |
7 files changed, 283 insertions, 25 deletions
diff --git a/man/blogc-template.7.ronn b/man/blogc-template.7.ronn index cf397b7..f418654 100644 --- a/man/blogc-template.7.ronn +++ b/man/blogc-template.7.ronn @@ -74,7 +74,7 @@ This is how a `listing_once` block is defined: will be included only once. {% endblock %} -This is a 'real life' usage example of a `listing_once` block, supposing +This is a 'real world' usage example of a `listing_once` block, supposing that the `TITLE` variable is defined: {% block listing_once %} @@ -90,9 +90,9 @@ that the `TITLE` variable is defined: ### listing_entry block This block is identical to the `entry` block, but its content is included in -the output file only when blogc(1) is called with `-l` and `-e` <SOURCE>. The -variables available in the block are provided by the source file provided -using `-e`. +the output file only when blogc(1) is called with `-l` and `-e` <SOURCE> +options. The variables available in the block are provided by the source +file provided using `-e` <SOURCE> option. This is how a `listing_entry` block is defined: @@ -101,6 +101,14 @@ This is how a `listing_entry` block is defined: content provided by a single entry. {% endblock %} +When multiple `listing_entry` blocks are defined, blogc(1) should be called +with multiple `-e` <SOURCE> options. If a `listing_entry` block does not have +a corresponding `-e` <SOURCE> option, or if its value is an empty string, +the content of the `listing_entry` block is not included. + +`listing_entry` blocks inside iterator are evaluated as multiple blocks and +also require multiple `-e` <SOURCE> options. blogc(1) won't use the same +source for every iteration. ## TEMPLATE VARIABLES diff --git a/man/blogc.1.ronn b/man/blogc.1.ronn index 8b5b52f..11f7808 100644 --- a/man/blogc.1.ronn +++ b/man/blogc.1.ronn @@ -57,8 +57,11 @@ designed to be used with make(1). * `-e` <SOURCE>: When used together with `-l` the source file will be parsed and its content - will be made available for usage in the templates in listing mode. See - blogc-template(7) for details. + will be made available for usage in the templates in listing mode via + `listing_entry` blocks. This option can be used more than once, so users can + have more than one `listing_entry` block in the same template. Passing an + empty string will skip the `listing_entry` block. See blogc-template(7) for + details. * `-D` <KEY>=<VALUE>: Set global configuration parameter. <KEY> must be an ascii uppercase string, diff --git a/src/blogc/main.c b/src/blogc/main.c index 550aec8..6a1839f 100644 --- a/src/blogc/main.c +++ b/src/blogc/main.c @@ -161,7 +161,6 @@ main(int argc, char **argv) bool debug = false; bool input_stdin = false; bool listing = false; - char *listing_entry = NULL; char *template = NULL; char *output = NULL; char *print = NULL; @@ -169,7 +168,8 @@ main(int argc, char **argv) char **pieces = NULL; bc_slist_t *sources = NULL; - bc_trie_t *listing_entry_source = NULL; + bc_slist_t *listing_entries = NULL; + bc_slist_t *listing_entries_source = NULL; bc_trie_t *config = bc_trie_new(free); bc_trie_insert(config, "BLOGC_VERSION", bc_strdup(PACKAGE_VERSION)); @@ -194,9 +194,9 @@ main(int argc, char **argv) break; case 'e': if (argv[i][2] != '\0') - listing_entry = bc_strdup(argv[i] + 2); + listing_entries = bc_slist_append(listing_entries, bc_strdup(argv[i] + 2)); else if (i + 1 < argc) - listing_entry = bc_strdup(argv[++i]); + listing_entries = bc_slist_append(listing_entries, bc_strdup(argv[++i])); break; case 't': if (argv[i][2] != '\0') @@ -316,12 +316,19 @@ main(int argc, char **argv) goto cleanup2; } - if (listing && listing_entry != NULL) { - listing_entry_source = blogc_source_parse_from_file(listing_entry, &err); - if (err != NULL) { - bc_error_print(err, "blogc"); - rv = 1; - goto cleanup2; + if (listing) { + for (bc_slist_t *tmp = listing_entries; tmp != NULL; tmp = tmp->next) { + if (0 == strlen(tmp->data)) { + listing_entries_source = bc_slist_append(listing_entries_source, NULL); + continue; + } + bc_trie_t *e = blogc_source_parse_from_file(tmp->data, &err); + if (err != NULL) { + bc_error_print(err, "blogc"); + rv = 1; + goto cleanup2; + } + listing_entries_source = bc_slist_append(listing_entries_source, e); } } @@ -360,7 +367,7 @@ main(int argc, char **argv) if (debug) blogc_debug_template(l); - char *out = blogc_render(l, s, listing_entry_source, config, listing); + char *out = blogc_render(l, s, listing_entries_source, config, listing); bool write_to_stdout = (output == NULL || (0 == strcmp(output, "-"))); @@ -394,8 +401,8 @@ cleanup: free(template); free(output); free(print); - free(listing_entry); - bc_trie_free(listing_entry_source); + bc_slist_free_full(listing_entries, free); + bc_slist_free_full(listing_entries_source, (bc_free_func_t) bc_trie_free); bc_slist_free_full(sources, free); return rv; } diff --git a/src/blogc/renderer.c b/src/blogc/renderer.c index 87b3f5a..140a86e 100644 --- a/src/blogc/renderer.c +++ b/src/blogc/renderer.c @@ -166,7 +166,8 @@ blogc_split_list_variable(const char *name, bc_trie_t *global, bc_trie_t *local) char* -blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_trie_t *listing_entry, bc_trie_t *config, bool listing) +blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries, + bc_trie_t *config, bool listing) { if (tmpl == NULL) return NULL; @@ -194,6 +195,7 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_trie_t *listing_entry, bc int cmp = 0; bc_slist_t *tmp = tmpl; + bc_slist_t *current_listing_entry = listing_entries; while (tmp != NULL) { blogc_template_node_t *node = tmp->data; @@ -222,8 +224,12 @@ blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_trie_t *listing_entry, bc tmp_source = current_source != NULL ? current_source->data : NULL; } if (0 == strcmp("listing_entry", node->data[0])) { + bc_trie_t *listing_entry = NULL; + if (current_listing_entry != NULL) { + listing_entry = current_listing_entry->data; + current_listing_entry = current_listing_entry->next; + } if (listing_entry == NULL || !listing) { - // we can just skip anything and walk until the next // 'endblock' while (node->type != BLOGC_TEMPLATE_NODE_ENDBLOCK) { diff --git a/src/blogc/renderer.h b/src/blogc/renderer.h index 8f2516a..b40da91 100644 --- a/src/blogc/renderer.h +++ b/src/blogc/renderer.h @@ -18,7 +18,7 @@ char* blogc_format_variable(const char *name, bc_trie_t *global, bc_trie_t *loca bc_slist_t *foreach_var); bc_slist_t* blogc_split_list_variable(const char *name, bc_trie_t *global, bc_trie_t *local); -char* blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_trie_t *listing_entr, +char* blogc_render(bc_slist_t *tmpl, bc_slist_t *sources, bc_slist_t *listing_entries, bc_trie_t *config, bool listing); #endif /* _RENDERER_H */ diff --git a/tests/blogc/check_blogc.sh.in b/tests/blogc/check_blogc.sh.in index 3e0b8d7..87b71fa 100755 --- a/tests/blogc/check_blogc.sh.in +++ b/tests/blogc/check_blogc.sh.in @@ -170,7 +170,7 @@ cat > "${TEMP}/main.tmpl" <<EOF <title>{% ifdef FOO1 %}{{ FOO1 }} {% endif %}{% block entry %}{{ TITLE }}{% endblock %}{% block listing_once %}{{ SITE_TITLE }}{% endblock %}</title> </head> <body> - <a href="{{ BASE_URL }}/"><div class="name">{{ SITE_TITLE }}</div></a>{% block listing_entry %}{{ CONTENT }}{% endblock %} + <a href="{{ BASE_URL }}/"><div class="name">{{ SITE_TITLE }}</div></a>{% block listing_entry %}{{ CONTENT }}{% endblock %}{% block listing_entry %}{{ CONTENT }}{% endblock %} {% block listing_once %} <section class="main"> <div class="container"> @@ -469,6 +469,113 @@ echo -e "${TEMP}/post1.txt\n${TEMP}/post2.txt" | ${TESTS_ENVIRONMENT} @abs_top_b diff -uN "${TEMP}/output12.html" "${TEMP}/expected-output3.html" +cat > "${TEMP}/expected-output4.html" <<EOF +<!DOCTYPE html> +<html lang="en"> + <head> + <title>Chunda's website</title> + </head> + <body> + <a href="/"><div class="name">Chunda's website</div></a><p>foo?</p> + + + <section class="main"> + <div class="container"> + <div class="content"> + <div class="page-heading">Blog</div> + <ul> + + + <li class="post-item"> + <div class="meta">Jan 01, 2010, 11:11 AM GMT</div> + <a href="/post/post1/"><div>foo</div></a> + </li> + + <li class="post-item"> + <div class="meta">Jan 01, 2010, 10:22 PM GMT</div> + <a href="/post/post2/"><div>bar</div></a> + </li> + + + </ul> + </div> + </div> + </section> + + + </body> +</html> +EOF + +${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \ + -D BASE_DOMAIN=http://bola.com/ \ + -D BASE_URL= \ + -D SITE_TITLE="Chunda's website" \ + -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \ + -e "" \ + -e "${TEMP}/post1.txt" \ + -e "${TEMP}/post3.txt" \ + -t "${TEMP}/main.tmpl" \ + -o "${TEMP}/output13.html" \ + -l \ + "${TEMP}/post1.txt" "${TEMP}/post2.txt" + +diff -uN "${TEMP}/output13.html" "${TEMP}/expected-output4.html" + + +cat > "${TEMP}/expected-output5.html" <<EOF +<!DOCTYPE html> +<html lang="en"> + <head> + <title>Chunda's website</title> + </head> + <body> + <a href="/"><div class="name">Chunda's website</div></a><p>foo?</p> +<p>bar?</p> + + + <section class="main"> + <div class="container"> + <div class="content"> + <div class="page-heading">Blog</div> + <ul> + + + <li class="post-item"> + <div class="meta">Jan 01, 2010, 11:11 AM GMT</div> + <a href="/post/post1/"><div>foo</div></a> + </li> + + <li class="post-item"> + <div class="meta">Jan 01, 2010, 10:22 PM GMT</div> + <a href="/post/post2/"><div>bar</div></a> + </li> + + + </ul> + </div> + </div> + </section> + + + </body> +</html> +EOF + +${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \ + -D BASE_DOMAIN=http://bola.com/ \ + -D BASE_URL= \ + -D SITE_TITLE="Chunda's website" \ + -D DATE_FORMAT="%b %d, %Y, %I:%M %p GMT" \ + -e "${TEMP}/post1.txt" \ + -e "${TEMP}/post3.txt" \ + -t "${TEMP}/main.tmpl" \ + -o "${TEMP}/output14.html" \ + -l \ + "${TEMP}/post1.txt" "${TEMP}/post2.txt" + +diff -uN "${TEMP}/output14.html" "${TEMP}/expected-output5.html" + echo "{% block listig %}foo{% endblock %}\n" > "${TEMP}/error.tmpl" ${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc \ diff --git a/tests/blogc/check_renderer.c b/tests/blogc/check_renderer.c index 479c239..c1a9f9d 100644 --- a/tests/blogc/check_renderer.c +++ b/tests/blogc/check_renderer.c @@ -234,13 +234,75 @@ test_render_listing_entry2(void **state) bc_trie_t *entry = bc_trie_new(free); bc_trie_insert(entry, "FUUUUU", bc_strdup("XD")); bc_trie_insert(entry, "BAAAAA", bc_strdup(":p")); - char *out = blogc_render(l, s, entry, NULL, true); - bc_trie_free(entry); + bc_slist_t *e = NULL; + e = bc_slist_append(e, entry); + char *out = blogc_render(l, s, e, NULL, true); + bc_slist_free_full(e, (bc_free_func_t) bc_trie_free); assert_string_equal(out, "foo\n" "fuuu\n" "\n" "XD\n" + "\n" + "\n" + "03:04\n" + "bola: asd\n" + "lol foo haha lol bar haha lol baz haha \n" + "\n" + "\n" + "2014-02-03 04:05:06\n" + "bola: asd2\n" + "\n" + "\n" + "\n" + "2013-01-02 03:04:05\n" + "bola: asd3\n" + "\n" + "\n" + "\n"); + blogc_template_free_ast(l); + bc_slist_free_full(s, (bc_free_func_t) bc_trie_free); + free(out); +} + + +static void +test_render_listing_entry3(void **state) +{ + const char *str = + "foo\n" + "{% block listing_once %}fuuu{% endblock %}\n" + "{% block entry %}\n" + "{% ifdef GUDA %}{{ GUDA }}{% endif %}\n" + "{% ifdef CHUNDA %}{{ CHUNDA }}{% endif %}\n" + "{% endblock %}\n" + "{% block listing_entry %}{{ FUUUUU }}{% endblock %}\n" + "{% block listing_entry %}{{ BAAAAA }}{% endblock %}\n" + "{% block listing %}\n" + "{% ifdef DATE_FORMATTED %}{{ DATE_FORMATTED }}{% endif %}\n" + "bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n" + "{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n" + "{% foreach TAGS_ASD %}yay{% endforeach %}\n" + "{% endblock %}\n"; + bc_error_t *err = NULL; + bc_slist_t *l = blogc_template_parse(str, strlen(str), &err); + assert_non_null(l); + assert_null(err); + bc_slist_t *s = create_sources(3); + assert_non_null(s); + bc_trie_t *entry = bc_trie_new(free); + bc_trie_insert(entry, "FUUUUU", bc_strdup("XD")); + bc_trie_insert(entry, "BAAAAA", bc_strdup(":p")); + bc_slist_t *e = NULL; + e = bc_slist_append(e, NULL); + e = bc_slist_append(e, entry); + char *out = blogc_render(l, s, e, NULL, true); + bc_slist_free_full(e, (bc_free_func_t) bc_trie_free); + assert_string_equal(out, + "foo\n" + "fuuu\n" + "\n" + "\n" ":p\n" "\n" "03:04\n" @@ -265,6 +327,69 @@ test_render_listing_entry2(void **state) static void +test_render_listing_entry4(void **state) +{ + const char *str = + "foo\n" + "{% block listing_once %}fuuu{% endblock %}\n" + "{% block entry %}\n" + "{% ifdef GUDA %}{{ GUDA }}{% endif %}\n" + "{% ifdef CHUNDA %}{{ CHUNDA }}{% endif %}\n" + "{% endblock %}\n" + "{% block listing_entry %}{{ FUUUUU }}{% endblock %}\n" + "{% block listing_entry %}{{ DDDDDD }}{% endblock %}\n" + "{% block listing %}\n" + "{% ifdef DATE_FORMATTED %}{{ DATE_FORMATTED }}{% endif %}\n" + "bola: {% ifdef BOLA %}{{ BOLA }}{% endif %}\n" + "{% foreach TAGS %}lol {{ FOREACH_ITEM }} haha {% endforeach %}\n" + "{% foreach TAGS_ASD %}yay{% endforeach %}\n" + "{% endblock %}\n"; + bc_error_t *err = NULL; + bc_slist_t *l = blogc_template_parse(str, strlen(str), &err); + assert_non_null(l); + assert_null(err); + bc_slist_t *s = create_sources(3); + assert_non_null(s); + bc_trie_t *entry1 = bc_trie_new(free); + bc_trie_insert(entry1, "FUUUUU", bc_strdup("XD")); + bc_trie_insert(entry1, "BAAAAA", bc_strdup(":p")); + bc_trie_t *entry2 = bc_trie_new(free); + bc_trie_insert(entry2, "CCCCCC", bc_strdup("er")); + bc_trie_insert(entry2, "DDDDDD", bc_strdup("ty")); + bc_slist_t *e = NULL; + e = bc_slist_append(e, entry1); + e = bc_slist_append(e, entry2); + char *out = blogc_render(l, s, e, NULL, true); + bc_slist_free_full(e, (bc_free_func_t) bc_trie_free); + assert_string_equal(out, + "foo\n" + "fuuu\n" + "\n" + "XD\n" + "ty\n" + "\n" + "03:04\n" + "bola: asd\n" + "lol foo haha lol bar haha lol baz haha \n" + "\n" + "\n" + "2014-02-03 04:05:06\n" + "bola: asd2\n" + "\n" + "\n" + "\n" + "2013-01-02 03:04:05\n" + "bola: asd3\n" + "\n" + "\n" + "\n"); + blogc_template_free_ast(l); + bc_slist_free_full(s, (bc_free_func_t) bc_trie_free); + free(out); +} + + +static void test_render_listing_empty(void **state) { const char *str = @@ -1227,6 +1352,8 @@ main(void) unit_test(test_render_listing), unit_test(test_render_listing_entry), unit_test(test_render_listing_entry2), + unit_test(test_render_listing_entry3), + unit_test(test_render_listing_entry4), unit_test(test_render_listing_empty), unit_test(test_render_ifdef), unit_test(test_render_ifdef2), |