commit 35b56ab728ff8d1cade8c5eb8d3220060136d8f2
parent dbd3471ed90a19ce994a16ddf65b7714fc265d3d
Author: Chris Bracken <chris@bracken.jp>
Date: Fri, 6 Mar 2026 21:17:17 +0900
gemini: make gemini refs writer consistent with HTML/Gopher structure
Now use use the same sort of table begin/end functions for writing the
table.
Diffstat:
1 file changed, 91 insertions(+), 43 deletions(-)
diff --git a/src/writer/gemini/refs.c b/src/writer/gemini/refs.c
@@ -11,16 +11,72 @@
#include "utils.h"
#include "writer/gemini/page.h"
+typedef struct {
+ char* title;
+ FILE* out;
+} GeminiRefsTable;
+
struct GeminiRefs {
const GitRepo* repo;
const FileSystem* fs;
FILE* out;
GeminiPage* page;
- bool has_branches;
- bool has_tags;
- bool in_block;
+ GeminiRefsTable* branches;
+ GeminiRefsTable* tags;
};
+static GeminiRefsTable* gemini_refstable_create(const char* title, FILE* out);
+static void gemini_refstable_free(GeminiRefsTable* table);
+static void gemini_refstable_begin(GeminiRefsTable* table);
+static void gemini_refstable_add_ref(GeminiRefsTable* table,
+ const GitReference* ref);
+static void gemini_refstable_end(GeminiRefsTable* table);
+
+static GeminiRefsTable* gemini_refstable_create(const char* title, FILE* out) {
+ assert(title != NULL);
+ assert(out != NULL);
+ GeminiRefsTable* table = ecalloc(1, sizeof(GeminiRefsTable));
+ table->title = estrdup(title);
+ table->out = out;
+ return table;
+}
+
+static void gemini_refstable_free(GeminiRefsTable* table) {
+ if (!table) {
+ return;
+ }
+ free(table->title);
+ free(table);
+}
+
+static void gemini_refstable_begin(GeminiRefsTable* table) {
+ assert(table != NULL);
+ fprintf(table->out, "## %s\n\n", table->title);
+ fprintf(table->out, "```\n");
+ print_utf8_padded(table->out, "Name", 32, ' ');
+ fprintf(table->out, " ");
+ print_utf8_padded(table->out, "Last commit date", 16, ' ');
+ fprintf(table->out, " Author\n");
+}
+
+static void gemini_refstable_add_ref(GeminiRefsTable* table,
+ const GitReference* ref) {
+ assert(table != NULL);
+ assert(ref != NULL);
+ GitCommit* commit = ref->commit;
+ FILE* out = table->out;
+
+ print_utf8_padded(out, ref->shorthand, 32, ' ');
+ fprintf(out, " ");
+ print_time_short(out, commit->author_time);
+ fprintf(out, " %s\n", commit->author_name);
+}
+
+static void gemini_refstable_end(GeminiRefsTable* table) {
+ assert(table != NULL);
+ fprintf(table->out, "```\n\n");
+}
+
GeminiRefs* gemini_refs_create(const GitRepo* repo, const FileSystem* fs) {
assert(repo != NULL);
assert(fs != NULL);
@@ -41,6 +97,8 @@ void gemini_refs_free(GeminiRefs* refs) {
}
refs->fs->fclose(refs->out);
gemini_page_free(refs->page);
+ gemini_refstable_free(refs->branches);
+ gemini_refstable_free(refs->tags);
free(refs);
}
@@ -49,53 +107,43 @@ void gemini_refs_begin(GeminiRefs* refs) {
gemini_page_begin(refs->page);
}
-static void ensure_block_closed(GeminiRefs* refs) {
- if (refs->in_block) {
- fprintf(refs->out, "```\n");
- refs->in_block = false;
- }
-}
-
-static void ensure_block_open(GeminiRefs* refs) {
- if (!refs->in_block) {
- fprintf(refs->out, "```\n");
- print_utf8_padded(refs->out, "Name", 32, ' ');
- fprintf(refs->out, " ");
- print_utf8_padded(refs->out, "Last commit date", 16, ' ');
- fprintf(refs->out, " Author\n");
- refs->in_block = true;
- }
-}
-
void gemini_refs_add_ref(GeminiRefs* refs, const GitReference* ref) {
assert(refs != NULL);
assert(ref != NULL);
- FILE* out = refs->out;
-
- if (ref->type == kReftypeBranch && !refs->has_branches) {
- ensure_block_closed(refs);
- fprintf(out, "## Branches\n\n");
- refs->has_branches = true;
- ensure_block_open(refs);
- } else if (ref->type == kReftypeTag && !refs->has_tags) {
- ensure_block_closed(refs);
- if (refs->has_branches) {
- fprintf(out, "\n");
- }
- fprintf(out, "## Tags\n\n");
- refs->has_tags = true;
- ensure_block_open(refs);
+ switch (ref->type) {
+ case kReftypeBranch:
+ if (!refs->branches) {
+ refs->branches = gemini_refstable_create("Branches", refs->out);
+ gemini_refstable_begin(refs->branches);
+ }
+ gemini_refstable_add_ref(refs->branches, ref);
+ break;
+ case kReftypeTag:
+ if (refs->branches) {
+ gemini_refstable_end(refs->branches);
+ gemini_refstable_free(refs->branches);
+ refs->branches = NULL;
+ }
+ if (!refs->tags) {
+ refs->tags = gemini_refstable_create("Tags", refs->out);
+ gemini_refstable_begin(refs->tags);
+ }
+ gemini_refstable_add_ref(refs->tags, ref);
+ break;
}
-
- GitCommit* commit = ref->commit;
- print_utf8_padded(out, ref->shorthand, 32, ' ');
- fprintf(out, " ");
- print_time_short(out, commit->author_time);
- fprintf(out, " %s\n", commit->author_name);
}
void gemini_refs_end(GeminiRefs* refs) {
assert(refs != NULL);
- ensure_block_closed(refs);
+ if (refs->branches) {
+ gemini_refstable_end(refs->branches);
+ gemini_refstable_free(refs->branches);
+ refs->branches = NULL;
+ }
+ if (refs->tags) {
+ gemini_refstable_end(refs->tags);
+ gemini_refstable_free(refs->tags);
+ refs->tags = NULL;
+ }
gemini_page_end(refs->page);
}