summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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) {