gout

A static git page generator
git clone https://git.bracken.jp/gout.git
Log | Files | Refs | README | LICENSE

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 }