about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJeff Smith2017-10-28 21:43:26 -0500
committerJason A. Donenfeld2018-01-19 11:40:58 +0100
commitdbaee2672be14374acb17266477c19294c6155f3 (patch)
treeb9824a153190bab7f0b6e48b922b1b3934666d96
parentui-blame: Make each column into a single table cell (diff)
downloadcgit-dbaee2672be14374acb17266477c19294c6155f3.tar.gz
cgit-dbaee2672be14374acb17266477c19294c6155f3.zip
ui-blame: Allow syntax highlighting
Place file contents into a single block so that syntax highlighting can
be applied in the usual fashion.  Place the alternating color bars
behind the file contents.  Force the default syntax highlighting
background to transparent.

Signed-off-by: Jeff Smith <whydoubt@gmail.com>
Reviewed-by: John Keeping <john@keeping.me.uk>
-rw-r--r--cgit.css10
-rwxr-xr-xfilters/syntax-highlighting.py2
-rw-r--r--ui-blame.c63
3 files changed, 62 insertions, 13 deletions
diff --git a/cgit.css b/cgit.css index 20b7e86..217a05a 100644 --- a/cgit.css +++ b/cgit.css
@@ -353,6 +353,16 @@ div#cgit table.blame div.alt:nth-child(odd) {
353 background: white; 353 background: white;
354} 354}
355 355
356div#cgit table.blame td.lines > div {
357 position: relative;
358}
359
360div#cgit table.blame td.lines > div > pre {
361 padding: 0 0 0 0.5em;
362 position: absolute;
363 top: 0;
364}
365
356div#cgit table.bin-blob { 366div#cgit table.bin-blob {
357 margin-top: 0.5em; 367 margin-top: 0.5em;
358 border: solid 1px black; 368 border: solid 1px black;
diff --git a/filters/syntax-highlighting.py b/filters/syntax-highlighting.py index 5888b50..e912594 100755 --- a/filters/syntax-highlighting.py +++ b/filters/syntax-highlighting.py
@@ -34,7 +34,7 @@ sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8', errors='replace
34sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace') 34sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
35data = sys.stdin.read() 35data = sys.stdin.read()
36filename = sys.argv[1] 36filename = sys.argv[1]
37formatter = HtmlFormatter(style='pastie') 37formatter = HtmlFormatter(style='pastie', nobackground=True)
38 38
39try: 39try:
40 lexer = guess_lexer_for_filename(filename, data) 40 lexer = guess_lexer_for_filename(filename, data)
diff --git a/ui-blame.c b/ui-blame.c index d565fff..17e2d60 100644 --- a/ui-blame.c +++ b/ui-blame.c
@@ -67,15 +67,29 @@ static void emit_blame_entry_linenumber(struct blame_entry *ent)
67 htmlf(numberfmt, ++lineno); 67 htmlf(numberfmt, ++lineno);
68} 68}
69 69
70static void emit_blame_entry_line(struct blame_scoreboard *sb, 70static void emit_blame_entry_line_background(struct blame_scoreboard *sb,
71 struct blame_entry *ent) 71 struct blame_entry *ent)
72{ 72{
73 const char *cp, *cpend; 73 unsigned long line;
74 size_t len, maxlen = 2;
75 const char* pos, *endpos;
74 76
75 cp = blame_nth_line(sb, ent->lno); 77 for (line = ent->lno; line < ent->lno + ent->num_lines; line++) {
76 cpend = blame_nth_line(sb, ent->lno + ent->num_lines); 78 html("\n");
79 pos = blame_nth_line(sb, line);
80 endpos = blame_nth_line(sb, line + 1);
81 len = 0;
82 while (pos < endpos) {
83 len++;
84 if (*pos++ == '\t')
85 len = (len + 7) & ~7;
86 }
87 if (len > maxlen)
88 maxlen = len;
89 }
77 90
78 html_ntxt(cp, cpend - cp); 91 for (len = 0; len < maxlen - 1; len++)
92 html(" ");
79} 93}
80 94
81struct walk_tree_context { 95struct walk_tree_context {
@@ -88,6 +102,7 @@ static void print_object(const unsigned char *sha1, const char *path,
88 const char *basename, const char *rev) 102 const char *basename, const char *rev)
89{ 103{
90 enum object_type type; 104 enum object_type type;
105 char *buf;
91 unsigned long size; 106 unsigned long size;
92 struct argv_array rev_argv = ARGV_ARRAY_INIT; 107 struct argv_array rev_argv = ARGV_ARRAY_INIT;
93 struct rev_info revs; 108 struct rev_info revs;
@@ -102,6 +117,13 @@ static void print_object(const unsigned char *sha1, const char *path,
102 return; 117 return;
103 } 118 }
104 119
120 buf = read_sha1_file(sha1, &type, &size);
121 if (!buf) {
122 cgit_print_error_page(500, "Internal server error",
123 "Error reading object %s", sha1_to_hex(sha1));
124 return;
125 }
126
105 argv_array_push(&rev_argv, "blame"); 127 argv_array_push(&rev_argv, "blame");
106 argv_array_push(&rev_argv, rev); 128 argv_array_push(&rev_argv, rev);
107 init_revisions(&revs, NULL); 129 init_revisions(&revs, NULL);
@@ -157,20 +179,37 @@ static void print_object(const unsigned char *sha1, const char *path,
157 html("</td>\n"); 179 html("</td>\n");
158 } 180 }
159 181
160 /* Lines */ 182 html("<td class='lines'><div>");
161 html("<td class='lines'>"); 183
184 /* Colored bars behind lines */
185 html("<div>");
162 for (ent = sb.ent; ent; ) { 186 for (ent = sb.ent; ent; ) {
163 struct blame_entry *e = ent->next; 187 struct blame_entry *e = ent->next;
164 html("<div class='alt'><pre><code>"); 188 html("<div class='alt'><pre>");
165 emit_blame_entry_line(&sb, ent); 189 emit_blame_entry_line_background(&sb, ent);
166 html("</code></pre></div>"); 190 html("</pre></div>");
167 free(ent); 191 free(ent);
168 ent = e; 192 ent = e;
169 } 193 }
170 html("</td>\n"); 194 html("</div>");
171 195
172 free((void *)sb.final_buf); 196 free((void *)sb.final_buf);
173 197
198 /* Lines */
199 html("<pre><code>");
200 if (ctx.repo->source_filter) {
201 char *filter_arg = xstrdup(basename);
202 cgit_open_filter(ctx.repo->source_filter, filter_arg);
203 html_raw(buf, size);
204 cgit_close_filter(ctx.repo->source_filter);
205 free(filter_arg);
206 } else {
207 html_txt(buf);
208 }
209 html("</code></pre>");
210
211 html("</div></td>\n");
212
174 html("</tr>\n</table>\n"); 213 html("</tr>\n</table>\n");
175 214
176 cgit_print_layout_end(); 215 cgit_print_layout_end();