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;