diff options
-rw-r--r-- | html.c | 46 | ||||
-rw-r--r-- | html.h | 1 | ||||
-rw-r--r-- | ui-diff.c | 5 |
3 files changed, 48 insertions, 4 deletions
@@ -156,6 +156,52 @@ ssize_t html_ntxt(const char *txt, size_t len) return slen; } +ssize_t html_ntxt_pre(const char *txt, size_t len) +{ + const char *t = txt; + ssize_t slen; + int prev = 0; + + if (len > SSIZE_MAX) + return -1; + + slen = (ssize_t) len; + while (t && *t && slen--) { + int c = *t; + if (c == '<' || c == '>' || c == '&' || c == ' ' || c == '\t') { + html_raw(txt, t - txt); + if (c == '>') + html(">"); + else if (c == '<') + html("<"); + else if (c == '&') + html("&"); + else if (c == ' ') { + if (!prev || prev == ' ' || prev == '\t') { + html(" "); + /* next byte can be unescaped ' ' */ + c = 160; + } else { + html(" "); + } + } else if (c == '\t') { + html("    " + "    "); + /* next byte can be unescaped ' ' */ + c = 160; + } + txt = t + 1; + } + prev = c; + t++; + } + if (t != txt) + html_raw(txt, t - txt); + return slen; +} + + + void html_attrf(const char *fmt, ...) { va_list ap; @@ -20,6 +20,7 @@ extern void html_attrf(const char *format,...); extern void html_txt(const char *txt); extern ssize_t html_ntxt(const char *txt, size_t len); +extern ssize_t html_ntxt_pre(const char *txt, size_t len); extern void html_attr(const char *txt); extern void html_url_path(const char *txt); extern void html_url_arg(const char *txt); @@ -222,7 +222,6 @@ static void cgit_print_diffstat(const struct object_id *old_oid, static void print_line(char *line, int len) { char *class = "ctx"; - char c = line[len-1]; if (line[0] == '+') class = "add"; @@ -232,10 +231,8 @@ static void print_line(char *line, int len) class = "hunk"; htmlf("<div class='%s'>", class); - line[len-1] = '\0'; - html_txt(line); + html_ntxt_pre(line, len - 1); html("</div>"); - line[len-1] = c; } static void header(const struct object_id *oid1, char *path1, int mode1, |