Merge remote branch 'seveas/seveas/syntax_highlight'
Dan Brook [Mon, 1 Apr 2013 21:28:44 +0000 (23:28 +0200)]
* seveas/seveas/syntax_highlight:
  Have linenumbers in blob displays
  Syntax higlighting improvements

lib/Gitalist/ContentMangler/Resolver/Default.pm
lib/Gitalist/Model/ContentMangler.pm
lib/Gitalist/View/SyntaxHighlight.pm
root/fragment/ref/blob.tt2
root/ref/blob.tt2
root/static/css/core.css
root/static/css/syntax/Code.css [moved from root/static/css/syntax/Perl.css with 100% similarity]

index 29aeda4..23d409d 100644 (file)
@@ -1,12 +1,51 @@
 use MooseX::Declare;
+use Syntax::Highlight::Engine::Kate ();
+
+our @interpreters = (
+    'awk',
+    'bash',
+    'ksh',
+    'make',
+    'node',
+    'perl',
+    'prolog',
+    'python',
+    'ruby',
+    'sh',
+    'tcl',
+);
+
+our %interpretersx = (
+    'awk'  => 'AWK',
+    'ksh'  => 'Bash',
+    'make' => 'Makefile',
+    'node' => 'Javascript',
+    'sh'   => 'Bash',
+);
 
 class Gitalist::ContentMangler::Resolver::Default with Gitalist::ContentMangler::Resolver {
     method resolve ($data) {
-        # This should be pulled out of $self->config
-        my $language;
-        $language = 'Perl' if $data->{filename} =~ /\.p[lm]$/i;
-        $language = 'Diff' if $data->{action} eq 'diff_fancy';
+        if($data->{action} eq 'diff_fancy') {
+            return 'Gitalist::ContentMangler::Transformer::SyntaxHighlight' => {language => 'Diff', css => 'Diff'};
+        }
+        my $kate = Syntax::Highlight::Engine::Kate->new();
+        # Detect .t files as perl code
+        $kate->extensions->{'*.t'} = ['Perl'];
+        my $language = $kate->languagePropose($data->{filename}) || $kate->languagePropose(lc $data->{filename});
+        if(!$language && exists($data->{blob})) {
+            my $interp = substr(${$data->{blob}}, 0, 256);
+            if($interp =~ /^#!(?:\S*\/)?([^\s\/]+)/) {
+                my $interp = $1;
+
+                for my $interpreter (@interpreters) {
+                    if($interp =~ /$interpreter/) {
+                        $language = $interpretersx{$interpreter} || ucfirst $interpreter;
+                        last;
+                    }
+                }
+            }
+        }
         return unless $language;
-        return 'Gitalist::ContentMangler::Transformer::SyntaxHighlight' => {language => $language, css => $language};
+        return 'Gitalist::ContentMangler::Transformer::SyntaxHighlight' => {language => $language, css => 'Code'};
     }
 }
index 6182362..720e0b3 100644 (file)
@@ -48,6 +48,7 @@ sub process {
 
   my($transformer, $config) = $self->resolve({
     filename => $c->stash->{filename} || '',
+    blob     => \$c->stash->{blob},
     config   => Gitalist->config->{'Model::ContentMangler'},
     action   => $c->action->name,
   });
index 4d98c36..f0b8f6e 100644 (file)
@@ -5,7 +5,6 @@ use namespace::autoclean;
 extends 'Catalyst::View';
 
 use Syntax::Highlight::Engine::Kate ();
-use Syntax::Highlight::Engine::Kate::Perl ();
 
 use HTML::Entities qw(encode_entities);
 
@@ -19,7 +18,7 @@ sub render {
     my ($self, $c, $blob, $args) = @_;
 
     # Don't bother with anything over 64kb, it'll be tragically slow.
-    return encode_entities $blob if length $blob > 8192;
+    return encode_entities $blob if length $blob > 65536;
 
     my $lang = $args->{language};
 
@@ -53,6 +52,30 @@ sub render {
             );
 
             my $hltxt = $hl->highlightText($blob);
+
+            # Line numbering breaks <span class="Other">#define foo\nbar</span>
+            # So let's fix that by closing all spans at end-of-line and opening
+            # new ones on the next, if needed.
+
+            my @lines = split(/\n/, $hltxt);
+            my $last_class = undef;
+            map {
+                unless($_ =~ s/^<\/span>//) {
+                    if($last_class) {
+                        $_ = "<span class=\"$last_class\">" . $_;
+                    }
+                }
+                $last_class = undef;
+                if($_ =~ /<span class="(.*?)">(?!.*<\/span>)/) {
+                    $last_class = $1;
+                }
+                if($_ !~ /<\/span>$/) {
+                    $_ .= "</span>";
+                }
+                $_;
+            } @lines;
+
+            $hltxt = join("\n", @lines);
             $hltxt =~ s/([^[:ascii:]])/encode_entities($1)/eg;
             $hltxt;
         };
index cb6097a..f527abb 100644 (file)
@@ -3,7 +3,14 @@
 [%- ELSIF is_binary -%]
 <div class='blob'>This is a binary file which won't render natively on the web, but you can get it here all the same: <a href="[% c.uri_for_action('/ref/raw', c.req.captures, filename) %]" title="[% filename %]">[% filename %]</a></div>
 [%- ELSE -%]
-[%- INCLUDE inc/syntax_highlight_css.tt2 -%]
 [%- USE UTF8Decode -%]
-<pre class='blob'>[% IF mangled; blob; ELSE; blob | utf8_decode | html; END; %]</pre>
+[%- IF mangled; INCLUDE inc/syntax_highlight_css.tt2; END -%]
+[% FOR line IN blob.split("\n") %]
+ <tr class=''>
+   <td nowrap class='lineno' id='l[% loop.index+1 %]'><tt><a href='[% c.uri_for_action('/ref/blame', [Repository.name, info.commit.sha1], filename.to_path ) %]#l[% lopo.index %]'>[% loop.index+1 %]</a></tt></td>
+   <td nowrap class='data'><pre>[%-
+     IF mangled; line; ELSE; line | utf8_decode | html; END
+   -%]</pre></td>
+ </tr>
+[% END %]
 [%- END -%]
index 9de554c..ee8b007 100755 (executable)
@@ -6,7 +6,12 @@
    </div>
   [% END %]
 
+<div id="blob">
+<table class="listing">
+<tbody>
 [% subinclude('/fragment/ref/blob', c.req.captures, c.req.args.to_path) %]
-
+</tbody>
+</table>
+</div>
 
 
index 98411b1..f98df2b 100755 (executable)
@@ -493,21 +493,21 @@ BUT the final width needs to be set with javascript based on the parent element
 
 
 /* /blame */
-#blame pre, #blame tt {
+#blame pre, #blame tt, #blob pre, #blob tt {
   margin: 0;
   font-size: 12px;
 }
 #blame .commit-info {
 
 }
-#blame .lineno {
+#blame .lineno, #blob .lineno {
   text-align: right;
   padding: 0 8px;
 }
-#blame a {
+#blame a, #blob a {
  text-decoration: none;
 }
-#blame {
+#blame, #blob {
     overflow-x: scroll;
 }
 #blame tr.alt {
@@ -516,37 +516,21 @@ BUT the final width needs to be set with javascript based on the parent element
 #blame tbody tr:hover {
   background-color: #fefeaa;
 }
-#blame td {
+#blame td, #blob td {
        vertical-align:middle;
        padding: 3px;
 }
-#blame td.lineno {
+#blame td.lineno, #blob td.lineno {
   background-color: #eee;
 }
 #blame td.date, #blame td.author, #blame td.commit-info {
 }
-#blame tbody td.data {
+#blame tbody td.data, #blob tbody td.data {
   padding-left: 5px;
   background-color: #333;
   color: #ddd;
 }
 
-/* /blob */
-pre.blob {
-  background-color: #333;
-  color: #ddd;
-  border-left: solid 3px #c33;
-  padding: 5px;
-  padding-left: 15px;
-  margin: 20px 15px 20px;
-  overflow:auto;
-  font-size:12px;
-}
-div.blob {
-    text-align: center;
-    margin: 30px;
-}
-
 /* /blobdiff etc */
 
 .commit-message {