From cd70ca266bb212d6a32d2dd808c7708bb7be6f1f Mon Sep 17 00:00:00 2001 From: Danny van Kooten Date: Thu, 12 Mar 2020 09:30:29 +0100 Subject: move files to src/ subdir --- src/hyde.c | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 src/hyde.c (limited to 'src/hyde.c') diff --git a/src/hyde.c b/src/hyde.c new file mode 100644 index 0000000..332ddab --- /dev/null +++ b/src/hyde.c @@ -0,0 +1,142 @@ +#include +#include +#include "vendor/mpc.h" +#include "hashmap.h" + + +struct post { + char title[64]; + char tags[8][32]; +}; + +char *read_file(char *filename) { + char *input = malloc(BUFSIZ); + unsigned int size = 0; + + FILE *f = fopen(filename, "r"); + if (!f) { + printf("Could not open \"%s\" for reading", filename); + exit(1); + } + + unsigned int read = 0; + while ( (read = fread(input, 1, BUFSIZ, f)) > 0) { + size += read; + input = realloc(input, size + BUFSIZ); + } + + fclose(f); + + input[size] = '\0'; + return input; +} + +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); + if (value == NULL) { + return 1; + } + strcat(dest, value); + return 0; + } + + 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]); + eval(dest, t->children[6], ctx); + } + return 0; + } + + for (int i=0; i < t->children_num; i++) { + eval(dest, t->children[i], ctx); + } + + return 0; +} + +mpc_parser_t *parser_init() { + mpc_parser_t *Symbol = mpc_new("symbol"); + mpc_parser_t *Text = mpc_new("text"); + mpc_parser_t *Var_Open = mpc_new("var_open"); + mpc_parser_t *Var_Close = mpc_new("var_close"); + mpc_parser_t *Var = mpc_new("var"); + 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 *Content = mpc_new("content"); + mpc_parser_t *Template = mpc_new("template"); + mpca_lang(MPCA_LANG_WHITESPACE_SENSITIVE, + " symbol : /[a-zA-Z._]+/ ;" + " var_open : /\{{2} ?/ ;" + " var_close : / ?}{2}/ ;" + " var : ;" + " block_open: /\{\% ?/ ;" + " block_close: / ?\%}/ ;" + " for : \"for \" \" in \" * \"endfor\" ;" + " text : /[^{][^{%]*/ ;" + " content : | | ;" + " template : /^/ * /$/ ;", + Symbol, Var_Open, Var_Close, Var, Block_Open, Block_Close, For, Text, Content, Template, NULL); + return Template; +} + +void template(char *tmpl, struct hashmap *ctx) { + mpc_parser_t *parser = parser_init(); + mpc_result_t r; + + if (mpc_parse("input", tmpl, parser, &r)) { + mpc_ast_print(r.output); + + // FIXME: Allocate precisely + char *output = malloc(strlen(tmpl) * 2); + output[0] = '\0'; + eval(output, r.output, ctx); + printf("Template: \n%s", output); + + mpc_ast_delete(r.output); + free(output); + } else { + mpc_err_print(r.error); + mpc_err_delete(r.error); + } +} + + +int main() { + char *input = read_file("index.tpl"); + + struct hashmap *ctx = hashmap_new(); + hashmap_insert(ctx, "title", "Hello world"); + + struct post home = { + .title = "Homepage", + .tags = { + "Tag 1", "Tag 2" + } + }; + hashmap_insert(ctx, "home", &home); + + struct post posts[] = { + { .title = "Post 1", .tags = { "p1t1" } }, + { .title = "Post 2", .tags = { "p2t1" } }, + }; + hashmap_insert(ctx, "posts", &posts); + + template(input, ctx); + hashmap_free(ctx); + free(input); +} \ No newline at end of file -- cgit v1.2.3