Ado

 view release on metacpan or  search on metacpan

lib/Ado/Plugin/MarkdownRenderer.pm  view on Meta::CPAN

package Ado::Plugin::MarkdownRenderer;
use Mojo::Base 'Ado::Plugin';
use Mojo::File qw(path);
File::Basename->import('fileparse');
File::Spec::Functions->import(qw(catfile catdir));
Mojo::ByteStream->import('b');

sub register {
    my ($self, $app, $config) = shift->initialise(@_);

    #Make sure we have all we need from config files.
    $config->{md_renderer}      ||= 'Text::MultiMarkdown';
    $config->{md_method}        ||= 'markdown';
    $config->{md_options}       ||= {use_wikilinks => 1,};
    $config->{md_helper}        ||= 'md_to_html';
    $config->{md_root}          ||= $app->home->rel_file('public/doc');
    $config->{md_articles_root} ||= $app->home->rel_file('public/articles');
    $config->{md_file_sufixes}  ||= ['.md'];

    if ($config->{md_renderer} eq 'Text::MultiMarkdown') {
        require Text::MultiMarkdown;
        $app->helper($config->{md_helper} => sub { md_to_html(shift, $config, @_) });
        $app->helper(
            markdown => sub {
                my $c = shift;
                return Text::MultiMarkdown::markdown(@_);
            }
        );

    }

    #make plugin configuration available for later in the app
    $app->config(__PACKAGE__, $config);
    return $self;
}

sub md_to_html {
    my ($c, $config, $file_path) = @_;
    $file_path ||= ($c->stash('md_file') || return '');

    #remove anchors
    $file_path =~ s{[^#]#.+}{};
    unless ($file_path) { $c->reply->not_found() && return '' }
    my $fullname = catfile($config->{md_root}, $file_path);
    $c->debug("md_file: $file_path; \$fullname: $fullname");

    my ($name, $path, $suffix) = fileparse($fullname, @{$config->{md_file_sufixes}});
    my $html_filepath = catfile($path, "$name.html");

    #Reuse previously produced html file if md_file is older than the html file.
    if (   $config->{md_reuse_produced_html}
        && -s $html_filepath
        && (stat($fullname))[9] < (stat($html_filepath))[9])
    {
        $c->debug('Found ' . $html_filepath);
        return b(path($html_filepath)->slurp)->decode;
    }

    #404 Not Found
    my $md_filepath = catfile($path, "$name$suffix");
    unless (-s $md_filepath) { $c->reply->not_found() && return '' }

    my $markdown = path($md_filepath)->slurp;
    my $self_url = $c->url_for()->to_string;
    my %options  = (%{$config->{md_options}}, self_url => $self_url);
    my $html     = $c->markdown($markdown, \%options);
    $c->debug($c->dumper({'%options' => \%options, '$html_filepath' => $html_filepath}));
    path($html_filepath)->spurt($html);
    return b($html)->decode;
}

1;


=pod

=encoding utf8

=head1 NAME

Ado::Plugin::MarkDownRenderer - Render markdown to HTML


=head1 SYNOPSIS

  #1. Use one or more markup parsers
  plugins => [
    #...
    #use default configuration
    'markdown_renderer',

    #Create your own Text::Trac based wiki
    {name => 'markdown_renderer', config => {
      md_renderer =>'Text::Trac',
      md_options => {
        trac_url      => '/wiki',
        disable_links => [ qw( changeset ticket ) ],
      },
      md_method => 'parse',
      md_helper =>'trac_to_html'
    }},
    #...
  ],

  #2. Describe your routes
  routes     => [
        #markdown_renderer route is already configured
        #in etc/plugins/markdown_renderer.conf.

        #Your own great enterprise wiki
        {route => '/wiki/*md_file', via => ['GET'],
          to => 'wiki#show',},
        #...
        ],

  #3. Write your controller
  package Ado::Control::Wiki;
  use Mojo::Base 'Ado::Control';
  #...



( run in 4.120 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )