summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--archive.c2
-rw-r--r--archive.h7
-rw-r--r--concat.c5
-rw-r--r--html.c39
4 files changed, 46 insertions, 7 deletions
diff --git a/archive.c b/archive.c
index 400e040..74491a1 100644
--- a/archive.c
+++ b/archive.c
@@ -171,7 +171,7 @@ searchThreads(struct IMAP *imap, const char *name, const char *expr) {
 	respFree(resp);
 
 concat:
-	concatSearch(name, threads, envelopes);
+	concatSearch(name, threads, envelopes, search.names, search.len);
 
 	for (size_t i = 0; i < threads.len; ++i) {
 		envelopeFree(envelopes[i]);
diff --git a/archive.h b/archive.h
index 3f13109..7740b98 100644
--- a/archive.h
+++ b/archive.h
@@ -222,7 +222,8 @@ void concatData(
 );
 void concatThreads(struct List threads, const struct Envelope *envelopes);
 void concatSearch(
-	const char *name, struct List threads, const struct Envelope *envelopes
+	const char *name, struct List threads, const struct Envelope *envelopes,
+	char *searches[const], size_t len
 );
 
 int mboxFrom(FILE *file);
@@ -251,7 +252,9 @@ int htmlSubthreadOpen(FILE *file, struct List thread);
 int htmlSubthreadClose(FILE *file);
 int htmlThreadClose(FILE *file);
 int htmlSearchHead(FILE *file, const char *name);
-int htmlSearchOpen(FILE *file, const char *name);
+int htmlSearchOpen(
+	FILE *file, const char *name, char *searches[const], size_t len
+);
 int htmlSearchThread(
 	FILE *file, const struct Envelope *envelope, struct List thread
 );
diff --git a/concat.c b/concat.c
index 2b1c619..800a7a2 100644
--- a/concat.c
+++ b/concat.c
@@ -264,7 +264,8 @@ static int sortCompare(const void *_a, const void *_b) {
 size_t concatSearchEntries = 20;
 
 void concatSearch(
-	const char *name, struct List threads, const struct Envelope *envelopes
+	const char *name, struct List threads, const struct Envelope *envelopes,
+	char *searches[const], size_t len
 ) {
 	char *path = searchPath(name, "atom");
 	FILE *file = fopen(path, "w");
@@ -316,7 +317,7 @@ void concatSearch(
 		if (error) err(EX_IOERR, "%s", path);
 	}
 
-	error = htmlSearchOpen(file, name);
+	error = htmlSearchOpen(file, name, searches, len);
 	if (error) err(EX_IOERR, "%s", path);
 
 	for (size_t i = threads.len - 1; i < threads.len; --i) {
diff --git a/html.c b/html.c
index 5eb2f29..6b25996 100644
--- a/html.c
+++ b/html.c
@@ -545,12 +545,40 @@ int htmlSearchHead(FILE *file, const char *name) {
 	return error;
 }
 
-int htmlSearchOpen(FILE *file, const char *name) {
+static int htmlSearchNav(
+	FILE *file, const char *name, char *searches[const], size_t len
+) {
+	if (len < 2 || strcmp(name, "index")) return 0;
+	int error = templateRender(file, Q(<nav>), NULL, NULL);
+	if (error) return error;
+	for (size_t i = 0; i < len; ++i) {
+		if (!strcmp(searches[i], "index")) continue;
+		char *url = htmlSearchURL(searches[i], "html");
+		const char *template = Q(<a href="[url]">[search]</a>) " ";
+		struct Variable vars[] = {
+			{ "url", url },
+			{ "search", searches[i] },
+			{0},
+		};
+		error = templateRender(file, template, vars, escapeXML);
+		free(url);
+		if (error) return error;
+	}
+	return templateRender(file, Q(</nav>), NULL, NULL);
+}
+
+int htmlSearchOpen(
+	FILE *file, const char *name, char *searches[const], size_t len
+) {
+	char *index = htmlSearchURL("index", "html");
 	char *atom = htmlSearchURL(name, "atom");
 	const char *template = Q(
 		<header class="index">
 			<h1>[+name][name] - [-][title]</h1>
 			<nav>
+				[+name]
+				<a href="[index]">index</a>
+				[-]
 				<a href="[atom]">follow</a>
 				[+subscribe]
 				<a href="[subscribe]">subscribe</a>
@@ -559,6 +587,8 @@ int htmlSearchOpen(FILE *file, const char *name) {
 				<a href="mailto:[mailto]">write</a>
 				[-]
 			</nav>
+	);
+	const char *tail = Q(
 		</header>
 		<main class="index">
 			<ol>
@@ -566,12 +596,17 @@ int htmlSearchOpen(FILE *file, const char *name) {
 	struct Variable vars[] = {
 		{ "name", (strcmp(name, "index") ? name : NULL) },
 		{ "title", baseTitle },
+		{ "index", index },
 		{ "atom", atom },
 		{ "subscribe", baseSubscribe },
 		{ "mailto", baseMailto },
 		{0},
 	};
-	int error = templateRender(file, template, vars, escapeXML);
+	int error = 0
+		|| templateRender(file, template, vars, escapeXML)
+		|| htmlSearchNav(file, name, searches, len)
+		|| templateRender(file, tail, NULL, NULL);
+	free(index);
 	free(atom);
 	return error;
 }