File Coverage

blib/lib/Text/Markdown/Slidy.pm
Criterion Covered Total %
statement 69 74 93.2
branch 20 26 76.9
condition 9 11 81.8
subroutine 13 13 100.0
pod 3 5 60.0
total 114 129 88.3


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