Skip to content

Commit 592ea41

Browse files
jnarebgitster
authored andcommitted
gitweb: Refactor syntax highlighting support
This refactoring (adding guess_file_syntax and run_highlighter subroutines) is meant to make it easier in the future to add support for other syntax highlighing solutions, or make it smarter by not re-running `git cat-file` second time. Instead of looping over list of regexps (keys of %highlight_type hash), make use of the fact that choosing syntax is based either on full basename (%highlight_basename), or on file extension (%highlight_ext). Add some basic test of syntax highlighting (with 'highlight' as prerequisite) to t/t9500-gitweb-standalone-no-errors.sh test. While at it make git_blob Perl style prettier. Signed-off-by: Jakub Narebski <[email protected]> Acked-by: Petr Baudis <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b331fe5 commit 592ea41

File tree

2 files changed

+92
-53
lines changed

2 files changed

+92
-53
lines changed

gitweb/gitweb.perl

Lines changed: 63 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -227,36 +227,6 @@ BEGIN
227227
# Leave it undefined (or set to 'undef') to turn off load checking.
228228
our $maxload = 300;
229229

230-
# syntax highlighting
231-
our %highlight_type = (
232-
# match by basename
233-
'SConstruct' => 'py',
234-
'Program' => 'py',
235-
'Library' => 'py',
236-
'Makefile' => 'make',
237-
# match by extension
238-
'\.py$' => 'py', # Python
239-
'\.c$' => 'c',
240-
'\.h$' => 'c',
241-
'\.cpp$' => 'cpp',
242-
'\.cxx$' => 'cpp',
243-
'\.rb$' => 'ruby',
244-
'\.java$' => 'java',
245-
'\.css$' => 'css',
246-
'\.php3?$' => 'php',
247-
'\.sh$' => 'sh', # Bash / shell script
248-
'\.pl$' => 'pl', # Perl
249-
'\.js$' => 'js', # JavaScript
250-
'\.tex$' => 'tex', # TeX and LaTeX
251-
'\.bib$' => 'bib', # BibTeX
252-
'\.x?html$' => 'xml',
253-
'\.xml$' => 'xml',
254-
'\.awk$' => 'awk',
255-
'\.bat$' => 'bat', # DOS Batch script
256-
'\.ini$' => 'ini',
257-
'\.spec$' => 'spec', # RPM Spec
258-
);
259-
260230
# You define site-wide feature defaults here; override them with
261231
# $GITWEB_CONFIG as necessary.
262232
our %feature = (
@@ -478,8 +448,8 @@ BEGIN
478448

479449
# Syntax highlighting support. This is based on Daniel Svensson's
480450
# and Sham Chukoury's work in gitweb-xmms2.git.
481-
# It requires the 'highlight' program, and therefore is disabled
482-
# by default.
451+
# It requires the 'highlight' program present in $PATH,
452+
# and therefore is disabled by default.
483453

484454
# To enable system wide have in $GITWEB_CONFIG
485455
# $feature{'highlight'}{'default'} = [1];
@@ -3198,6 +3168,61 @@ sub blob_contenttype {
31983168
return $type;
31993169
}
32003170

3171+
# guess file syntax for syntax highlighting; return undef if no highlighting
3172+
# the name of syntax can (in the future) depend on syntax highlighter used
3173+
sub guess_file_syntax {
3174+
my ($highlight, $mimetype, $file_name) = @_;
3175+
return undef unless ($highlight && defined $file_name);
3176+
3177+
# configuration for 'highlight' (http://www.andre-simon.de/)
3178+
# match by basename
3179+
my %highlight_basename = (
3180+
#'Program' => 'py',
3181+
#'Library' => 'py',
3182+
'SConstruct' => 'py', # SCons equivalent of Makefile
3183+
'Makefile' => 'make',
3184+
);
3185+
# match by extension
3186+
my %highlight_ext = (
3187+
# main extensions, defining name of syntax;
3188+
# see files in /usr/share/highlight/langDefs/ directory
3189+
map { $_ => $_ }
3190+
qw(py c cpp rb java css php sh pl js tex bib xml awk bat ini spec tcl),
3191+
# alternate extensions, see /etc/highlight/filetypes.conf
3192+
'h' => 'c',
3193+
map { $_ => 'cpp' } qw(cxx c++ cc),
3194+
map { $_ => 'php' } qw(php3 php4),
3195+
map { $_ => 'pl' } qw(perl pm), # perhaps also 'cgi'
3196+
'mak' => 'make',
3197+
map { $_ => 'xml' } qw(xhtml html htm),
3198+
);
3199+
3200+
my $basename = basename($file_name, '.in');
3201+
return $highlight_basename{$basename}
3202+
if exists $highlight_basename{$basename};
3203+
3204+
$basename =~ /\.([^.]*)$/;
3205+
my $ext = $1 or return undef;
3206+
return $highlight_ext{$ext}
3207+
if exists $highlight_ext{$ext};
3208+
3209+
return undef;
3210+
}
3211+
3212+
# run highlighter and return FD of its output,
3213+
# or return original FD if no highlighting
3214+
sub run_highlighter {
3215+
my ($fd, $highlight, $syntax) = @_;
3216+
return $fd unless ($highlight && defined $syntax);
3217+
3218+
close $fd
3219+
or die_error(404, "Reading blob failed");
3220+
open $fd, quote_command(git_cmd(), "cat-file", "blob", $hash)." | ".
3221+
"highlight --xhtml --fragment --syntax $syntax |"
3222+
or die_error(500, "Couldn't open file or run syntax highlighter");
3223+
return $fd;
3224+
}
3225+
32013226
## ======================================================================
32023227
## functions printing HTML: header, footer, error page
32033228

@@ -5397,24 +5422,10 @@ sub git_blob {
53975422
# we can have blame only for text/* mimetype
53985423
$have_blame &&= ($mimetype =~ m!^text/!);
53995424

5400-
my $have_highlight = gitweb_check_feature('highlight');
5401-
my $syntax;
5402-
if ($have_highlight && defined($file_name)) {
5403-
my $basename = basename($file_name, '.in');
5404-
foreach my $regexp (keys %highlight_type) {
5405-
if ($basename =~ /$regexp/) {
5406-
$syntax = $highlight_type{$regexp};
5407-
last;
5408-
}
5409-
}
5410-
5411-
if ($syntax) {
5412-
close $fd;
5413-
open $fd, quote_command(git_cmd(), "cat-file", "blob", $hash)." | ".
5414-
"highlight --xhtml --fragment -t 8 --syntax $syntax |"
5415-
or die_error(500, "Couldn't open file or run syntax highlighter");
5416-
}
5417-
}
5425+
my $highlight = gitweb_check_feature('highlight');
5426+
my $syntax = guess_file_syntax($highlight, $mimetype, $file_name);
5427+
$fd = run_highlighter($fd, $highlight, $syntax)
5428+
if $syntax;
54185429

54195430
git_header_html(undef, $expires);
54205431
my $formats_nav = '';
@@ -5465,9 +5476,8 @@ sub git_blob {
54655476
chomp $line;
54665477
$nr++;
54675478
$line = untabify($line);
5468-
printf "<div class=\"pre\"><a id=\"l%i\" href=\"" . href(-replay => 1)
5469-
. "#l%i\" class=\"linenr\">%4i</a> %s</div>\n",
5470-
$nr, $nr, $nr, $syntax ? $line : esc_html($line, -nbsp=>1);
5479+
printf qq!<div class="pre"><a id="l%i" href="%s#l%i" class="linenr">%4i</a> %s</div>\n!,
5480+
$nr, href(-replay => 1), $nr, $nr, $syntax ? $line : esc_html($line, -nbsp=>1);
54715481
}
54725482
}
54735483
close $fd

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,4 +647,33 @@ test_expect_success \
647647
gitweb_run "p=.git;a=summary"'
648648
test_debug 'cat gitweb.log'
649649

650+
# ----------------------------------------------------------------------
651+
# syntax highlighting
652+
653+
cat >>gitweb_config.perl <<\EOF
654+
$feature{'highlight'}{'override'} = 1;
655+
EOF
656+
657+
highlight --version >/dev/null 2>&1
658+
if [ $? -eq 127 ]; then
659+
say "Skipping syntax highlighting test, because 'highlight' was not found"
660+
else
661+
test_set_prereq HIGHLIGHT
662+
fi
663+
664+
test_expect_success HIGHLIGHT \
665+
'syntax highlighting (no highlight)' \
666+
'git config gitweb.highlight yes &&
667+
gitweb_run "p=.git;a=blob;f=file"'
668+
test_debug 'cat gitweb.log'
669+
670+
test_expect_success HIGHLIGHT \
671+
'syntax highlighting (highlighted)' \
672+
'git config gitweb.highlight yes &&
673+
echo "#!/usr/bin/sh" > test.sh &&
674+
git add test.sh &&
675+
git commit -m "Add test.sh" &&
676+
gitweb_run "p=.git;a=blob;f=test.sh"'
677+
test_debug 'cat gitweb.log'
678+
650679
test_done

0 commit comments

Comments
 (0)