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'};
}
}
my($transformer, $config) = $self->resolve({
filename => $c->stash->{filename} || '',
+ blob => \$c->stash->{blob},
config => Gitalist->config->{'Model::ContentMangler'},
action => $c->action->name,
});
extends 'Catalyst::View';
use Syntax::Highlight::Engine::Kate ();
-use Syntax::Highlight::Engine::Kate::Perl ();
use HTML::Entities qw(encode_entities);
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};
);
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;
};
[%- 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 -%]
</div>
[% END %]
+<div id="blob">
+<table class="listing">
+<tbody>
[% subinclude('/fragment/ref/blob', c.req.captures, c.req.args.to_path) %]
-
+</tbody>
+</table>
+</div>
/* /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 {
#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 {