@@ -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
450463sub 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
0 commit comments