Have linenumbers in blob displays
[catagits/Gitalist.git] / lib / Gitalist / View / SyntaxHighlight.pm
CommitLineData
7e54e579 1package Gitalist::View::SyntaxHighlight;
2use Moose;
7e54e579 3use namespace::autoclean;
4
5extends 'Catalyst::View';
6
7use Syntax::Highlight::Engine::Kate ();
7e54e579 8
c8870bd3 9use HTML::Entities qw(encode_entities);
10
7e54e579 11sub process {
12 my($self, $c) = @_;
c8870bd3 13
b2e0fe31 14 $c->res->body($self->render($c, $c->res->body, $c->stash));
f5da8e7a 15}
16
8deaad58 17sub render {
18 my ($self, $c, $blob, $args) = @_;
21ede19a 19
20 # Don't bother with anything over 64kb, it'll be tragically slow.
a8f57013 21 return encode_entities $blob if length $blob > 65536;
fe89796b 22
8deaad58 23 my $lang = $args->{language};
f5da8e7a 24
6cf4366a 25 my $ret;
f5da8e7a 26 if($lang) {
6cf4366a 27 # via http://github.com/jrockway/angerwhale/blob/master/lib/Angerwhale/Format/Pod.pm#L136
28 $ret = eval {
c8870bd3 29 no warnings 'redefine';
30 local *Syntax::Highlight::Engine::Kate::Template::logwarning
31 = sub { die @_ }; # i really don't care
32 my $hl = Syntax::Highlight::Engine::Kate->new(
f5da8e7a 33 language => $lang,
c8870bd3 34 substitutions => {
35 "<" => "&lt;",
36 ">" => "&gt;",
37 "&" => "&amp;",
38 q{'} => "&apos;",
39 q{"} => "&quot;",
40 },
41 format_table => {
42 # convert Kate's internal representation into
43 # <span class="<internal name>"> value </span>
44 map {
45 $_ => [ qq{<span class="$_">}, '</span>' ]
46 }
47 qw/Alert BaseN BString Char Comment DataType
48 DecVal Error Float Function IString Keyword
49 Normal Operator Others RegionMarker Reserved
50 String Variable Warning/,
51 },
52 );
53
4621ecf0 54 my $hltxt = $hl->highlightText($blob);
18add14a 55
56 # Line numbering breaks <span class="Other">#define foo\nbar</span>
57 # So let's fix that by closing all spans at end-of-line and opening
58 # new ones on the next, if needed.
59
60 my @lines = split(/\n/, $hltxt);
61 my $last_class = undef;
62 map {
63 unless($_ =~ s/^<\/span>//) {
64 if($last_class) {
65 $_ = "<span class=\"$last_class\">" . $_;
66 }
67 }
68 $last_class = undef;
69 if($_ =~ /<span class="(.*?)">(?!.*<\/span>)/) {
70 $last_class = $1;
71 }
72 if($_ !~ /<\/span>$/) {
73 $_ .= "</span>";
74 }
75 $_;
76 } @lines;
77
78 $hltxt = join("\n", @lines);
4621ecf0 79 $hltxt =~ s/([^[:ascii:]])/encode_entities($1)/eg;
80 $hltxt;
c8870bd3 81 };
82 warn $@ if $@;
c8870bd3 83 }
6cf4366a 84
85 return $ret || encode_entities($blob);
7e54e579 86}
87
1ef8dc7d 88__PACKAGE__->meta->make_immutable;
775e96e0 89
90__END__
91
92=head1 NAME
93
94Gitalist::View::SyntaxHighlight - Responsible for syntax highlighting code
95
96=head1 DESCRIPTION
97
98Catalyst View for Syntax highlighting.
99
d137f7d5 100=head1 METHODS
101
102=head2 process
103
104=head2 highlight
105
775e96e0 106=head1 AUTHORS
107
108See L<Gitalist> for authors.
109
110=head1 LICENSE
111
112See L<Gitalist> for the license.
113
114=cut