From a39e8c713e0a8ea9f2f8e455c1ce2b4d0c3f5115 Mon Sep 17 00:00:00 2001 From: Danny van Kooten Date: Thu, 12 Mar 2020 14:45:48 +0100 Subject: evaluate for blocks correctly --- src/template.c | 29 +++++++++++++++-------------- src/template.h | 6 ++++++ tests/test_template.c | 18 ++++++++++++++++-- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/src/template.c b/src/template.c index 1a3c049..c88d90a 100644 --- a/src/template.c +++ b/src/template.c @@ -29,14 +29,9 @@ char *read_file(char *filename) { int eval(char *dest, mpc_ast_t* t, struct hashmap *ctx) { printf("%s: %s\n", t->tag, t->contents); - if (strstr(t->tag, "content|text")) { - strcat(dest, t->contents); - return 0; - } - if (strstr(t->tag, "content|var")) { printf("Key: %s\n", t->contents); - char *value = hashmap_get(ctx, t->children[1]->contents); + char *value = (char *) hashmap_get(ctx, t->children[1]->contents); if (value == NULL) { return 1; } @@ -47,15 +42,19 @@ int eval(char *dest, mpc_ast_t* t, struct hashmap *ctx) { if (strstr(t->tag, "content|for")) { char *tmp_key = t->children[2]->contents; char *iterator_key = t->children[4]->contents; - // TODO: Make this dynamic - struct post **posts = hashmap_get(ctx, iterator_key); - for (int i=0; i < 2; i++) { - hashmap_insert(ctx, tmp_key, posts[i]); + struct list *list = hashmap_get(ctx, iterator_key); + for (int i=0; i < list->size; i++) { + hashmap_insert(ctx, tmp_key, list->values[i]); eval(dest, t->children[6], ctx); } return 0; } + if (strstr(t->tag, "content|text")) { + strcat(dest, t->contents); + return 0; + } + for (int i=0; i < t->children_num; i++) { eval(dest, t->children[i], ctx); } @@ -72,6 +71,7 @@ mpc_parser_t *parser_init() { mpc_parser_t *Block_Open = mpc_new("block_open"); mpc_parser_t *Block_Close = mpc_new("block_close"); mpc_parser_t *For = mpc_new("for"); + mpc_parser_t *Body = mpc_new("body"); mpc_parser_t *Content = mpc_new("content"); mpc_parser_t *Template = mpc_new("template"); mpca_lang(MPCA_LANG_WHITESPACE_SENSITIVE, @@ -81,15 +81,16 @@ mpc_parser_t *parser_init() { " var : ;" " block_open: /\{\% ?/ ;" " block_close: / ?\%}/ ;" - " for : \"for \" \" in \" * \"endfor\" ;" + " for : \"for \" \" in \" \"endfor\" ;" " text : /[^{][^{%]*/ ;" " content : | | ;" - " template : /^/ * /$/ ;", - Symbol, Var_Open, Var_Close, Var, Block_Open, Block_Close, For, Text, Content, Template, NULL); + " body : * ;" + " template : /^/ /$/ ;", + Symbol, Var_Open, Var_Close, Var, Block_Open, Block_Close, For, Text, Content, Body, Template, NULL); return Template; } -char * template(char *tmpl, struct hashmap *ctx) { +char *template(char *tmpl, struct hashmap *ctx) { mpc_parser_t *parser = parser_init(); mpc_result_t r; diff --git a/src/template.h b/src/template.h index 9174ad8..b4d46b3 100644 --- a/src/template.h +++ b/src/template.h @@ -6,4 +6,10 @@ char *template(char *tmpl, struct hashmap *ctx); struct post { char title[64]; char tags[8][32]; +}; + +struct list { + void **values; + int size; + int cap; }; \ No newline at end of file diff --git a/tests/test_template.c b/tests/test_template.c index 88d1ab4..69f1d94 100644 --- a/tests/test_template.c +++ b/tests/test_template.c @@ -30,7 +30,21 @@ TEST(text_multiline) { free(output); } - - +TEST(for_block) { + char *input = "{% for n in numbers %}{{ n }}, {% endfor %}"; + struct hashmap *ctx = hashmap_new(); + struct list numbers; + numbers.size = 0; + numbers.cap = 64; + numbers.values = malloc(numbers.cap * sizeof *numbers.values); + numbers.values[numbers.size++] = "1"; + numbers.values[numbers.size++] = "2"; + numbers.values[numbers.size++] = "3"; + hashmap_insert(ctx, "numbers", &numbers); + char *output = template(input, ctx); + assert_str(output, "1, 2, 3, "); + hashmap_free(ctx); + free(output); +} END_TESTS \ No newline at end of file -- cgit v1.2.3