summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Makefile8
-rw-r--r--archive.c4
-rw-r--r--archive.h3
-rw-r--r--bubger.18
-rwxr-xr-xconfigure1
-rw-r--r--default.html96
-rw-r--r--html.c28
-rw-r--r--stylesheet.c96
8 files changed, 138 insertions, 106 deletions
diff --git a/Makefile b/Makefile
index 19f8e21..43fcb0d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,5 @@
 PREFIX ?= /usr/local
 MANDIR ?= ${SHAREDIR}/man
-DATADIR ?= ${PREFIX}/share
 
 CFLAGS += -std=c11 -Wall -Wextra -Wpedantic
 LDLIBS = -ltls
@@ -16,6 +15,7 @@ OBJS += html.o
 OBJS += imap.o
 OBJS += mbox.o
 OBJS += parse.o
+OBJS += stylesheet.o
 OBJS += template.o
 
 dev: tags all
@@ -33,12 +33,10 @@ tags: *.[ch]
 clean:
 	rm -f bubger ${OBJS} tags
 
-install: bubger bubger.1 default.html
-	install -d ${PREFIX}/bin ${MANDIR}/man1 ${DATADIR}/bubger
+install: bubger bubger.1
+	install -d ${PREFIX}/bin ${MANDIR}/man1
 	install bubger ${PREFIX}/bin
 	install -m 644 bubger.1 ${MANDIR}/man1
-	install -m 644 default.html ${DATADIR}/bubger
 
 uninstall:
 	rm -f ${PREFIX}/bin/bubger ${MANDIR}/man1/bubger.1
-	rm -fr ${DATADIR}/bubger
diff --git a/archive.c b/archive.c
index 469c24c..e0ad6ad 100644
--- a/archive.c
+++ b/archive.c
@@ -44,6 +44,7 @@ const char *baseURL = "";
 const char *baseTitle;
 const char *baseMailto;
 const char *baseSubscribe;
+const char *baseStylesheet;
 
 static uint32_t uidRead(const char *path) {
 	FILE *file = fopen(path, "r");
@@ -87,7 +88,7 @@ int main(int argc, char *argv[]) {
 	const char *algo = "REFERENCES";
 	const char *search = "ALL";
 
-	for (int opt; 0 < (opt = getopt(argc, argv, "C:S:a:h:m:p:qs:t:u:vw:"));) {
+	for (int opt; 0 < (opt = getopt(argc, argv, "C:S:a:h:m:p:qs:t:u:vw:y:"));) {
 		switch (opt) {
 			break; case 'C': {
 				int error = chdir(optarg);
@@ -104,6 +105,7 @@ int main(int argc, char *argv[]) {
 			break; case 'u': baseURL = optarg;
 			break; case 'v': imapVerbose = true;
 			break; case 'w': passPath = optarg;
+			break; case 'y': baseStylesheet = optarg;
 		}
 	}
 	if (optind < argc) host = argv[optind++];
diff --git a/archive.h b/archive.h
index 0b8b6d8..51dede8 100644
--- a/archive.h
+++ b/archive.h
@@ -50,10 +50,13 @@
 	"Message-Id In-Reply-To References " \
 	"MIME-Version Content-Type Content-Disposition Content-Transfer-Encoding"
 
+extern const char Stylesheet[];
+
 extern const char *baseURL;
 extern const char *baseTitle;
 extern const char *baseMailto;
 extern const char *baseSubscribe;
+extern const char *baseStylesheet;
 
 static inline struct U32 {
 	char s[sizeof("4294967295")];
diff --git a/bubger.1 b/bubger.1
index 324d7c6..ef1d7f9 100644
--- a/bubger.1
+++ b/bubger.1
@@ -1,4 +1,4 @@
-.Dd May 11, 2020
+.Dd December  1, 2020
 .Dt BUBGER 1
 .Os
 .
@@ -19,6 +19,7 @@
 .Op Fl t Ar title
 .Op Fl u Ar base
 .Op Fl w Ar file
+.Op Fl y Ar css
 .Ar host
 .Ar user
 .Op Ar mailbox
@@ -103,6 +104,11 @@ By default the password is set by the
 .Ev BUBGER_IMAP_PASSWORD
 environment variable.
 .
+.It Fl y Ar css
+Use the stylesheet URL
+.Ar css .
+The default is an inline stylesheet.
+.
 .It Ar host
 Connect to IMAP on
 .Ar host .
diff --git a/configure b/configure
index bd6d39d..4cfd27c 100755
--- a/configure
+++ b/configure
@@ -26,7 +26,6 @@ for opt; do
 	case "${opt}" in
 		(--prefix=*) echo "PREFIX = ${opt#*=}" ;;
 		(--mandir=*) echo "MANDIR = ${opt#*=}" ;;
-		(--datadir=*) echo "DATADIR = ${opt#*=}" ;;
 		(*) echo "warning: unsupported option ${opt}" >&2 ;;
 	esac
 done
diff --git a/default.html b/default.html
deleted file mode 100644
index 8573ba6..0000000
--- a/default.html
+++ /dev/null
@@ -1,96 +0,0 @@
-<meta name="viewport" content="width=device-width, initial-scale=1.0">
-<style>
-html {
-	font-family: monospace;
-}
-body {
-	max-width: 104ch;
-	margin: auto;
-	padding: 0 1ch;
-}
-
-header {
-	margin: 1em 0;
-}
-
-main.index ol {
-	list-style-type: none;
-	padding: 0;
-}
-main.index ol li {
-	margin: 1em 0;
-}
-main.index h2 {
-	font-size: 1em;
-	margin: 0;
-}
-main.index time, main.index data.replies {
-	display: block;
-}
-main.index data.replies[value="0"] {
-	display: none;
-}
-
-article.message header {
-	background-color: gainsboro;
-	padding: 1ex 1ch;
-}
-article.message:target header {
-	background-color: khaki;
-}
-article.message header h2 {
-	font-size: 1em;
-	margin: 0;
-}
-
-pre {
-	white-space: pre-wrap;
-}
-span.quote {
-	color: navy;
-}
-span.quote.level2 {
-	color: teal;
-}
-span.quote.level3 {
-	color: purple;
-}
-span.diff.head {
-	font-weight: bold;
-}
-span.diff.hunk {
-	color: navy;
-}
-span.diff.old {
-	color: red;
-}
-span.diff.new {
-	text-decoration: none;
-	color: green;
-}
-
-ul.attachment {
-	background-color: gainsboro;
-	padding-top: 1ex;
-	padding-bottom: 1ex;
-	list-style-type: square;
-}
-
-details.subthread, article.message > article.message {
-	border-left: 2px solid gainsboro;
-	padding-left: 1ch;
-}
-details.subthread summary {
-	margin: 1em 0;
-}
-
-footer {
-	margin: 1em 0;
-	font-size: x-small;
-	text-align: center;
-	color: gray;
-}
-footer a {
-	color: inherit;
-}
-</style>
diff --git a/html.c b/html.c
index 1757fd9..25c9118 100644
--- a/html.c
+++ b/html.c
@@ -362,6 +362,24 @@ int htmlMessageClose(FILE *file) {
 	return templateRender(file, Q(</article>), NULL, NULL);
 }
 
+static int htmlStylesheet(FILE *file) {
+	if (baseStylesheet) {
+		const char *template = Q(<link rel="stylesheet" href="[href]">);
+		struct Variable vars[] = {
+			{ "href", baseStylesheet },
+			{0},
+		};
+		return templateRender(file, template, vars, escapeXML);
+	} else {
+		const char *template = Q(<style>[style]</style>);
+		struct Variable vars[] = {
+			{ "style", Stylesheet },
+			{0},
+		};
+		return templateRender(file, template, vars, NULL);
+	}
+}
+
 static char *htmlThreadURL(const struct Envelope *envelope, const char *type) {
 	struct Variable vars[] = {
 		{ "messageID", envelope->messageID },
@@ -381,6 +399,7 @@ int htmlThreadHead(FILE *file, const struct Envelope *envelope) {
 		<title>[subject]</title>
 		<link rel="alternate" type="application/atom+xml" href="[atom]">
 		<link rel="alternate" type="application/mbox" href="[mbox]">
+		<meta name="viewport" content="width=device-width, initial-scale=1.0">
 	);
 	struct Variable vars[] = {
 		{ "generator", GENERATOR_URL },
@@ -389,7 +408,9 @@ int htmlThreadHead(FILE *file, const struct Envelope *envelope) {
 		{ "mbox", mbox },
 		{0},
 	};
-	int error = templateRender(file, template, vars, escapeXML);
+	int error = 0
+		|| templateRender(file, template, vars, escapeXML)
+		|| htmlStylesheet(file);
 	free(atom);
 	free(mbox);
 	return error;
@@ -488,13 +509,16 @@ int htmlIndexHead(FILE *file) {
 		<meta name="generator" content="[generator]">
 		<title>[title]</title>
 		<link rel="alternate" type="application/atom+xml" href="index.atom">
+		<meta name="viewport" content="width=device-width, initial-scale=1.0">
 	);
 	struct Variable vars[] = {
 		{ "generator", GENERATOR_URL },
 		{ "title", baseTitle },
 		{0},
 	};
-	return templateRender(file, template, vars, escapeXML);
+	return 0
+		|| templateRender(file, template, vars, escapeXML)
+		|| htmlStylesheet(file);
 }
 
 int htmlIndexOpen(FILE *file) {
diff --git a/stylesheet.c b/stylesheet.c
new file mode 100644
index 0000000..41a0bd9
--- /dev/null
+++ b/stylesheet.c
@@ -0,0 +1,96 @@
+#include "archive.h"
+const char Stylesheet[] = Q(
+	html {
+		font-family: monospace;
+	}
+	body {
+		max-width: 104ch;
+		margin: auto;
+		padding: 0 1ch;
+	}
+
+	header {
+		margin: 1em 0;
+	}
+
+	main.index ol {
+		list-style-type: none;
+		padding: 0;
+	}
+	main.index ol li {
+		margin: 1em 0;
+	}
+	main.index h2 {
+		font-size: 1em;
+		margin: 0;
+	}
+	main.index time, main.index data.replies {
+		display: block;
+	}
+	main.index data.replies[value="0"] {
+		display: none;
+	}
+
+	article.message header {
+		background-color: gainsboro;
+		padding: 1ex 1ch;
+	}
+	article.message:target header {
+		background-color: khaki;
+	}
+	article.message header h2 {
+		font-size: 1em;
+		margin: 0;
+	}
+
+	pre {
+		white-space: pre-wrap;
+	}
+	span.quote {
+		color: navy;
+	}
+	span.quote.level2 {
+		color: teal;
+	}
+	span.quote.level3 {
+		color: purple;
+	}
+	span.diff.head {
+		font-weight: bold;
+	}
+	span.diff.hunk {
+		color: navy;
+	}
+	span.diff.old {
+		color: red;
+	}
+	span.diff.new {
+		text-decoration: none;
+		color: green;
+	}
+
+	ul.attachment {
+		background-color: gainsboro;
+		padding-top: 1ex;
+		padding-bottom: 1ex;
+		list-style-type: square;
+	}
+
+	details.subthread, article.message > article.message {
+		border-left: 2px solid gainsboro;
+		padding-left: 1ch;
+	}
+	details.subthread summary {
+		margin: 1em 0;
+	}
+
+	footer {
+		margin: 1em 0;
+		font-size: x-small;
+		text-align: center;
+		color: gray;
+	}
+	footer a {
+		color: inherit;
+	}
+);