From bc940fdee98b3b33cc1c065e117976a97883f6cf Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Mon, 9 Mar 2026 00:09:35 +0900 Subject: [PATCH] add theme --- Makefile | 2 +- Makefile.watcom | 2 + src/classic.c | 27 +---- src/default.c | 19 +-- src/image/fill.c | 8 +- src/process.c | 16 +++ src/seed.c | 4 +- src/simple.c | 297 +++++++++++++++++++++++++++++++++++++++++++++++ src/site.c | 37 +++++- 9 files changed, 372 insertions(+), 40 deletions(-) diff --git a/Makefile b/Makefile index ed50e8b..fc1bcd8 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC ?= cc -CFLAGS ?= -I external/xemil/include -I src +CFLAGS ?= -I external/xemil/include -I src $(DEFS) LDFLAGS ?= LIBS ?= AFTER ?= diff --git a/Makefile.watcom b/Makefile.watcom index d2f45ee..8b76ae1 100644 --- a/Makefile.watcom +++ b/Makefile.watcom @@ -1,5 +1,7 @@ CC = owcc -bnt +DEFS = -DSTBI_NO_SIMD E = .exe AFTER = wrc -q -bt=nt src/taiga.rc taiga.exe +LIBS = include Makefile diff --git a/src/classic.c b/src/classic.c index 7ac3ff6..4cfb163 100644 --- a/src/classic.c +++ b/src/classic.c @@ -123,6 +123,7 @@ void classic_stylesheet(FILE* out, const char* top) { fprintf(out, " padding: 0.33em 0 0.67em 5px;\n"); fprintf(out, " margin: 0.67em 0;\n"); fprintf(out, "}\n"); + fprintf(out, "\n"); } } @@ -186,7 +187,7 @@ void classic_body(FILE* out, const char* top, const char* title, xl_node_t* body sitesearch = "https://invalid.link"; fprintf(out, " \n"); - fprintf(out, " \n"); + fprintf(out, " \n"); fprintf(out, " \n"); fprintf(out, "
\n"); for(i = 0; i < sizeof(images) / sizeof(images[0]); i++) { char path[64]; @@ -228,7 +229,7 @@ void classic_body(FILE* out, const char* top, const char* title, xl_node_t* body fprintf(out, "
\n"); fprintf(out, " \n"); - fprintf(out, " \n"); + fprintf(out, " \n"); fprintf(out, " \n"); - fprintf(out, " \n"); fprintf(out, " \n"); fprintf(out, " \n"); fprintf(out, "
\n"); if((nodes = xl_get_path(skinconf->root, "breadcrumb.link")) != NULL) { int i; @@ -252,7 +253,7 @@ void classic_body(FILE* out, const char* top, const char* title, xl_node_t* body free(nodes); } fprintf(out, " \n"); + fprintf(out, " \n"); fprintf(out, "
\n"); fprintf(out, " Search\n"); fprintf(out, " \n", sitesearch); @@ -304,25 +305,9 @@ void classic_body(FILE* out, const char* top, const char* title, xl_node_t* body fprintf(out, "
\n"); - fprintf(out, " \"Valid\n", top); - fprintf(out, " \"Valid\n", top); + fprintf(out, " \"Valid\n", top); + fprintf(out, " \"Valid\n", top); fprintf(out, " \n"); fprintf(out, "
\n"); - fprintf(out, " \n"); } diff --git a/src/default.c b/src/default.c index 42732f0..6f116d6 100644 --- a/src/default.c +++ b/src/default.c @@ -121,9 +121,9 @@ void default_body(FILE* out, const char* top, xl_node_t* element, int indent) { sprintf(tag + strlen(tag), " \n"); sprintf(tag + strlen(tag), " \n"); sprintf(tag + strlen(tag), " \n"); - sprintf(tag + strlen(tag), " \n"); sprintf(tag + strlen(tag), " \n"); @@ -146,7 +146,13 @@ void default_body(FILE* out, const char* top, xl_node_t* element, int indent) { strcmp(element->name, "sub") == 0 || /**/ strcmp(element->name, "sup") == 0 || /**/ strcmp(element->name, "tr") == 0 || /**/ - strcmp(element->name, "em") == 0) { + strcmp(element->name, "em") == 0 || /**/ + strcmp(element->name, "h1") == 0 || /**/ + strcmp(element->name, "h2") == 0 || /**/ + strcmp(element->name, "h3") == 0 || /**/ + strcmp(element->name, "h4") == 0 || /**/ + strcmp(element->name, "h5") == 0 || /**/ + strcmp(element->name, "h6") == 0) { accept_attr(text, element, "id", "class", NULL); sprintf(tag, "<%s%s>", element->name, text); @@ -173,12 +179,11 @@ void default_body(FILE* out, const char* top, xl_node_t* element, int indent) { sprintf(end, "", element->name); } else if(strcmp(element->name, "img") == 0) { - accept_attr(text, element, "src", "alt", "title", "height", "width", "id", - "class", NULL); + xl_attribute_t* attr = element->first_attribute; - sprintf(tag, "<%s%s>", element->name, text); + accept_attr(text, element, "src", "alt", "title", "height", "width", "id", "class", NULL); - sprintf(end, "", element->name); + sprintf(tag, "<%s%s border=\"0\">", element->name, text); } else if(strcmp(element->name, "script") == 0) { accept_attr(text, element, "src", "type", NULL); diff --git a/src/image/fill.c b/src/image/fill.c index 96e0c30..2a1b13e 100644 --- a/src/image/fill.c +++ b/src/image/fill.c @@ -1,6 +1,6 @@ unsigned char image_fill[] = { - 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0xf0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3b}; + 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3b}; unsigned int image_fill_len = 43; diff --git a/src/process.c b/src/process.c index 71ac688..b191319 100644 --- a/src/process.c +++ b/src/process.c @@ -71,6 +71,7 @@ static int parse_file(const char* top, const char* full) { site_head(f, top, header); + fprintf(f, " \n", top); if(!has_own_icon && (nodes = xl_get_path(skinconf->root, "favicon")) != NULL) { if(nodes[0]->text != NULL) { char* p = u_path(top, nodes[0]->text); @@ -84,6 +85,21 @@ static int parse_file(const char* top, const char* full) { fprintf(f, " \n"); fprintf(f, " \n"); site_body(f, top, title, body); + fprintf(f, " \n"); fprintf(f, " \n"); fprintf(f, "\n"); diff --git a/src/seed.c b/src/seed.c index 2c321cc..b681858 100644 --- a/src/seed.c +++ b/src/seed.c @@ -84,9 +84,11 @@ int action_seed(int argc, char** argv) { fprintf(f, " \n"); fprintf(f, " \n"); fprintf(f, " \n"); + fprintf(f, " \n"); + fprintf(f, " classic\n"); fprintf(f, " \n"); fprintf(f, " Example Co, Ltd\n"); - fprintf(f, " %d\n", 1900 + tm->tm_year); + fprintf(f, " %d \n", 1900 + tm->tm_year); fprintf(f, " \n"); fprintf(f, " \n"); fprintf(f, "\n"); diff --git a/src/simple.c b/src/simple.c index 2a5b17a..307a827 100644 --- a/src/simple.c +++ b/src/simple.c @@ -1,10 +1,307 @@ #include void simple_stylesheet(FILE* out, const char* top) { + char* messages[] = { + "fixme", /**/ + "warning", /**/ + "note" /**/ + }; + int i; + + fprintf(out, "body {\n"); + fprintf(out, " padding: 0;\n"); + fprintf(out, " margin: 0;\n"); + fprintf(out, " background-color: #c0c0c0;\n"); + fprintf(out, " color: #000000;\n"); + fprintf(out, " font-family: \"Times New Roman\", Times, serif;\n"); + fprintf(out, " font-size: 16px;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "a:link {\n"); + fprintf(out, " color: #0000ee;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "a:visited {\n"); + fprintf(out, " color: #551a8b;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "a:hover {\n"); + fprintf(out, " color: #ff0000;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "#page {\n"); + fprintf(out, " width: 760px;\n"); + fprintf(out, " margin: 12px auto;\n"); + fprintf(out, " background-color: #ffffff;\n"); + fprintf(out, " border: 2px solid #808080;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "#banner {\n"); + fprintf(out, " background-color: #000080;\n"); + fprintf(out, " color: #ffffff;\n"); + fprintf(out, " padding: 12px;\n"); + fprintf(out, " border-bottom: 2px solid #808080;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "h1, h2, h3, h4, h5, h6, .linkgrouptitle {\n"); + fprintf(out, " font-family: Arial, Helvetica, sans-serif;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "#banner h1, .box h2 {\n"); + fprintf(out, " margin: 0;\n"); + fprintf(out, " padding: 0;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "#banner p {\n"); + fprintf(out, " margin-top: 6px;\n"); + fprintf(out, " margin-bottom: 0;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "#nav {\n"); + fprintf(out, " width: 190px;\n"); + fprintf(out, " background-color: #dcdcdc;\n"); + fprintf(out, " border-right: 1px solid #808080;\n"); + fprintf(out, " padding: 12px;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, ".box {\n"); + fprintf(out, " margin-bottom: 16px;\n"); + fprintf(out, " border: 1px solid #808080;\n"); + fprintf(out, " background-color: #f4f4f4;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, ".box h2 {\n"); + fprintf(out, " padding: 6px 8px;\n"); + fprintf(out, " background-color: #c0c0c0;\n"); + fprintf(out, " border-bottom: 1px solid #808080;\n"); + fprintf(out, " font-size: 15px;\n"); + fprintf(out, "\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, ".box-content {\n"); + fprintf(out, " margin: 0;\n"); + fprintf(out, " padding-top: 8px;\n"); + fprintf(out, " padding-bottom: 18px;\n"); + fprintf(out, " padding-left: 8px;\n"); + fprintf(out, " padding-right: 26px;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, ".linkgroup {\n"); + fprintf(out, " padding-left: 12px;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, ".linkgrouptitle {\n"); + fprintf(out, " font-weight: bold;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "#footer {\n"); + fprintf(out, " margin-top: 24px;\n"); + fprintf(out, " padding-top: 8px;\n"); + fprintf(out, " border-top: 1px solid #808080;\n"); + fprintf(out, " font-size: 13px;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "#content {\n"); + fprintf(out, " padding: 18px;\n"); + fprintf(out, "}\n"); + fprintf(out, ".grid {\n"); + fprintf(out, " border-collapse: collapse;\n"); + fprintf(out, " margin-top: 10px 0;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, ".grid, .grid th, .grid td {\n"); + fprintf(out, " border: none;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, ".grid th, .grid td {\n"); + fprintf(out, " border: 1px solid #808080;\n"); + fprintf(out, " padding: 6px;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, ".grid th {\n"); + fprintf(out, " text-align: left;\n"); + fprintf(out, " background-color: #dcdcdc;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "h1 {\n"); + fprintf(out, " font-size: 30px;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "h2 {\n"); + fprintf(out, " font-size: 24px;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "h3 {\n"); + fprintf(out, " font-size: 18px;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "h4 {\n"); + fprintf(out, " font-size: 17px;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "h5 {\n"); + fprintf(out, " font-size: 16px;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, "h6 {\n"); + fprintf(out, " font-size: 16px;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, ".section {\n"); + fprintf(out, " font-size: 24px;\n"); + fprintf(out, " font-family: Arial, Helvetica, sans-serif;\n"); + fprintf(out, " border-bottom: 1px solid #808080;\n"); + fprintf(out, " padding: 4px 0;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, ".message-icon {\n"); + fprintf(out, " padding-right: 5px;\n"); + ; + fprintf(out, "}\n"); + fprintf(out, "\n"); + fprintf(out, ".message-title {\n"); + fprintf(out, " font-family: Arial, Helvetica, sans-serif;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + + for(i = 0; i < sizeof(messages) / sizeof(messages[0]); i++) { + fprintf(out, ".%s-message {\n", messages[i]); + fprintf(out, " border: 1px solid #808080;\n"); + fprintf(out, " margin: 0.67em 0;\n"); + fprintf(out, " padding: 8px;\n"); + fprintf(out, " background-color: #ffffe0;\n"); + fprintf(out, "}\n"); + fprintf(out, "\n"); + } } void simple_head(FILE* out, const char* top, xl_node_t* header) { } void simple_body(FILE* out, const char* top, const char* title, xl_node_t* body) { + char year[4 + 1 + 4 + 1]; /* no one would use our software in year 10000... right? :) */ + char* holder = "Unknown people"; + char* project = "Unknown project"; + char* project_desc = "Unknown project description"; + xl_node_t** nodes; + xl_node_t* child; + char* text; + char* link; + + strcpy(year, "Some year"); + + if((nodes = xl_get_path(skinconf->root, "copyright.holder")) != NULL) { + holder = nodes[0]->text; + + free(nodes); + } + + if((nodes = xl_get_path(skinconf->root, "project.name")) != NULL) { + project = nodes[0]->text; + + free(nodes); + } + + if((nodes = xl_get_path(skinconf->root, "project.description")) != NULL) { + project_desc = nodes[0]->text; + + free(nodes); + } + + /* should this be default behavior? */ + if(strcmp(top, "") != 0 && title != NULL) project_desc = (char*)title; + + if((nodes = xl_get_path(skinconf->root, "copyright.year")) != NULL) { + time_t t = time(NULL); + struct tm* tm = localtime(&t); + int cyear = tm->tm_year + 1900; + int xyear = atoi(nodes[0]->text); + + if(cyear == xyear) { + sprintf(year, "%d", cyear); + } else { + int low = cyear < xyear ? cyear : xyear; + int high = cyear > xyear ? cyear : xyear; + + sprintf(year, "%d-%d", low, high); + } + + free(nodes); + } + + fprintf(out, "
\n"); - sprintf(tag + strlen(tag), " \n", top, element->name); + sprintf(tag + strlen(tag), " \"%s\"\n", top, element->name, say); sprintf(tag + strlen(tag), " \n"); + sprintf(tag + strlen(tag), " \n"); sprintf(tag + strlen(tag), " %s%s\n", say, author); sprintf(tag + strlen(tag), "
\n"); + fprintf(out, " \n"); + fprintf(out, " \n"); + fprintf(out, " \n"); + fprintf(out, " \n"); + fprintf(out, " \n"); + fprintf(out, " \n"); + fprintf(out, " \n"); + fprintf(out, "
\n"); + fprintf(out, " \n"); + fprintf(out, " \n"); + fprintf(out, " \n"); + fprintf(out, " \n"); + fprintf(out, " \n"); + fprintf(out, "
\n"); + fprintf(out, "

%s

\n", project); + fprintf(out, "

%s

\n", project_desc); + fprintf(out, "
\n"); + + link = NULL; + if((nodes = xl_get_path(skinconf->root, "project.link")) != NULL) { + link = xl_get_attribute(nodes[0], "href"); + } + if(link == NULL) link = "https://invalid.link"; + link = u_path(top, link); + + text = NULL; + if((nodes = xl_get_path(skinconf->root, "project.image")) != NULL) { + text = xl_get_attribute(nodes[0], "src"); + if(text != NULL) text = u_path(top, text); + } + + if(text != NULL) { + fprintf(out, " \"Project\n", link, text); + free(text); + } + + free(link); + + fprintf(out, "
\n"); + fprintf(out, "
\n"); + fprintf(out, "
\n"); + fprintf(out, "

LINKS

\n"); + fprintf(out, "
\n"); + if((nodes = xl_get_path(skinconf->root, "nav")) != NULL) { + int i; + + child = nodes[0]->first_child; + while(child != NULL) { + default_nav(out, top, child, 8); + + child = child->next; + } + + free(nodes); + } + fprintf(out, "
\n"); + fprintf(out, "
\n"); + fprintf(out, "
\n"); + + child = body->first_child; + while(child != NULL) { + default_body(out, top, child, 5); + + child = child->next; + } + + fprintf(out, "
\n"); + fprintf(out, " \"Valid\n", top); + fprintf(out, " \"Valid\n", top); + fprintf(out, "

\n"); + fprintf(out, " Copyright © %s %s%s All rights reserved.\n", year, holder, (strlen(holder) > 0 && holder[strlen(holder) - 1] == '.') ? "" : "."); + fprintf(out, "

\n"); + fprintf(out, "
\n"); + fprintf(out, "
\n"); } diff --git a/src/site.c b/src/site.c index fe3a31e..18b1971 100644 --- a/src/site.c +++ b/src/site.c @@ -84,25 +84,50 @@ static int scan(const char* top, const char* path) { site_body = x##_body; int action_site(int argc, char** argv) { - int st = 0; - FILE* css; + int st = 0; + FILE* css; + xl_node_t** nodes; io_mkdir("build", 0755); - USE_THEME(simple); - - if((skinconf = xl_open_file("site/skinconf.xml")) == NULL || - !xl_parse(skinconf)) { + 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; } + USE_THEME(classic); + if((nodes = xl_get_path(skinconf->root, "skin")) != NULL) { + if(nodes[0]->text != NULL) { + if(strcmp(nodes[0]->text, "classic") == 0) { + USE_THEME(classic); + } else if(strcmp(nodes[0]->text, "simple") == 0) { + USE_THEME(simple); + } else { + fprintf(stderr, "Unknown skin: %s\n", nodes[0]->text); + st = 1; + goto cleanup; + } + } + + free(nodes); + } + if((css = fopen("build/style.css", "w")) == NULL) { st = 1; goto cleanup; } site_stylesheet(css, "build/"); + + if((nodes = xl_get_path(skinconf->root, "extra-css")) != NULL) { + if(nodes[0]->text != NULL) { + fwrite("\n", 1, 1, css); + fwrite(nodes[0]->text, 1, strlen(nodes[0]->text), css); + } + + free(nodes); + } + fclose(css); if(!scan("", "")) {