add theme
All checks were successful
pyrite-dev/taiga/pipeline/head This commit looks good

This commit is contained in:
Nishi 2026-03-09 00:09:35 +09:00
commit bc940fdee9
Signed by: nishi
GPG key ID: 27EF69B208EB9343
9 changed files with 372 additions and 40 deletions

View file

@ -1,5 +1,5 @@
CC ?= cc
CFLAGS ?= -I external/xemil/include -I src
CFLAGS ?= -I external/xemil/include -I src $(DEFS)
LDFLAGS ?=
LIBS ?=
AFTER ?=

View file

@ -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

View file

@ -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, " <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%%\">\n");
fprintf(out, " <tr width=\"100%%\">\n");
fprintf(out, " <tr>\n");
fprintf(out, " <td>\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, " </tr>\n");
fprintf(out, " </table>\n");
fprintf(out, " <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%%\" id=\"breadcrumb\">\n");
fprintf(out, " <tr width=\"100%%\">\n");
fprintf(out, " <tr>\n");
fprintf(out, " <td>\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, " </td>\n");
fprintf(out, " <td nowrap=\"1\" align=\"right\">\n");
fprintf(out, " <td nowrap=\"nowrap\" align=\"right\">\n");
fprintf(out, " <form action=\"https://www.google.com/search\" method=\"GET\">\n");
fprintf(out, " Search\n");
fprintf(out, " <input type=\"hidden\" name=\"sitesearch\" value=\"%s\">\n", sitesearch);
@ -304,25 +305,9 @@ void classic_body(FILE* out, const char* top, const char* title, xl_node_t* body
fprintf(out, " </tr>\n");
fprintf(out, " <tr>\n");
fprintf(out, " <td align=\"right\">\n");
fprintf(out, " <a href=\"https://validator.w3.org/check/referer\"><img src=\"%simage/valid-html401.png\" alt=\"Valid HTML 4.01\" border=\"0\"></a>\n", top);
fprintf(out, " <a href=\"https://jigsaw.w3.org/css-validator/\"><img src=\"%simage/valid-css.png\" alt=\"Valid CSS\" border=\"0\"></a>\n", top);
fprintf(out, " <a href=\"https://validator.w3.org/check/referer\"><img src=\"%simage/valid-html401.png\" alt=\"Valid HTML 4.01\" border=\"0\" width=\"88\" height=\"31\"></a>\n", top);
fprintf(out, " <a href=\"https://jigsaw.w3.org/css-validator/\"><img src=\"%simage/valid-css.png\" alt=\"Valid CSS\" border=\"0\" width=\"88\" height=\"31\"></a>\n", top);
fprintf(out, " <td>\n");
fprintf(out, " </tr>\n");
fprintf(out, " </table>\n");
fprintf(out, " <!--[if lte IE 6]>\n");
fprintf(out, " <script language=\"javascript\" type=\"text/javascript\">\n");
fprintf(out, " for(var i = 0; i < document.images.length; i++){\n");
fprintf(out, " var s = document.images[i].src;\n");
fprintf(out, " if(s.indexOf('.png') > 0){\n");
fprintf(out, " var oldw = document.images[i].clientWidth;\n");
fprintf(out, " var oldh = document.images[i].clientHeight;\n");
fprintf(out, " document.images[i].src = '%simage/fill.gif';\n", top);
fprintf(out, " document.images[i].style.filter = \"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='\" + s + \"', sizingMethod='scale')\";\n");
fprintf(out, " "
"document.images[i].style.width = oldw + \"px\";\n");
fprintf(out, " document.images[i].style.height = oldh + \"px\";\n");
fprintf(out, " }\n");
fprintf(out, " }\n");
fprintf(out, " </script>\n");
fprintf(out, " <![endif]-->\n");
}

View file

@ -121,9 +121,9 @@ void default_body(FILE* out, const char* top, xl_node_t* element, int indent) {
sprintf(tag + strlen(tag), " <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%%\">\n");
sprintf(tag + strlen(tag), " <tr>\n");
sprintf(tag + strlen(tag), " <td rowspan=\"2\" class=\"message-icon\">\n");
sprintf(tag + strlen(tag), " <img src=\"%simage/%s.png\">\n", top, element->name);
sprintf(tag + strlen(tag), " <img src=\"%simage/%s.png\" alt=\"%s\" width=\"32\" height=\"32\">\n", top, element->name, say);
sprintf(tag + strlen(tag), " </td>\n");
sprintf(tag + strlen(tag), " <td>\n");
sprintf(tag + strlen(tag), " <td class=\"message-title\">\n");
sprintf(tag + strlen(tag), " <b>%s%s</b>\n", say, author);
sprintf(tag + strlen(tag), " </td>\n");
sprintf(tag + strlen(tag), " </tr>\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, "</%s>", 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, "</%s>", 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);

View file

@ -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;

View file

@ -71,6 +71,7 @@ static int parse_file(const char* top, const char* full) {
site_head(f, top, header);
fprintf(f, " <link rel=\"stylesheet\" href=\"%sstyle.css\">\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, " </head>\n");
fprintf(f, " <body>\n");
site_body(f, top, title, body);
fprintf(f, " <!--[if lte IE 6]>\n");
fprintf(f, " <script language=\"javascript\" type=\"text/javascript\">\n");
fprintf(f, " for(var i = 0; i < document.images.length; i++){\n");
fprintf(f, " var s = document.images[i].src;\n");
fprintf(f, " if(s.indexOf('.png') > 0){\n");
fprintf(f, " var oldw = document.images[i].clientWidth;\n");
fprintf(f, " var oldh = document.images[i].clientHeight;\n");
fprintf(f, " document.images[i].src = '%simage/fill.gif';\n", top);
fprintf(f, " document.images[i].style.filter = \"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='\" + s + \"', sizingMethod='scale')\";\n");
fprintf(f, " document.images[i].style.width = oldw + \"px\";\n");
fprintf(f, " document.images[i].style.height = oldh + \"px\";\n");
fprintf(f, " }\n");
fprintf(f, " }\n");
fprintf(f, " </script>\n");
fprintf(f, " <![endif]-->\n");
fprintf(f, " </body>\n");
fprintf(f, "</html>\n");

View file

@ -84,9 +84,11 @@ int action_seed(int argc, char** argv) {
fprintf(f, " </group>\n");
fprintf(f, " </nav>\n");
fprintf(f, " <favicon></favicon>\n");
fprintf(f, " <extra-css></extra-css>\n");
fprintf(f, " <skin>classic</skin> <!-- classic or simple -->\n");
fprintf(f, " <copyright>\n");
fprintf(f, " <holder>Example Co, Ltd</holder>\n");
fprintf(f, " <year>%d</year>\n", 1900 + tm->tm_year);
fprintf(f, " <year>%d</year> <!-- Year when you started this project/whatever copyright holder -->\n", 1900 + tm->tm_year);
fprintf(f, " <link href=\"https://example.com\" />\n");
fprintf(f, " </copyright>\n");
fprintf(f, "</skinconfig>\n");

View file

@ -1,10 +1,307 @@
#include <taiga.h>
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, " <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%%\" id=\"page\">\n");
fprintf(out, " <tr>\n");
fprintf(out, " <td colspan=\"2\" id=\"banner\">\n");
fprintf(out, " <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%%\">\n");
fprintf(out, " <tr>\n");
fprintf(out, " <td>\n");
fprintf(out, " <h1>%s</h1>\n", project);
fprintf(out, " <p>%s</p>\n", project_desc);
fprintf(out, " </td>\n");
fprintf(out, " <td align=\"right\">\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, " <a href=\"%s\"><img src=\"%s\" alt=\"Project logo\" border=\"0\"></a>\n", link, text);
free(text);
}
free(link);
fprintf(out, " </td>\n");
fprintf(out, " </tr>\n");
fprintf(out, " </table>\n");
fprintf(out, " </td>\n");
fprintf(out, " </tr>\n");
fprintf(out, " <tr>\n");
fprintf(out, " <td id=\"nav\" valign=\"top\">\n");
fprintf(out, " <div class=\"box\">\n");
fprintf(out, " <h2>LINKS</h2>\n");
fprintf(out, " <div class=\"box-content\">\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, " </div>\n");
fprintf(out, " </div>\n");
fprintf(out, " </td>\n");
fprintf(out, " <td id=\"content\" valign=\"top\">\n");
child = body->first_child;
while(child != NULL) {
default_body(out, top, child, 5);
child = child->next;
}
fprintf(out, " <div id=\"footer\">\n");
fprintf(out, " <a href=\"https://validator.w3.org/check/referer\"><img src=\"%simage/valid-html401.png\" alt=\"Valid HTML 4.01\" border=\"0\" width=\"88\" height=\"31\"></a>\n", top);
fprintf(out, " <a href=\"https://jigsaw.w3.org/css-validator/\"><img src=\"%simage/valid-css.png\" alt=\"Valid CSS\" border=\"0\" width=\"88\" height=\"31\"></a>\n", top);
fprintf(out, " <p id=\"copyright\">\n");
fprintf(out, " Copyright &copy; %s %s%s All rights reserved.\n", year, holder, (strlen(holder) > 0 && holder[strlen(holder) - 1] == '.') ? "" : ".");
fprintf(out, " </p>\n");
fprintf(out, " </div>\n");
fprintf(out, " </td>\n");
fprintf(out, " </tr>\n");
fprintf(out, " </table>\n");
}

View file

@ -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("", "")) {