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 }