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 }