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__ |