refs.c (2435B)
1 #include "writer/gemini/refs.h" 2 3 #include <assert.h> 4 #include <err.h> 5 #include <stdio.h> 6 #include <stdlib.h> 7 8 #include "format.h" 9 #include "git/commit.h" 10 #include "utils.h" 11 #include "writer/gemini/page.h" 12 13 struct GeminiRefs { 14 const GitRepo* repo; 15 const FileSystem* fs; 16 FILE* out; 17 GeminiPage* page; 18 bool has_branches; 19 bool has_tags; 20 bool in_block; 21 }; 22 23 GeminiRefs* gemini_refs_create(const GitRepo* repo, const FileSystem* fs) { 24 assert(repo != NULL); 25 assert(fs != NULL); 26 GeminiRefs* refs = ecalloc(1, sizeof(GeminiRefs)); 27 refs->repo = repo; 28 refs->fs = fs; 29 refs->out = fs->fopen("refs.gmi", "w"); 30 if (!refs->out) { 31 err(1, "fopen: refs.gmi"); 32 } 33 refs->page = gemini_page_create(refs->out, repo, fs, "Refs", ""); 34 return refs; 35 } 36 37 void gemini_refs_free(GeminiRefs* refs) { 38 if (!refs) { 39 return; 40 } 41 refs->fs->fclose(refs->out); 42 refs->out = NULL; 43 gemini_page_free(refs->page); 44 refs->page = NULL; 45 free(refs); 46 } 47 48 void gemini_refs_begin(GeminiRefs* refs) { 49 assert(refs != NULL); 50 gemini_page_begin(refs->page); 51 } 52 53 static void ensure_block_closed(GeminiRefs* refs) { 54 if (refs->in_block) { 55 fprintf(refs->out, "```\n"); 56 refs->in_block = false; 57 } 58 } 59 60 static void ensure_block_open(GeminiRefs* refs) { 61 if (!refs->in_block) { 62 fprintf(refs->out, "```\n"); 63 print_utf8_padded(refs->out, "Name", 32, ' '); 64 fprintf(refs->out, " "); 65 print_utf8_padded(refs->out, "Last commit date", 16, ' '); 66 fprintf(refs->out, " Author\n"); 67 refs->in_block = true; 68 } 69 } 70 71 void gemini_refs_add_ref(GeminiRefs* refs, const GitReference* ref) { 72 assert(refs != NULL); 73 assert(ref != NULL); 74 FILE* out = refs->out; 75 76 if (ref->type == kReftypeBranch && !refs->has_branches) { 77 ensure_block_closed(refs); 78 fprintf(out, "## Branches\n\n"); 79 refs->has_branches = true; 80 ensure_block_open(refs); 81 } else if (ref->type == kReftypeTag && !refs->has_tags) { 82 ensure_block_closed(refs); 83 if (refs->has_branches) { 84 fprintf(out, "\n"); 85 } 86 fprintf(out, "## Tags\n\n"); 87 refs->has_tags = true; 88 ensure_block_open(refs); 89 } 90 91 GitCommit* commit = ref->commit; 92 print_utf8_padded(out, ref->shorthand, 32, ' '); 93 fprintf(out, " "); 94 print_time_short(out, commit->author_time); 95 fprintf(out, " %s\n", commit->author_name); 96 } 97 98 void gemini_refs_end(GeminiRefs* refs) { 99 assert(refs != NULL); 100 ensure_block_closed(refs); 101 gemini_page_end(refs->page); 102 }