File Coverage

blib/lib/Text/Markdown/Slidy.pm
Criterion Covered Total %
statement 71 75 94.6
branch 20 26 76.9
condition 12 17 70.5
subroutine 13 13 100.0
pod 3 5 60.0
total 119 136 87.5


line stmt bran cond sub pod time code
1             package Text::Markdown::Slidy;
2 2     2   63294 use 5.008001;
  2         18  
3 2     2   10 use strict;
  2         4  
  2         37  
4 2     2   8 use warnings;
  2         3  
  2         45  
5              
6 2     2   878 use YAML::PP ();
  2         118471  
  2         74  
7              
8             our $VERSION = "0.04";
9 2     2   801 use parent 'Exporter';
  2         534  
  2         10  
10              
11             our @EXPORT = qw/markdown split_markdown/;
12              
13             sub new {
14 8     8 1 19 my $class = shift;
15 8 50       39 my %args = @_ == 1 ? %{$_[0]} : @_;
  0         0  
16 8         28 bless {%args}, $class;
17             }
18              
19             sub markdown {
20 16     16 1 45629 my ($self, $text) = @_;
21              
22             # Detect functional mode, and create an instance for this run
23 16 100       54 unless (ref $self) {
24 8 50       38 if ( $self ne __PACKAGE__ ) {
25 8         42 my $ob = __PACKAGE__->new();
26             # $self is text, $text is options
27 8         32 return $ob->markdown($self, $text);
28             }
29             else {
30 0         0 croak('Calling ' . $self . '->markdown (as a class method) is not supported.');
31             }
32             }
33 8         29 my ($body, $meta) = _separate_frontmater($text);
34 8         45 my @slides = $self->_sections($body);
35 8         36 my $html = join "\n", @slides;
36 8 100       116 return wantarray ? ($html, $meta) : $html;
37             }
38              
39             sub template {
40 26     26 0 52 my $self = shift;
41              
42 26   100     272 $self->{template} ||= qq[
\n%s
\n];
43             }
44              
45             sub _separate_frontmater {
46 8     8   18 my $text = shift;
47              
48 8         16 my $delim = "---\n";
49 8         14 my $strict_frontmatter;
50 8         111 my ($raw_header, $body, $body2) = split /^$delim/ms, $text, 3;
51 8 100       40 if ($raw_header eq '') {
    50          
52 4         11 my $strict_frontmatter = 1;
53 4         13 ($raw_header, $body) = ($body, $body2);
54             } elsif ($body2) {
55 4         15 $body = $body . $delim . $body2;
56             }
57 8         17 my $meta;
58 8 50       21 if (!$body) {
59 0         0 $body = $raw_header;
60             } else {
61 8         16 eval {
62 8         43 $meta = YAML::PP::Load($raw_header);
63             };
64 8 100 33     30095 if ($@ || !$meta || ref $meta ne 'HASH') {
      66        
65 2 50       9 if ($strict_frontmatter) {
66 0         0 die sprintf("invalid frontmatter\n%s", $raw_header);
67             }
68 2         5 undef $meta;
69 2         10 $body = $raw_header . $delim . $body;
70             }
71             }
72 8         49 return ($body, $meta);
73             }
74              
75             sub md {
76 26     26 0 41 my $self = shift;
77              
78 26   66     106 $self->{md} ||= do {
79 8         998 require Text::Markdown;
80 8         33354 Text::Markdown->new;
81             };
82             }
83              
84             sub _process {
85 26     26   66 my ($self, $slide_text) = @_;
86              
87 26         81 my $html = $self->md->markdown($slide_text);
88 26         32821 sprintf $self->template, $html;
89             }
90              
91             sub _sections {
92 8     8   29 my ($self, $text) = @_;
93              
94 8         34 map {$self->_process($_)} split_markdown($text);
  26         73  
95             }
96              
97             sub split_markdown {
98 8     8 1 20 my $text = shift;
99 8         47 $text =~ s/^\A\s+//ms;
100 8         79 $text =~ s/\s+\z//ms;
101              
102 8         24 my @slides;
103             my @slide_lines;
104 8         114 for my $line (split /\r?\n/, $text) {
105 84 100 66     284 if ( my ($delim) = $line =~ /^([- ]+?|=+)\s*$/ and @slide_lines) {
106 20 100 100     97 if ($delim =~ / / || !$slide_lines[$#slide_lines]) {
107             #
108             # `- - -`
109             # "\n\n----\n"
110 4         13 push @slides, join("\n", (@slide_lines, $line));
111 4         8 @slide_lines = ();
112 4         9 next;
113             }
114             # h1 or h2
115 16         27 my $prev = pop @slide_lines;
116 16 100       66 push @slides, join("\n", @slide_lines) if @slide_lines;
117 16         34 @slide_lines = ($prev); # $prev is title;
118             }
119 80         132 push @slide_lines, $line;
120             }
121 8 50       37 push @slides, join("\n", @slide_lines) if @slide_lines;
122              
123 8         35 @slides;
124             }
125              
126             1;
127             __END__