| blib/lib/App/mookview.pm | |||
|---|---|---|---|
| Criterion | Covered | Total | % |
| statement | 80 | 94 | 85.1 |
| branch | 6 | 16 | 37.5 |
| condition | n/a | ||
| subroutine | 19 | 22 | 86.3 |
| pod | 1 | 8 | 12.5 |
| total | 106 | 140 | 75.7 |
| line | stmt | bran | cond | sub | pod | time | code |
|---|---|---|---|---|---|---|---|
| 1 | package App::mookview; | ||||||
| 2 | 2 | 2 | 35744 | use 5.008005; | |||
| 2 | 9 | ||||||
| 2 | 76 | ||||||
| 3 | 2 | 2 | 12 | use strict; | |||
| 2 | 3 | ||||||
| 2 | 86 | ||||||
| 4 | 2 | 2 | 22 | use warnings; | |||
| 2 | 11 | ||||||
| 2 | 68 | ||||||
| 5 | 2 | 2 | 2274 | use Plack::Request; | |||
| 2 | 309501 | ||||||
| 2 | 89 | ||||||
| 6 | 2 | 2 | 2597 | use Path::Tiny qw/path/; | |||
| 2 | 61875 | ||||||
| 2 | 259 | ||||||
| 7 | 2 | 2 | 1923 | use Text::Markdown::Discount qw/markdown/; | |||
| 2 | 2419 | ||||||
| 2 | 162 | ||||||
| 8 | 2 | 2 | 2340 | use Text::Xslate qw/mark_raw/; | |||
| 2 | 26380 | ||||||
| 2 | 219 | ||||||
| 9 | 2 | 2 | 2593 | use Number::Format qw/format_number/; | |||
| 2 | 45181 | ||||||
| 2 | 303 | ||||||
| 10 | 2 | 2 | 2638 | use File::ShareDir qw/dist_dir/; | |||
| 2 | 18514 | ||||||
| 2 | 213 | ||||||
| 11 | 2 | 2 | 2063 | use Plack::App::Directory; | |||
| 2 | 44775 | ||||||
| 2 | 75 | ||||||
| 12 | 2 | 2 | 3833 | use Try::Tiny; | |||
| 2 | 5081 | ||||||
| 2 | 168 | ||||||
| 13 | 2 | 2 | 2448 | use Encode; | |||
| 2 | 41354 | ||||||
| 2 | 5867 | ||||||
| 14 | |||||||
| 15 | our $VERSION = "0.03"; | ||||||
| 16 | |||||||
| 17 | sub new { | ||||||
| 18 | 1 | 1 | 1 | 19 | my $class = shift; | ||
| 19 | 1 | 5 | my $self = bless {}, $class; | ||||
| 20 | 1 | 50 | 238 | my $name = shift or return; | |||
| 21 | 1 | 9 | my $file_path = path($name); | ||||
| 22 | 1 | 50 | 58 | return unless $file_path->is_file(); | |||
| 23 | 1 | 113 | $self->{file_path} = $file_path; | ||||
| 24 | 1 | 6 | $self->{xslate} = Text::Xslate->new( | ||||
| 25 | path => $self->local_or_share_path( [qw/share templates/] ) | ||||||
| 26 | ); | ||||||
| 27 | 1 | 354 | return $self; | ||||
| 28 | } | ||||||
| 29 | |||||||
| 30 | sub local_or_share_path { | ||||||
| 31 | 3 | 3 | 0 | 748 | my ($self, $p) = @_; | ||
| 32 | 3 | 15 | my $path = path(@$p); | ||||
| 33 | 3 | 50 | 94 | return $path if $path->exists; | |||
| 34 | try { | ||||||
| 35 | 0 | 0 | 0 | shift @$p; | |||
| 36 | 0 | 0 | $path = path(dist_dir('App-mookview'), @$p); | ||||
| 37 | 0 | 0 | }; | ||||
| 38 | 0 | 0 | return $path; | ||||
| 39 | } | ||||||
| 40 | |||||||
| 41 | sub psgi_app { | ||||||
| 42 | 0 | 0 | 0 | 0 | my $self = shift; | ||
| 43 | return sub { | ||||||
| 44 | 0 | 0 | 0 | my $req = Plack::Request->new(shift); | |||
| 45 | 0 | 0 | my $path = $req->path_info; | ||||
| 46 | 0 | 0 | 0 | return $self->return_markdown($path) if $path eq '/'; | |||
| 47 | 0 | 0 | 0 | return $self->return_css($path) if $path =~ m!^/css/.+!; | |||
| 48 | 0 | 0 | Plack::App::Directory->new->to_app->($req->env); | ||||
| 49 | 0 | 0 | }; | ||||
| 50 | } | ||||||
| 51 | |||||||
| 52 | sub return_404 { | ||||||
| 53 | 1 | 1 | 0 | 2078 | return [404, [ 'Content-Type' => 'text/plain' ], ['Not Found'] ]; | ||
| 54 | } | ||||||
| 55 | |||||||
| 56 | sub return_css { | ||||||
| 57 | 1 | 1 | 0 | 322 | my ($self, $path) = @_; | ||
| 58 | 1 | 50 | 6 | return $self->return_404 unless $path; | |||
| 59 | 1 | 11 | my ($name) = $path =~ m!/([^/]+?)$!; | ||||
| 60 | 1 | 8 | my $local_path = $self->local_or_share_path([qw/share static css/, $name]); | ||||
| 61 | 1 | 50 | 49 | return $self->return_404 unless $local_path; | |||
| 62 | 1 | 10 | my $css = $local_path->slurp(); | ||||
| 63 | 1 | 503 | return [200, [ 'Content-Type' => 'text/css', 'Content-Length' => length $css ], [ encode_utf8($css) ] ]; | ||||
| 64 | } | ||||||
| 65 | |||||||
| 66 | sub return_markdown { | ||||||
| 67 | 1 | 1 | 0 | 793 | my ($self, $path) = @_; | ||
| 68 | 1 | 8 | my $text = $self->{file_path}->slurp_utf8(); | ||||
| 69 | 1 | 2559 | my $length = format_number(length $text); | ||||
| 70 | 1 | 706 | $text = $self->filter_markdown($text); | ||||
| 71 | 1 | 2 | my $stock = ''; my $page = 1; my $content = ''; | ||||
| 1 | 3 | ||||||
| 1 | 2 | ||||||
| 72 | 1 | 2 | my $limit = 1100; | ||||
| 73 | 1 | 23 | for my $t (split /\n/, $text) { | ||||
| 74 | 38 | 61 | $stock .= $t . "\n"; | ||||
| 75 | 38 | 50 | 160 | if (length $stock > $limit) { | |||
| 76 | 0 | 0 | $content = $self->add_markdown_to_html($content, $stock, $page); | ||||
| 77 | 0 | 0 | $stock = ''; | ||||
| 78 | 0 | 0 | $page++; | ||||
| 79 | } | ||||||
| 80 | } | ||||||
| 81 | 1 | 10 | $content = $self->add_markdown_to_html($content, $stock, $page); | ||||
| 82 | 1 | 21 | my $html = $self->{xslate}->render('preview.tx', { | ||||
| 83 | content => mark_raw($content), | ||||||
| 84 | filename => $self->{file_path}->basename, | ||||||
| 85 | length => $length | ||||||
| 86 | }); | ||||||
| 87 | 1 | 1026 | $html = encode_utf8($html); | ||||
| 88 | 1 | 18 | return [200, [ | ||||
| 89 | 'Content-Type' => 'text/html; charset=utf8', | ||||||
| 90 | 'Content-Length' => length $html, | ||||||
| 91 | ], [ $html ] ]; | ||||||
| 92 | } | ||||||
| 93 | |||||||
| 94 | sub filter_markdown { | ||||||
| 95 | 2 | 2 | 0 | 340 | my ($self, $markdown) = @_; | ||
| 96 | 2 | 58 | $markdown =~ s!^```.*?\n(.+?)\n```.*?$! | ||||
| 97 | 1 | 3 | my $code = ''; | ||||
| 98 | 1 | 14 | $code .= " $_\n" for split /\n/, $1; | ||||
| 99 | 1 | 6 | $code; | ||||
| 100 | !gmse; | ||||||
| 101 | 2 | 8 | return $markdown; | ||||
| 102 | } | ||||||
| 103 | |||||||
| 104 | sub add_markdown_to_html { | ||||||
| 105 | 1 | 1 | 0 | 102 | my ($self, $html, $markdown, $page) = @_; | ||
| 106 | 1 | 9 | $html .= ' ' . markdown($markdown) . " \n"; |
||||
| 107 | 1 | 540 | $html .= " $page \n"; |
||||
| 108 | 1 | 4 | return $html; | ||||
| 109 | } | ||||||
| 110 | |||||||
| 111 | 1; | ||||||
| 112 | |||||||
| 113 | __END__ |