gout

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

page.c (4218B)


      1 #include "writer/html/page.h"
      2 
      3 #include <assert.h>
      4 #include <stdlib.h>
      5 
      6 #include "format.h"
      7 #include "utils.h"
      8 
      9 struct HtmlPage {
     10   FILE* out;
     11   const GitRepo* repo;
     12   const FileSystem* fs;
     13   char* title;
     14   char* relpath;
     15 };
     16 
     17 HtmlPage* html_page_create(FILE* out,
     18                            const GitRepo* repo,
     19                            const FileSystem* fs,
     20                            const char* title,
     21                            const char* relpath) {
     22   assert(out != NULL);
     23   assert(repo != NULL);
     24   assert(fs != NULL);
     25   assert(title != NULL);
     26   assert(relpath != NULL);
     27   HtmlPage* page = ecalloc(1, sizeof(HtmlPage));
     28   page->out = out;
     29   page->repo = repo;
     30   page->fs = fs;
     31   page->title = estrdup(title);
     32   page->relpath = estrdup(relpath);
     33   return page;
     34 }
     35 
     36 void html_page_free(HtmlPage* page) {
     37   if (!page) {
     38     return;
     39   }
     40   free(page->title);
     41   page->title = NULL;
     42   free(page->relpath);
     43   page->relpath = NULL;
     44   free(page);
     45 }
     46 
     47 void html_page_begin(HtmlPage* page) {
     48   assert(page != NULL);
     49   FILE* out = page->out;
     50   fprintf(
     51       out,
     52       "<!DOCTYPE html>\n"
     53       "<html>\n"
     54       "<head>\n"
     55       "<meta "
     56       "http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n"
     57       "<meta "
     58       "name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n");
     59   fprintf(out, "<title>");
     60 
     61   print_xml_encoded(out, page->title);
     62   const char* short_name = page->repo->short_name;
     63   if (page->title[0] != '\0' && short_name && short_name[0] != '\0') {
     64     fprintf(out, " - ");
     65     print_xml_encoded(out, short_name);
     66   }
     67   const char* description = page->repo->description;
     68   if (page->title[0] != '\0' && description && description[0] != '\0') {
     69     fprintf(out, " - ");
     70     print_xml_encoded(out, description);
     71   }
     72 
     73   const char* relpath = page->relpath;
     74   fprintf(out, "</title>\n");
     75   fprintf(out,
     76           "<link rel=\"icon\" type=\"image/png\" href=\"%sfavicon.png\" />\n",
     77           relpath);
     78   fprintf(out,
     79           "<link rel=\"alternate\" type=\"application/atom+xml\" title=\"");
     80   if (page->repo->name) {
     81     print_xml_encoded(out, page->repo->name);
     82   }
     83   fprintf(out, " Atom Feed\" href=\"%satom.xml\" />\n", relpath);
     84   fprintf(out,
     85           "<link rel=\"alternate\" type=\"application/atom+xml\" title=\"");
     86   if (page->repo->name) {
     87     print_xml_encoded(out, page->repo->name);
     88   }
     89   fprintf(out, " Atom Feed (tags)\" href=\"%stags.xml\" />\n", relpath);
     90   fprintf(out,
     91           "<link rel=\"stylesheet\" type=\"text/css\" href=\"%sstyle.css\" />",
     92           relpath);
     93   fprintf(out, "\n</head>\n<body>\n<table><tr><td>");
     94   fprintf(out, "<a href=\"../%s\">", relpath);
     95   fprintf(out, "<img src=\"%slogo.png\" alt=\"\" width=\"32\" height=\"32\" />",
     96           relpath);
     97   fprintf(out, "</a></td><td><h1>");
     98   if (page->repo->short_name) {
     99     print_xml_encoded(out, page->repo->short_name);
    100   }
    101   fprintf(out, "</h1><span class=\"desc\">");
    102   if (page->repo->description) {
    103     print_xml_encoded(out, page->repo->description);
    104   }
    105   fprintf(out, "</span></td></tr>");
    106 
    107   const char* clone_url = page->repo->clone_url;
    108   if (clone_url && clone_url[0] != '\0') {
    109     fprintf(out, "<tr class=\"url\"><td></td><td>git clone ");
    110     if (is_safe_url(clone_url)) {
    111       fprintf(out, "<a href=\"");
    112       print_xml_encoded(out, clone_url);
    113       fprintf(out, "\">");
    114       print_xml_encoded(out, clone_url);
    115       fprintf(out, "</a>");
    116     } else {
    117       print_xml_encoded(out, clone_url);
    118     }
    119     fprintf(out, "</td></tr>");
    120   }
    121   fprintf(out, "<tr><td></td><td>\n");
    122   fprintf(out, "<a href=\"%slog.html\">Log</a> | ", relpath);
    123   fprintf(out, "<a href=\"%sfiles.html\">Files</a> | ", relpath);
    124   fprintf(out, "<a href=\"%srefs.html\">Refs</a>", relpath);
    125 
    126   for (size_t i = 0; i < page->repo->special_files_len; i++) {
    127     RepoSpecialFile* sf = &page->repo->special_files[i];
    128     fprintf(out, " | <a href=\"%sfile/", relpath);
    129     print_percent_encoded(out, sf->path);
    130     fprintf(out, ".html\">");
    131     print_xml_encoded(out, sf->label);
    132     fprintf(out, "</a>");
    133   }
    134   fprintf(out, "</td></tr></table>\n<hr/>\n<div id=\"content\">\n");
    135 }
    136 
    137 void html_page_end(HtmlPage* page) {
    138   assert(page != NULL);
    139   fprintf(page->out, "</div>\n</body>\n</html>\n");
    140 }