* [PATCH/RFC 1/2 v2] gitweb: Syntax highlighting support
@ 2010-02-28 20:28 Jakub Narebski
2010-02-28 20:28 ` [PATCH/RFC 2/2] gitweb: Refactor syntax " Jakub Narebski
0 siblings, 1 reply; 2+ messages in thread
From: Jakub Narebski @ 2010-02-28 20:28 UTC (permalink / raw)
To: git; +Cc: Johannes Schindelin, Jakub Narebski
From: Johannes Schindelin <johannes.schindelin@gmx.de>
It requires the 'highlight' program to do all the heavy-lifting.
This is loosely based on Daniel Svensson's and Sham Chukoury's work in
gitweb-xmms2.git (it cannot be cherry-picked, as gitweb-xmms2 first forked
wildly, then not contributed back, and then went stale).
[jn: cherry picked from bc1ed6aafd9ee4937559535c66c8bddf1864bec6
in http://repo.or.cz/w/git/dscho.git, with a few changes]
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
Compared to the version in Dscho repository, it makes gitweb do line
numbering by itself, instead of making 'highlight' do it... and then
rewriting it to conform to the rest of gitweb. It also leaves tab
expansion to gitweb, for 'blob' view to look the same with and without
syntax hightlighting enabled.
The list of supported extensions is widened, and syntax is decided
based on basename, not on whole pathname (which might be a mistake).
Also the '.in' suffix is stripped if it is present (so 'git.spec.in'
file would use 'spec' syntax).
Note that gitweb.css contains default 'highlight' style, but perhaps
other style would be better fit for deafule gitweb CSS.
gitweb/gitweb.css | 18 ++++++++++++++
gitweb/gitweb.perl | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 82 insertions(+), 1 deletions(-)
diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 50067f2..4132aab 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -572,3 +572,21 @@ span.match {
div.binary {
font-style: italic;
}
+
+/* Style definition generated by highlight 2.4.5, http://www.andre-simon.de/ */
+
+/* Highlighting theme definition: */
+
+.num { color:#2928ff; }
+.esc { color:#ff00ff; }
+.str { color:#ff0000; }
+.dstr { color:#818100; }
+.slc { color:#838183; font-style:italic; }
+.com { color:#838183; font-style:italic; }
+.dir { color:#008200; }
+.sym { color:#000000; }
+.line { color:#555555; }
+.kwa { color:#000000; font-weight:bold; }
+.kwb { color:#830000; }
+.kwc { color:#000000; font-weight:bold; }
+.kwd { color:#010181; }
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 32b04a4..5b85581 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -227,6 +227,36 @@ our %avatar_size = (
# Leave it undefined (or set to 'undef') to turn off load checking.
our $maxload = 300;
+# syntax highlighting
+our %highlight_type = (
+ # match by basename
+ 'SConstruct' => 'py',
+ 'Program' => 'py',
+ 'Library' => 'py',
+ 'Makefile' => 'make',
+ # match by extension
+ '\.py$' => 'py', # Python
+ '\.c$' => 'c',
+ '\.h$' => 'c',
+ '\.cpp$' => 'cpp',
+ '\.cxx$' => 'cpp',
+ '\.rb$' => 'ruby',
+ '\.java$' => 'java',
+ '\.css$' => 'css',
+ '\.php3?$' => 'php',
+ '\.sh$' => 'sh', # Bash / shell script
+ '\.pl$' => 'pl', # Perl
+ '\.js$' => 'js', # JavaScript
+ '\.tex$' => 'tex', # TeX and LaTeX
+ '\.bib$' => 'bib', # BibTeX
+ '\.x?html$' => 'xml',
+ '\.xml$' => 'xml',
+ '\.awk$' => 'awk',
+ '\.bat$' => 'bat', # DOS Batch script
+ '\.ini$' => 'ini',
+ '\.spec$' => 'spec', # RPM Spec
+);
+
# You define site-wide feature defaults here; override them with
# $GITWEB_CONFIG as necessary.
our %feature = (
@@ -445,6 +475,19 @@ our %feature = (
'javascript-actions' => {
'override' => 0,
'default' => [0]},
+
+ # Syntax highlighting support. This is based on Daniel Svensson's
+ # and Sham Chukoury's work in gitweb-xmms2.git.
+ # It requires the 'highlight' program, and therefore is disabled
+ # by default.
+
+ # To enable system wide have in $GITWEB_CONFIG
+ # $feature{'highlight'}{'default'} = [1];
+
+ 'highlight' => {
+ 'sub' => sub { feature_bool('highlight', @_) },
+ 'override' => 0,
+ 'default' => [0]},
);
sub gitweb_get_feature {
@@ -5340,6 +5383,7 @@ sub git_blob {
open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash
or die_error(500, "Couldn't cat $file_name, $hash");
my $mimetype = blob_mimetype($fd, $file_name);
+ # use 'blob_plain' (aka 'raw') view for files that cannot be displayed
if ($mimetype !~ m!^(?:text/|image/(?:gif|png|jpeg)$)! && -B $fd) {
close $fd;
return git_blob_plain($mimetype);
@@ -5347,6 +5391,25 @@ sub git_blob {
# we can have blame only for text/* mimetype
$have_blame &&= ($mimetype =~ m!^text/!);
+ my $have_highlight = gitweb_check_feature('highlight');
+ my $syntax;
+ if ($have_highlight && defined($file_name)) {
+ my $basename = basename($file_name, '.in');
+ foreach my $regexp (keys %highlight_type) {
+ if ($basename =~ /$regexp/) {
+ $syntax = $highlight_type{$regexp};
+ last;
+ }
+ }
+
+ if ($syntax) {
+ close $fd;
+ open $fd, quote_command(git_cmd(), "cat-file", "blob", $hash)." | ".
+ "highlight --xhtml --fragment -t 8 --syntax $syntax |"
+ or die_error(500, "Couldn't open file or run syntax highlighter");
+ }
+ }
+
git_header_html(undef, $expires);
my $formats_nav = '';
if (defined $hash_base && (my %co = parse_commit($hash_base))) {
@@ -5398,7 +5461,7 @@ sub git_blob {
$line = untabify($line);
printf "<div class=\"pre\"><a id=\"l%i\" href=\"" . href(-replay => 1)
. "#l%i\" class=\"linenr\">%4i</a> %s</div>\n",
- $nr, $nr, $nr, esc_html($line, -nbsp=>1);
+ $nr, $nr, $nr, $syntax ? $line : esc_html($line, -nbsp=>1);
}
}
close $fd
--
1.6.6.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH/RFC 2/2] gitweb: Refactor syntax highlighting support
2010-02-28 20:28 [PATCH/RFC 1/2 v2] gitweb: Syntax highlighting support Jakub Narebski
@ 2010-02-28 20:28 ` Jakub Narebski
0 siblings, 0 replies; 2+ messages in thread
From: Jakub Narebski @ 2010-02-28 20:28 UTC (permalink / raw)
To: git; +Cc: Johannes Schindelin, Jakub Narebski
This refactoring (adding blob_syntax_highlight and blob_highlight
subroutines) is meant to make it easier 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, or on file extension.
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 <jnareb@gmail.com>
---
This probably could be squashed together with previous patch.
It is an RFC, because I am not sure about names blob_syntax_highlight
and blob_highlight for subroutines.
Note: if 'SConstruct', 'Program' and 'Library' must match path, and
not only basename to identify Python (py) program, then current
solution of using hash-table instead of loop over regexp to match
would be not possible.
[I probably should update comment and add some information to
gitweb/README and/or gitweb/INSTALL about syntax hightlight support.]
gitweb/gitweb.perl | 106 ++++++++++++++++---------------
t/t9500-gitweb-standalone-no-errors.sh | 29 +++++++++
2 files changed, 84 insertions(+), 51 deletions(-)
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 5b85581..528ffe1 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -227,36 +227,6 @@ our %avatar_size = (
# Leave it undefined (or set to 'undef') to turn off load checking.
our $maxload = 300;
-# syntax highlighting
-our %highlight_type = (
- # match by basename
- 'SConstruct' => 'py',
- 'Program' => 'py',
- 'Library' => 'py',
- 'Makefile' => 'make',
- # match by extension
- '\.py$' => 'py', # Python
- '\.c$' => 'c',
- '\.h$' => 'c',
- '\.cpp$' => 'cpp',
- '\.cxx$' => 'cpp',
- '\.rb$' => 'ruby',
- '\.java$' => 'java',
- '\.css$' => 'css',
- '\.php3?$' => 'php',
- '\.sh$' => 'sh', # Bash / shell script
- '\.pl$' => 'pl', # Perl
- '\.js$' => 'js', # JavaScript
- '\.tex$' => 'tex', # TeX and LaTeX
- '\.bib$' => 'bib', # BibTeX
- '\.x?html$' => 'xml',
- '\.xml$' => 'xml',
- '\.awk$' => 'awk',
- '\.bat$' => 'bat', # DOS Batch script
- '\.ini$' => 'ini',
- '\.spec$' => 'spec', # RPM Spec
-);
-
# You define site-wide feature defaults here; override them with
# $GITWEB_CONFIG as necessary.
our %feature = (
@@ -3192,6 +3162,55 @@ sub blob_contenttype {
return $type;
}
+sub blob_syntax_highlight {
+ my ($highlight, $mimetype, $file_name) = @_;
+ return undef unless ($highlight && defined $file_name);
+
+ # match by basename
+ my %highlight_basename = (
+ #'SConstruct' => 'py',
+ #'Program' => 'py',
+ #'Library' => 'py',
+ 'Makefile' => 'make',
+ );
+ # match by extension
+ my %highlight_ext = (
+ # see files in /usr/share/highlight/langDefs/ directory
+ map { $_ => $_ }
+ qw(py c cpp rb java css php sh pl js tex bib xml awk bat ini spec tcl),
+ # alternate extensions, see /etc/highlight/filetypes.conf
+ 'h' => 'c',
+ 'cxx' => 'cpp', 'c++' => 'cpp',
+ 'php3' => 'php', 'php4' => 'php',
+ 'perl' => 'pl', 'pm' => 'pl',
+ 'mak' => 'make',
+ 'xhtml' => 'xml', 'html' => 'xml', 'htm' => 'xml',
+ );
+
+ my $basename = basename($file_name, '.in');
+ return $highlight_basename{$basename}
+ if exists $highlight_basename{$basename};
+
+ $basename =~ /\.([^.]*)$/;
+ my $ext = $1 or return undef;
+ return $highlight_ext{$ext}
+ if exists $highlight_ext{$ext};
+
+ return undef;
+}
+
+sub blob_highlight {
+ my ($fd, $highlight, $syntax) = @_;
+ return $fd unless ($highlight && defined $syntax);
+
+ close $fd
+ or die_error(404, "Reading blob failed");
+ open $fd, quote_command(git_cmd(), "cat-file", "blob", $hash)." | ".
+ "highlight --xhtml --fragment --syntax $syntax |"
+ or die_error(500, "Couldn't open file or run syntax highlighter");
+ return $fd;
+}
+
## ======================================================================
## functions printing HTML: header, footer, error page
@@ -5391,24 +5410,10 @@ sub git_blob {
# we can have blame only for text/* mimetype
$have_blame &&= ($mimetype =~ m!^text/!);
- my $have_highlight = gitweb_check_feature('highlight');
- my $syntax;
- if ($have_highlight && defined($file_name)) {
- my $basename = basename($file_name, '.in');
- foreach my $regexp (keys %highlight_type) {
- if ($basename =~ /$regexp/) {
- $syntax = $highlight_type{$regexp};
- last;
- }
- }
-
- if ($syntax) {
- close $fd;
- open $fd, quote_command(git_cmd(), "cat-file", "blob", $hash)." | ".
- "highlight --xhtml --fragment -t 8 --syntax $syntax |"
- or die_error(500, "Couldn't open file or run syntax highlighter");
- }
- }
+ my $highlight = gitweb_check_feature('highlight');
+ my $syntax = blob_syntax_highlight($highlight, $mimetype, $file_name);
+ $fd = blob_highlight($fd, $highlight, $syntax)
+ if $syntax;
git_header_html(undef, $expires);
my $formats_nav = '';
@@ -5459,9 +5464,8 @@ sub git_blob {
chomp $line;
$nr++;
$line = untabify($line);
- printf "<div class=\"pre\"><a id=\"l%i\" href=\"" . href(-replay => 1)
- . "#l%i\" class=\"linenr\">%4i</a> %s</div>\n",
- $nr, $nr, $nr, $syntax ? $line : esc_html($line, -nbsp=>1);
+ printf qq!<div class="pre"><a id="l%i" href="%s#l%i" class="linenr">%4i</a> %s</div>\n!,
+ $nr, href(-replay => 1), $nr, $nr, $syntax ? $line : esc_html($line, -nbsp=>1);
}
}
close $fd
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index 2fc7fdb..0fe9beb 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -639,4 +639,33 @@ test_expect_success \
gitweb_run "p=.git;a=summary"'
test_debug 'cat gitweb.log'
+# ----------------------------------------------------------------------
+# syntax highlighting
+
+cat >>gitweb_config.perl <<\EOF
+$feature{'highlight'}{'override'} = 1;
+EOF
+
+highlight --version >/dev/null 2>&1
+if [ $? -eq 127 ]; then
+ say "Skipping syntax highlighting test, because 'highlight' was not found"
+else
+ test_set_prereq HIGHLIGHT
+fi
+
+test_expect_success HIGHLIGHT \
+ 'syntax highlighting (no highlight)' \
+ 'git config gitweb.highlight yes &&
+ gitweb_run "p=.git;a=blob;f=file"'
+test_debug 'cat gitweb.log'
+
+test_expect_success HIGHLIGHT \
+ 'syntax highlighting (highlighted)' \
+ 'git config gitweb.highlight yes &&
+ echo "#!/usr/bin/sh" > test.sh &&
+ git add test.sh &&
+ git commit -m "Add test.sh" &&
+ gitweb_run "p=.git;a=blob;f=test.sh"'
+test_debug 'cat gitweb.log'
+
test_done
--
1.6.6.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-02-28 20:28 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-28 20:28 [PATCH/RFC 1/2 v2] gitweb: Syntax highlighting support Jakub Narebski
2010-02-28 20:28 ` [PATCH/RFC 2/2] gitweb: Refactor syntax " Jakub Narebski
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).