gout

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

page.c (4172B)


      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   free(page->relpath);
     42   free(page);
     43 }
     44 
     45 void html_page_begin(HtmlPage* page) {
     46   assert(page != NULL);
     47   FILE* out = page->out;
     48   fprintf(
     49       out,
     50       "<!DOCTYPE html>\n"
     51       "<html>\n"
     52       "<head>\n"
     53       "<meta "
     54       "http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n"
     55       "<meta "
     56       "name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n");
     57   fprintf(out, "<title>");
     58 
     59   print_xml_encoded(out, page->title);
     60   const char* short_name = page->repo->short_name;
     61   if (page->title[0] != '\0' && short_name && short_name[0] != '\0') {
     62     fprintf(out, " - ");
     63     print_xml_encoded(out, short_name);
     64   }
     65   const char* description = page->repo->description;
     66   if (page->title[0] != '\0' && description && description[0] != '\0') {
     67     fprintf(out, " - ");
     68     print_xml_encoded(out, description);
     69   }
     70 
     71   const char* relpath = page->relpath;
     72   fprintf(out, "</title>\n");
     73   fprintf(out,
     74           "<link rel=\"icon\" type=\"image/png\" href=\"%sfavicon.png\" />\n",
     75           relpath);
     76   fprintf(out,
     77           "<link rel=\"alternate\" type=\"application/atom+xml\" title=\"");
     78   if (page->repo->name) {
     79     print_xml_encoded(out, page->repo->name);
     80   }
     81   fprintf(out, " Atom Feed\" href=\"%satom.xml\" />\n", relpath);
     82   fprintf(out,
     83           "<link rel=\"alternate\" type=\"application/atom+xml\" title=\"");
     84   if (page->repo->name) {
     85     print_xml_encoded(out, page->repo->name);
     86   }
     87   fprintf(out, " Atom Feed (tags)\" href=\"%stags.xml\" />\n", relpath);
     88   fprintf(out,
     89           "<link rel=\"stylesheet\" type=\"text/css\" href=\"%sstyle.css\" />",
     90           relpath);
     91   fprintf(out, "\n</head>\n<body>\n<table><tr><td>");
     92   fprintf(out, "<a href=\"../%s\">", relpath);
     93   fprintf(out, "<img src=\"%slogo.png\" alt=\"\" width=\"32\" height=\"32\" />",
     94           relpath);
     95   fprintf(out, "</a></td><td><h1>");
     96   if (page->repo->short_name) {
     97     print_xml_encoded(out, page->repo->short_name);
     98   }
     99   fprintf(out, "</h1><span class=\"desc\">");
    100   if (page->repo->description) {
    101     print_xml_encoded(out, page->repo->description);
    102   }
    103   fprintf(out, "</span></td></tr>");
    104 
    105   const char* clone_url = page->repo->clone_url;
    106   if (clone_url && clone_url[0] != '\0') {
    107     fprintf(out, "<tr class=\"url\"><td></td><td>git clone ");
    108     if (is_safe_url(clone_url)) {
    109       fprintf(out, "<a href=\"");
    110       print_xml_encoded(out, clone_url);
    111       fprintf(out, "\">");
    112       print_xml_encoded(out, clone_url);
    113       fprintf(out, "</a>");
    114     } else {
    115       print_xml_encoded(out, clone_url);
    116     }
    117     fprintf(out, "</td></tr>");
    118   }
    119   fprintf(out, "<tr><td></td><td>\n");
    120   fprintf(out, "<a href=\"%slog.html\">Log</a> | ", relpath);
    121   fprintf(out, "<a href=\"%sfiles.html\">Files</a> | ", relpath);
    122   fprintf(out, "<a href=\"%srefs.html\">Refs</a>", relpath);
    123 
    124   for (size_t i = 0; i < page->repo->special_files_len; i++) {
    125     RepoSpecialFile* sf = &page->repo->special_files[i];
    126     fprintf(out, " | <a href=\"%sfile/", relpath);
    127     print_percent_encoded(out, sf->path);
    128     fprintf(out, ".html\">");
    129     print_xml_encoded(out, sf->label);
    130     fprintf(out, "</a>");
    131   }
    132   fprintf(out, "</td></tr></table>\n<hr/>\n<div id=\"content\">\n");
    133 }
    134 
    135 void html_page_end(HtmlPage* page) {
    136   assert(page != NULL);
    137   fprintf(page->out, "</div>\n</body>\n</html>\n");
    138 }