commit 326216d12d44a5b3ebc480d8cb20ac3708094eee
parent cd8d754cc036718b092b4aaf899852a8ee41e649
Author: Nathaniel Chappelle <nathaniel@chappelle.dev>
Date: Thu, 29 Jan 2026 10:37:18 -0800
it renders threads, but weird bug generating extra (empty) messages
Diffstat:
| M | stamail.c | | | 105 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- |
1 file changed, 104 insertions(+), 1 deletion(-)
diff --git a/stamail.c b/stamail.c
@@ -358,6 +358,102 @@ static int write_message(const char *output_dir, struct message *m) {
return 0;
}
+static void render_thread_ascii(FILE *fp,
+ struct thread_node *n,
+ const char *prefix,
+ int is_last)
+{
+ char next_prefix[1024];
+
+ /* branch marker */
+ fprintf(fp, "%s%s ", prefix, is_last ? "\\-" : "+-");
+
+ /* link to message */
+ unsigned long hash =
+ hash_msgid(n->msg->id, n->msg->id_len);
+
+ fprintf(fp, "<a href=\"msg-%08lx.html\">", hash);
+ fprinthtml(fp,
+ n->msg->subject,
+ n->msg->subject_len);
+ fprintf(fp, "</a>\n");
+
+ /* extend prefix */
+ snprintf(next_prefix, sizeof(next_prefix),
+ "%s%s ",
+ prefix,
+ is_last ? " " : "| ");
+
+ /* walk children */
+ struct thread_node *c = n->child;
+ while (c) {
+ render_thread_ascii(fp,
+ c,
+ next_prefix,
+ c->sibling == NULL);
+ c = c->sibling;
+ }
+}
+
+static int write_threads(const char *output_dir,
+ const char *archive_name,
+ struct thread_node **threads,
+ int num_threads)
+{
+ FILE *fp;
+ char path[1024];
+
+ snprintf(path, sizeof(path), "%s/threads.html", output_dir);
+ fp = fopen(path, "w");
+ if (!fp) {
+ perror(path);
+ return -1;
+ }
+
+ writeheader(fp, archive_name);
+
+ fprintf(fp, "<h1>%s — Threads</h1>\n", archive_name);
+ fprintf(fp, "<nav>\n");
+ fprintf(fp, "<a href=\"index.html\">Messages</a> | ");
+ fprintf(fp, "<a href=\"threads.html\">Threads</a>\n");
+ fprintf(fp, "</nav>\n");
+
+ fprintf(fp,
+ "<pre style=\"font-family: monospace;"
+ "white-space: pre; line-height: 1.3;\">\n");
+
+ for (int i = 0; i < num_threads; i++) {
+ struct thread_node *r = *threads++;
+
+ /* root line (no prefix) */
+ unsigned long hash =
+ hash_msgid(r->msg->id, r->msg->id_len);
+
+ fprintf(fp, "<a href=\"msg-%08lx.html\">", hash);
+ fprinthtml(fp,
+ r->msg->subject,
+ r->msg->subject_len);
+ fprintf(fp, "</a>\n");
+
+ /* children */
+ struct thread_node *c = r->child;
+ while (c) {
+ render_thread_ascii(fp,
+ c,
+ "",
+ c->sibling == NULL);
+ c = c->sibling;
+ }
+
+ fprintf(fp, "\n");
+ }
+
+ fprintf(fp, "</pre>\n");
+ writefooter(fp);
+ fclose(fp);
+ return 0;
+}
+
int main(int argc, char *argv[]) {
/* CONFIG */
const char *output_dir = "./output";
@@ -496,7 +592,14 @@ int main(int argc, char *argv[]) {
print_threads(threads, num_threads);
}
-
+ if (threads) {
+ if (write_threads(output_dir,
+ archive_name,
+ threads,
+ num_threads) != 0) {
+ fprintf(stderr, "Failed to write threads.html\n");
+ }
+ }
free(buf);
struct message_node *n = head;