package MojoMojo::Formatter::SyntaxHighlight; use strict; use warnings; use parent qw/MojoMojo::Formatter/; use HTML::Entities; eval "use Syntax::Highlight::Engine::Kate;"; my $eval_res = $@; sub module_loaded { $eval_res ? 0 : 1 } my $main_formatter; eval { $main_formatter = MojoMojo->pref('main_formatter'); }; $main_formatter ||= 'MojoMojo::Formatter::Markdown'; =head1 NAME MojoMojo::Formatter::SyntaxHighlight - syntax highlighting for code blocks =head1 DESCRIPTION This formatter performs syntax highlighting on code blocks. =head1 METHODS =head2 format_content_order The syntax highlight formatter is based on C<<
>>tags entered by the
user, so it must run before other formatters that produce C<< >> tags.
The earliest such formatter is the main formatter.
=cut
sub format_content_order { 14 }
=head2 format_content
This formatter uses L to syntax highlight code
inside of C<< ...
>> tags:
say "Hello world!";
See L for a list of supported
languages.
=cut
# The $kate formatter is scoped outside of format_content. Otherwise, memory
# leaks have occurred. This is alos faster, as it avoids instantiation for every
# request.
my $kate;
sub format_content {
my ( $class, $content ) = @_;
return unless $class->module_loaded;
my @blocks = ();
my $ph = 0;
my $ph_base = __PACKAGE__ . '::PlaceHolder::';
# new school - consistent with other new syntax, but broke for me to the point of exhaustion
# $$content =~ s/\{\{\s*code\s+lang=""\s*\}\}//g;
# while ( $$content =~ s/\{\{\s*code(?:\s+lang=['"]*(.*?)['"]*")?\s*\}\}(.*?)\{\{\s*end\s*\}\}/$ph_base$ph/si ) {
# drop all lang="" -- mateu
$$content =~ s/<\s*pre\s+lang=""\s*>//g;
while ( $$content =~ s/<\s*pre(?:\s+lang=['"]*(.*?)['"]*")?\s*>(.*?)<\s*\/pre\s*>/$ph_base$ph/si ) {
my ( $language, $block ) = ( $1, $2 );
# Fix newline issue
$block =~ s/\r//g;
if ($language) {
eval {
$kate->language($language);
} and do {
$block = $kate->highlightText($block);
}
}
push @blocks, $block;
$ph++;
}
for ( my $i = 0 ; $i < $ph ; $i++ ) {
$$content =~ s/$ph_base$i/$blocks[$i]<\/pre>/;
}
return $content;
}
$kate = Syntax::Highlight::Engine::Kate->new(
language => 'Perl',
substitutions => {
"<" => "<",
">" => ">",
"&" => "&",
" " => " ",
"\t" => " ",
"\n" => "\n",
},
format_table => {
Alert => [ q{}, "" ],
BaseN => [ q{}, "" ],
BString => [ q{}, "" ],
Char => [ q{}, "" ],
Comment => [ q{}, "" ],
DataType => [ q{}, "" ],
DecVal => [ q{}, "" ],
Error => [ q{}, "" ],
Float => [ q{}, "" ],
Function => [ q{}, "" ],
IString => [ q{}, "" ],
Keyword => [ q{}, "" ],
Normal => [ q{}, "" ],
Operator => [ q{}, "" ],
Others => [ q{}, "" ],
RegionMarker => [ q{}, "" ],
Reserved => [ q{}, "" ],
String => [ q{}, "" ],
Variable => [ q{}, "" ],
Warning => [ q{}, "" ],
},
);
=head1 SEE ALSO
L, L and L.
=head1 AUTHORS
Johannes Plunien Eplu@cpan.orgE
=head1 LICENSE
This library is free software. You can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
1;