diff --git a/external/xemil b/external/xemil index e5b592e..e8f00f4 160000 --- a/external/xemil +++ b/external/xemil @@ -1 +1 @@ -Subproject commit e5b592e29a3be4b021836dd364f94c8e4137ef4e +Subproject commit e8f00f411100f7e2cc66d935204cd7e1d058ad71 diff --git a/objs.mk b/objs.mk index 6570a92..d13c745 100644 --- a/objs.mk +++ b/objs.mk @@ -14,6 +14,9 @@ src/external_xemil_src_unicode.o: external/xemil/src/unicode.c OBJS += src/external_xemil_src_util.o src/external_xemil_src_util.o: external/xemil/src/util.c $(CC) $(CFLAGS) -c -o $@ external/xemil/src/util.c +OBJS += src/src_classic.o +src/src_classic.o: src/classic.c + $(CC) $(CFLAGS) -c -o $@ src/classic.c OBJS += src/src_help.o src/src_help.o: src/help.c $(CC) $(CFLAGS) -c -o $@ src/help.c diff --git a/src/process.c b/src/process.c index 4f6024a..d2954c0 100644 --- a/src/process.c +++ b/src/process.c @@ -1,16 +1,98 @@ #include -void process(const char* out, const char* full){ - char* f = strrchr(full, '/'); +static FILE* f; - if(f != NULL) f = f + 1; +static int parse_file(const char* top, const char* full){ + xemil_t* handle = xl_open_file(full); + int st = 1; - if(f != NULL){ - char* n; + handle->new_text = 1; - f = u_strdup(f); - if((n = strrchr(f, '.')) != NULL) n[0] = 0; + if(handle != NULL && xl_parse(handle)){ + if(handle->root == NULL || strcmp(handle->root->name, "document") != 0){ + fprintf(stderr, "Root element has to be document\n"); + st = 0; + } - free(f); + if(st){ + char* title = NULL; + xl_node_t* node = NULL; + xl_node_t* header = NULL; + xl_node_t* body = NULL; + + if(handle->root != NULL) node = handle->root->first_child; + while(node != NULL){ + if(node->type == XL_NODE_NODE && strcmp(node->name, "header") == 0){ + xl_node_t* n = node->first_child; + + while(n != NULL){ + if(n->type == XL_NODE_NODE && strcmp(n->name, "title") == 0){ + if(title != NULL) free(title); + title = u_strdup(n->text); + } + n = n->next; + } + + header = node; + }else if(node->type == XL_NODE_NODE && strcmp(node->name, "body") == 0){ + body = node; + } + + node = node->next; + } + + if(title == NULL) title = u_strdup("Untitled"); + + fprintf(f, "\n"); + fprintf(f, "\n"); + fprintf(f, " \n"); + fprintf(f, " \n"); + fprintf(f, " %s\n", title); + classic_head(f, top, header); + fprintf(f, " \n"); + fprintf(f, " \n"); + classic_body(f, top, title, body); + fprintf(f, " \n"); + fprintf(f, "\n"); + + free(title); + } + }else{ + fprintf(stderr, "Parse failed!\n", full); + st = 0; } + + if(handle != NULL) xl_close(handle); + + return st; +} + +int process(const char* top, const char* out, const char* full){ + char* fn = strrchr(full, '/'); + + if(fn != NULL) fn = fn + 1; + + if(fn != NULL){ + char* n; + char* p; + + fn = u_strdup(fn); + if((n = strrchr(fn, '.')) != NULL) n[0] = 0; + + p = u_strvacat(out, fn, ".html", NULL); + if((f = fopen(p, "w")) != NULL){ + if(!parse_file(top, full)){ + fclose(f); + free(p); + free(fn); + return 0; + } + fclose(f); + } + free(p); + + free(fn); + } + + return 1; } diff --git a/src/seed.c b/src/seed.c index 5daebfd..03bc6bf 100644 --- a/src/seed.c +++ b/src/seed.c @@ -23,9 +23,15 @@ int action_seed(int argc, char** argv){ fprintf(f, "\n"); fprintf(f, "\n"); fprintf(f, " \n"); - fprintf(f, " Example Co, Ltd.\n"); - fprintf(f, " 2026\n"); - fprintf(f, " https://example.com\n"); + fprintf(f, " \n"); + fprintf(f, " \n"); + fprintf(f, " \n"); + fprintf(f, " \n"); + fprintf(f, " \n"); + fprintf(f, " Example Co, Ltd.\n"); + fprintf(f, " 2026\n"); + fprintf(f, " \n"); + fprintf(f, " \n"); fprintf(f, "\n"); fclose(f); @@ -36,7 +42,7 @@ int action_seed(int argc, char** argv){ fprintf(f, "\n"); fprintf(f, "\n"); fprintf(f, "
\n"); - fprintf(f, " Welcome to template\n"); + fprintf(f, " <![CDATA[Welcome to template]]>\n"); fprintf(f, "
\n"); fprintf(f, " \n"); fprintf(f, "
\n"); diff --git a/src/site.c b/src/site.c index 3a99054..47e94e7 100644 --- a/src/site.c +++ b/src/site.c @@ -1,6 +1,8 @@ #include -static void scan(const char* path){ +xemil_t* skinconf; + +static int scan(const char* top, const char* path){ char* in = u_strvacat("site/content/", path, NULL); char* out = u_strvacat("build/", path, NULL); IO_DIR* dir; @@ -19,11 +21,29 @@ static void scan(const char* path){ if(io_stat(p, &s) == 0){ if(IO_S_ISDIR(s.st_mode)){ char* p2 = u_strvacat(d->d_name, "/", NULL); - scan(p2); + char* t = u_strvacat(top, "../", NULL); + if(!scan(t, p2)){ + free(t); + free(p2); + free(p); + io_closedir(dir); + free(out); + free(in); + + return 0; + } + free(t); free(p2); }else if(strcmp(d->d_name, "index.xml") == 0){ - process(out, p); - printf("%s\n", p); + printf("%s:\n", p); + if(!process(top, out, p)){ + free(p); + io_closedir(dir); + free(out); + free(in); + + return 0; + } } } free(p); @@ -34,12 +54,42 @@ static void scan(const char* path){ free(out); free(in); + + return 1; } int action_site(int argc, char** argv){ + int st = 0; + FILE* css; + io_mkdir("build", 0755); - scan(""); + if((skinconf = xl_open_file("site/skinconf.xml")) == NULL || !xl_parse(skinconf)){ + fprintf(stderr, "Failed to parse site/skinconf.xml!\n"); + st = 1; + goto cleanup; + } + + if((css = fopen("build/style.css", "w")) == NULL){ + st = 1; + goto cleanup; + } + classic_stylesheet(css); + fclose(css); + + if(!scan("", "")){ + st = 1; + goto cleanup; + } + +cleanup:; + if(skinconf != NULL) xl_close(skinconf); + + if(st == 0){ + fprintf(stderr, "\nBuild successful\n"); + }else{ + fprintf(stderr, "\nBuild failed!\n"); + } return 0; } diff --git a/src/taiga.h b/src/taiga.h index d72c023..4bd8706 100644 --- a/src/taiga.h +++ b/src/taiga.h @@ -15,6 +15,8 @@ #include #endif +#include + #ifdef _WIN32 #define io_mkdir(x,y) _mkdir(x) #define io_chdir(x) _chdir(x) @@ -36,6 +38,8 @@ #endif /* site.c */ +extern xemil_t* skinconf; + int action_site(int argc, char** argv); /* help.c */ @@ -49,6 +53,11 @@ char* u_strvacat(const char* str, ...); char* u_strdup(const char* str); /* process.c */ -void process(const char* out, const char* full); +int process(const char* top, const char* out, const char* full); + +/* classic.c */ +void classic_stylesheet(FILE* out); +void classic_head(FILE* out, const char* top, xl_node_t* header); +void classic_body(FILE* out, const char* top, const char* title, xl_node_t* body); #endif