X Tutup
Skip to content

Commit a26df4c

Browse files
committed
Merge branch 'jn/gitweb-syntax-highlight'
* jn/gitweb-syntax-highlight: gitweb: Refactor syntax highlighting support gitweb: Syntax highlighting support
2 parents 04d30ce + 592ea41 commit a26df4c

File tree

3 files changed

+123
-3
lines changed

3 files changed

+123
-3
lines changed

gitweb/gitweb.css

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,3 +572,21 @@ span.match {
572572
div.binary {
573573
font-style: italic;
574574
}
575+
576+
/* Style definition generated by highlight 2.4.5, http://www.andre-simon.de/ */
577+
578+
/* Highlighting theme definition: */
579+
580+
.num { color:#2928ff; }
581+
.esc { color:#ff00ff; }
582+
.str { color:#ff0000; }
583+
.dstr { color:#818100; }
584+
.slc { color:#838183; font-style:italic; }
585+
.com { color:#838183; font-style:italic; }
586+
.dir { color:#008200; }
587+
.sym { color:#000000; }
588+
.line { color:#555555; }
589+
.kwa { color:#000000; font-weight:bold; }
590+
.kwb { color:#830000; }
591+
.kwc { color:#000000; font-weight:bold; }
592+
.kwd { color:#010181; }

gitweb/gitweb.perl

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,19 @@ BEGIN
445445
'javascript-actions' => {
446446
'override' => 0,
447447
'default' => [0]},
448+
449+
# Syntax highlighting support. This is based on Daniel Svensson's
450+
# and Sham Chukoury's work in gitweb-xmms2.git.
451+
# It requires the 'highlight' program present in $PATH,
452+
# and therefore is disabled by default.
453+
454+
# To enable system wide have in $GITWEB_CONFIG
455+
# $feature{'highlight'}{'default'} = [1];
456+
457+
'highlight' => {
458+
'sub' => sub { feature_bool('highlight', @_) },
459+
'override' => 0,
460+
'default' => [0]},
448461
);
449462

450463
sub gitweb_get_feature {
@@ -3179,6 +3192,61 @@ sub blob_contenttype {
31793192
return $type;
31803193
}
31813194

3195+
# guess file syntax for syntax highlighting; return undef if no highlighting
3196+
# the name of syntax can (in the future) depend on syntax highlighter used
3197+
sub guess_file_syntax {
3198+
my ($highlight, $mimetype, $file_name) = @_;
3199+
return undef unless ($highlight && defined $file_name);
3200+
3201+
# configuration for 'highlight' (http://www.andre-simon.de/)
3202+
# match by basename
3203+
my %highlight_basename = (
3204+
#'Program' => 'py',
3205+
#'Library' => 'py',
3206+
'SConstruct' => 'py', # SCons equivalent of Makefile
3207+
'Makefile' => 'make',
3208+
);
3209+
# match by extension
3210+
my %highlight_ext = (
3211+
# main extensions, defining name of syntax;
3212+
# see files in /usr/share/highlight/langDefs/ directory
3213+
map { $_ => $_ }
3214+
qw(py c cpp rb java css php sh pl js tex bib xml awk bat ini spec tcl),
3215+
# alternate extensions, see /etc/highlight/filetypes.conf
3216+
'h' => 'c',
3217+
map { $_ => 'cpp' } qw(cxx c++ cc),
3218+
map { $_ => 'php' } qw(php3 php4),
3219+
map { $_ => 'pl' } qw(perl pm), # perhaps also 'cgi'
3220+
'mak' => 'make',
3221+
map { $_ => 'xml' } qw(xhtml html htm),
3222+
);
3223+
3224+
my $basename = basename($file_name, '.in');
3225+
return $highlight_basename{$basename}
3226+
if exists $highlight_basename{$basename};
3227+
3228+
$basename =~ /\.([^.]*)$/;
3229+
my $ext = $1 or return undef;
3230+
return $highlight_ext{$ext}
3231+
if exists $highlight_ext{$ext};
3232+
3233+
return undef;
3234+
}
3235+
3236+
# run highlighter and return FD of its output,
3237+
# or return original FD if no highlighting
3238+
sub run_highlighter {
3239+
my ($fd, $highlight, $syntax) = @_;
3240+
return $fd unless ($highlight && defined $syntax);
3241+
3242+
close $fd
3243+
or die_error(404, "Reading blob failed");
3244+
open $fd, quote_command(git_cmd(), "cat-file", "blob", $hash)." | ".
3245+
"highlight --xhtml --fragment --syntax $syntax |"
3246+
or die_error(500, "Couldn't open file or run syntax highlighter");
3247+
return $fd;
3248+
}
3249+
31823250
## ======================================================================
31833251
## functions printing HTML: header, footer, error page
31843252

@@ -5380,13 +5448,19 @@ sub git_blob {
53805448
open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash
53815449
or die_error(500, "Couldn't cat $file_name, $hash");
53825450
my $mimetype = blob_mimetype($fd, $file_name);
5451+
# use 'blob_plain' (aka 'raw') view for files that cannot be displayed
53835452
if ($mimetype !~ m!^(?:text/|image/(?:gif|png|jpeg)$)! && -B $fd) {
53845453
close $fd;
53855454
return git_blob_plain($mimetype);
53865455
}
53875456
# we can have blame only for text/* mimetype
53885457
$have_blame &&= ($mimetype =~ m!^text/!);
53895458

5459+
my $highlight = gitweb_check_feature('highlight');
5460+
my $syntax = guess_file_syntax($highlight, $mimetype, $file_name);
5461+
$fd = run_highlighter($fd, $highlight, $syntax)
5462+
if $syntax;
5463+
53905464
git_header_html(undef, $expires);
53915465
my $formats_nav = '';
53925466
if (defined $hash_base && (my %co = parse_commit($hash_base))) {
@@ -5436,9 +5510,8 @@ sub git_blob {
54365510
chomp $line;
54375511
$nr++;
54385512
$line = untabify($line);
5439-
printf "<div class=\"pre\"><a id=\"l%i\" href=\"" . href(-replay => 1)
5440-
. "#l%i\" class=\"linenr\">%4i</a> %s</div>\n",
5441-
$nr, $nr, $nr, esc_html($line, -nbsp=>1);
5513+
printf qq!<div class="pre"><a id="l%i" href="%s#l%i" class="linenr">%4i</a> %s</div>\n!,
5514+
$nr, href(-replay => 1), $nr, $nr, $syntax ? $line : esc_html($line, -nbsp=>1);
54425515
}
54435516
}
54445517
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)
X Tutup