Skip to content

Commit 779a206

Browse files
ian-kellinggitster
authored andcommitted
gitweb: use highlight's shebang detection
The "highlight" binary can, in some cases, determine the language type by the means of file contents, for example the shebang in the first line for some scripting languages. Make use of this autodetection for files which syntax is not known by gitweb. In that case, pass the blob contents to "highlight --force"; the parameter is needed to make it always generate HTML output (which includes HTML-escaping). Although we now run highlight on files which do not end up highlighted, performance is virtually unaffected because when we call highlight, it is used for escaping HTML. In the case that highlight is used, gitweb calls sanitize() instead of esc_html(), and the latter is significantly slower (it does more, being roughly a superset of sanitize()). Simple benchmark comparing performance of 'blob' view of files without syntax highlighting in gitweb before and after this change indicates ±1% difference in request time for all file types. Benchmark was performed on local instance on Debian, using Apache/2.4.23 web server and CGI. Document the feature and improve syntax highlight documentation, add test to ensure gitweb doesn't crash when language detection is used. Signed-off-by: Ian Kelling <[email protected]> Acked-by: Jakub Narębski <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c151aa3 commit 779a206

File tree

3 files changed

+27
-12
lines changed

3 files changed

+27
-12
lines changed

Documentation/gitweb.conf.txt

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -246,13 +246,20 @@ $highlight_bin::
246246
Note that 'highlight' feature must be set for gitweb to actually
247247
use syntax highlighting.
248248
+
249-
*NOTE*: if you want to add support for new file type (supported by
250-
"highlight" but not used by gitweb), you need to modify `%highlight_ext`
251-
or `%highlight_basename`, depending on whether you detect type of file
252-
based on extension (for example "sh") or on its basename (for example
253-
"Makefile"). The keys of these hashes are extension and basename,
254-
respectively, and value for given key is name of syntax to be passed via
255-
`--syntax <syntax>` to highlighter.
249+
*NOTE*: for a file to be highlighted, its syntax type must be detected
250+
and that syntax must be supported by "highlight". The default syntax
251+
detection is minimal, and there are many supported syntax types with no
252+
detection by default. There are three options for adding syntax
253+
detection. The first and second priority are `%highlight_basename` and
254+
`%highlight_ext`, which detect based on basename (the full filename, for
255+
example "Makefile") and extension (for example "sh"). The keys of these
256+
hashes are the basename and extension, respectively, and the value for a
257+
given key is the name of the syntax to be passed via `--syntax <syntax>`
258+
to "highlight". The last priority is the "highlight" configuration of
259+
`Shebang` regular expressions to detect the language based on the first
260+
line in the file, (for example, matching the line "#!/bin/bash"). See
261+
the highlight documentation and the default config at
262+
/etc/highlight/filetypes.conf for more details.
256263
+
257264
For example if repositories you are hosting use "phtml" extension for
258265
PHP files, and you want to have correct syntax-highlighting for those

gitweb/gitweb.perl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3931,15 +3931,16 @@ sub guess_file_syntax {
39313931
# or return original FD if no highlighting
39323932
sub run_highlighter {
39333933
my ($fd, $highlight, $syntax) = @_;
3934-
return $fd unless ($highlight && defined $syntax);
3934+
return $fd unless ($highlight);
39353935

39363936
close $fd;
3937+
my $syntax_arg = (defined $syntax) ? "--syntax $syntax" : "--force";
39373938
open $fd, quote_command(git_cmd(), "cat-file", "blob", $hash)." | ".
39383939
quote_command($^X, '-CO', '-MEncode=decode,FB_DEFAULT', '-pse',
39393940
'$_ = decode($fe, $_, FB_DEFAULT) if !utf8::decode($_);',
39403941
'--', "-fe=$fallback_encoding")." | ".
39413942
quote_command($highlight_bin).
3942-
" --replace-tabs=8 --fragment --syntax $syntax |"
3943+
" --replace-tabs=8 --fragment $syntax_arg |"
39433944
or die_error(500, "Couldn't open file or run syntax highlighter");
39443945
return $fd;
39453946
}
@@ -7063,8 +7064,7 @@ sub git_blob {
70637064

70647065
my $highlight = gitweb_check_feature('highlight');
70657066
my $syntax = guess_file_syntax($highlight, $file_name);
7066-
$fd = run_highlighter($fd, $highlight, $syntax)
7067-
if $syntax;
7067+
$fd = run_highlighter($fd, $highlight, $syntax);
70687068

70697069
git_header_html(undef, $expires);
70707070
my $formats_nav = '';
@@ -7117,7 +7117,7 @@ sub git_blob {
71177117
$line = untabify($line);
71187118
printf qq!<div class="pre"><a id="l%i" href="%s#l%i" class="linenr">%4i</a> %s</div>\n!,
71197119
$nr, esc_attr(href(-replay => 1)), $nr, $nr,
7120-
$syntax ? sanitize($line) : esc_html($line, -nbsp=>1);
7120+
$highlight ? sanitize($line) : esc_html($line, -nbsp=>1);
71217121
}
71227122
}
71237123
close $fd

t/t9500-gitweb-standalone-no-errors.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,14 @@ test_expect_success HIGHLIGHT \
709709
git commit -m "Add test.sh" &&
710710
gitweb_run "p=.git;a=blob;f=test.sh"'
711711

712+
test_expect_success HIGHLIGHT \
713+
'syntax highlighting (highlighter language autodetection)' \
714+
'git config gitweb.highlight yes &&
715+
echo "#!/usr/bin/perl" > test &&
716+
git add test &&
717+
git commit -m "Add test" &&
718+
gitweb_run "p=.git;a=blob;f=test"'
719+
712720
# ----------------------------------------------------------------------
713721
# forks of projects
714722

0 commit comments

Comments
 (0)