File Coverage

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__