summary refs log tree commit diff
path: root/main.c
diff options
context:
space:
mode:
authorWormHeamer2025-03-09 15:47:46 -0400
committerWormHeamer2025-03-09 15:47:46 -0400
commit317582f6b58d4a7518b6f65f86bf8862e815ff82 (patch)
tree57ba4b30a301a4746f39896d605ccc07905d40e0 /main.c
parent83fc688d4ca2dbe06020279de502ab1c8b27bf81 (diff)
factor html_head out of main
Diffstat (limited to 'main.c')
-rw-r--r--main.c119
1 files changed, 61 insertions, 58 deletions
diff --git a/main.c b/main.c
index 395f7f1..5304802 100644
--- a/main.c
+++ b/main.c
@@ -14,6 +14,10 @@
 #define ARGS_IMPL
 #include "args.h"
 
+#define ARENA(n, sz) Arena n; { static char arena_backarr[sz];\
+	n.beg = arena_backarr; n.end = arena_backarr + sizeof(arena_backarr);\
+	__asm("":"+r"(n.beg)); __asm("":"+r"(n.end)); }
+
 int read_all(FILE *f, Str *buf, Arena *a) {
 	if (!f) return -1;
 	buf->s = a->beg;
@@ -244,10 +248,6 @@ int wdoc(FILE *f, Doc **dp, Arena *a, Arena *scratch) {
 	return 0;
 }
 
-#define ARENA(n, sz) Arena n; { static char arena_backarr[sz];\
-	n.beg = arena_backarr; n.end = arena_backarr + sizeof(arena_backarr);\
-	__asm("":"+r"(n.beg)); __asm("":"+r"(n.end)); }
-
 uint64_t str_hash(Str s) {
 	uint64_t h = 14695981039346656037LU;
 	for (isize i = 0; i < s.n; i++) h = (h ^ (s.s[i] & 0xff)) * 1099511628211LU;
@@ -287,6 +287,59 @@ void usage(const char *cmd) {
 			cmd, cmd);
 }
 
+typedef struct {
+	int standalone;
+	int from_stdin;
+	Str stylesheet;
+	Str hvarv[1024];
+	Str title;
+	int hvarc;
+} Options;
+
+Str html_head(Options *o, Arena *m, Arena *l) {
+	Str h = S("<!DOCTYPE html>\n"
+			"<meta charset=utf-8>\n"
+			"<meta name=viewport content='width=device-width,initial-scale=1'>\n");
+	if (o->title.s) {
+		str_cat(&h, S("<title>"), m);
+		str_cat_html(&h, o->title, m);
+		str_cat(&h, S("</title>\n"), m);
+	}
+	if (o->stylesheet.s) {
+		FILE *f = fopen(str_to_cstr(o->stylesheet, m), "r/o");
+		if (!f) {
+			str_putf(o->stylesheet, stderr);
+			fprintf(stderr, ": %s\n", strerror(errno));
+			exit(1);
+		}
+		str_cat(&h, S("<style>\n"), m);
+		if (o->hvarc > 0) {
+			str_cat(&h, S(":root{"), m);
+			for (int i = 0; i < o->hvarc; i++) {
+				Str name, val;
+				if (hvar_calc(o->hvarv[i], &name, &val, o->title)) {
+					fprintf(stderr, "invalid argument given to --hvar\n");
+					exit(1);
+				}
+				str_cat(&h, S("--"), m);
+				str_cat(&h, name, m);
+				str_catc(&h, ':', m);
+				str_cat(&h, val, m);
+				str_catc(&h, ';', m);
+			}
+			str_catc(&h, '}', m);
+		}
+		Str css;
+		if (read_all(f, &css, l)) {
+			fprintf(stderr, "failed to read stylesheet: %s\n", strerror(errno));
+			exit(1);
+		}
+		str_cat(&h, css, m);
+		str_cat(&h, S("</style>\n"), m);
+	}
+	return h;
+}
+
 #define countof(x) (sizeof(x) / sizeof(*x))
 int main(int argc, const char **argv) {
 	(void)argc;
@@ -295,13 +348,7 @@ int main(int argc, const char **argv) {
 	ARENA(scratch, 1 << 20)
 
 	Doc *doc = 0;
-	struct {
-		int standalone;
-		int from_stdin;
-		Str stylesheet;
-		Str hvarv[1024];
-		int hvarc;
-	} opts = { 0 };
+	Options opts = { 0 };
 	int r;
 
 	ArgsState a = args_begin(argv);
@@ -378,56 +425,12 @@ int main(int argc, const char **argv) {
 	}
 
 	if (doc && opts.standalone) {
-		Str title = doc->title;
+		opts.title = doc->title;
 		while (doc->prev) {
 			doc = doc->prev;
-			if (doc->title.s) title = doc->title;
-		}
-		Str thtml = S("<!DOCTYPE html>\n"
-				"<meta charset=utf-8>\n"
-				"<meta name=viewport content='width=device-width,initial-scale=1'>\n");
-		if (title.s) {
-			str_cat(&thtml, S("<title>"), &scratch);
-			str_cat_html(&thtml, title, &scratch);
-			str_cat(&thtml, S("</title>\n"), &scratch);
-		}
-
-		if (opts.stylesheet.s) {
-			FILE *f = fopen(str_to_cstr(opts.stylesheet, &scratch), "r/o");
-			if (!f) {
-				str_putf(opts.stylesheet, stderr);
-				fprintf(stderr, ": %s\n", strerror(errno));
-				return 1;
-			}
-			Str css;
-			Arena p = perm;
-			if (read_all(f, &css, &perm)) {
-				fprintf(stderr, "failed to read stylesheet: %s\n", strerror(errno));
-				return 1;
-			}
-			str_cat(&thtml, S("<style>\n"), &scratch);
-			if (opts.hvarc > 0) {
-				str_cat(&thtml, S(":root{"), &scratch);
-				for (int i = 0; i < opts.hvarc; i++) {
-					Str name, val;
-					if (hvar_calc(opts.hvarv[i], &name, &val, title)) {
-						fprintf(stderr, "invalid argument given to --hvar\n");
-						return 1;
-					}
-					str_cat(&thtml, S("--"), &scratch);
-					str_cat(&thtml, name, &scratch);
-					str_catc(&thtml, ':', &scratch);
-					str_cat(&thtml, val, &scratch);
-					str_catc(&thtml, ';', &scratch);
-				}
-				str_catc(&thtml, '}', &scratch);
-			}
-			str_cat(&thtml, css, &scratch);
-			str_cat(&thtml, S("</style>\n"), &scratch);
-			perm = p;
+			if (doc->title.s) opts.title = doc->title;
 		}
-
-		str_put(thtml);
+		str_put(html_head(&opts, &perm, &scratch));
 	}
 
 	while (doc) {