File Coverage

blib/lib/Text/WikiFormat/Blocks.pm
Criterion Covered Total %
statement 73 73 100.0
branch 21 24 87.5
condition 9 9 100.0
subroutine 22 22 100.0
pod n/a
total 125 128 97.6


line stmt bran cond sub pod time code
1             package Text::WikiFormat::Blocks;
2              
3 14     14   75 use strict;
  14         28  
  14         906  
4 14     14   77 use warnings;
  14         20  
  14         1986  
5              
6             sub import
7             {
8 14     14   37 my $caller = caller();
9 14     14   78 no strict 'refs';
  14         27  
  14         4923  
10 14         543 *{ $caller . '::new_block' } = sub
11             {
12 268     268   3947 my $type = shift;
13 268         493 my $class = "Text::WikiFormat::Block::$type";
14 268         267 my $ctor;
15            
16 268 100       10589 unless ($ctor = $class->can( 'new' ))
17             {
18 41         61 @{ $class . '::ISA' } = ( 'Text::WikiFormat::Block' );
  41         929  
19 41         603 $ctor = $class->can( 'new' );
20             }
21              
22 268         842 return $class->new( type => $type, @_ );
23 14         218 };
24             }
25              
26             package Text::WikiFormat::Block;
27              
28 14     14   103 use Scalar::Util qw( blessed reftype );
  14         35  
  14         13302  
29              
30             sub new
31             {
32 268     268   1105 my ($class, %args) = @_;
33              
34 268   100     1366 $args{text} = $class->arg_to_ref( delete $args{text} || '' );
35 268   100     1529 $args{args} = [ $class->arg_to_ref( delete $args{args} || [] ) ];
36              
37 268         1663 bless \%args, $class;
38             }
39              
40             sub arg_to_ref
41             {
42 536     536   717 my ($class, $value) = @_;
43 536 100 100     3485 return $value if ( reftype( $value ) || '' ) eq 'ARRAY';
44 262         769 return [ $value ];
45             }
46              
47             sub shift_args
48             {
49 36     36   54 my $self = shift;
50 36         45 my $args = shift @{ $self->{args} };
  36         70  
51 36 50       207 return wantarray ? @$args : $args;
52             }
53              
54             sub all_args
55             {
56 64     64   110 my $args = $_[0]{args};
57 64 50       325 return wantarray ? @$args : $args;
58             }
59              
60             sub text
61             {
62 196     196   335 my $text = $_[0]{text};
63 196 50       719 return wantarray ? @$text : $text;
64             }
65              
66             sub add_text
67             {
68 74     74   96 my $self = shift;
69 74         87 push @{ $self->{text} }, @_;
  74         194  
70             }
71              
72             sub formatted_text
73             {
74 116     116   156 my $self = shift;
75 195 100       907 return map
76             {
77 116         283 blessed( $_ ) ? $_ : $self->formatter( $_ )
78             } $self->text();
79             }
80              
81             sub formatter
82             {
83 171     171   408 my ($self, $line) = @_;
84 171         481 Text::WikiFormat::format_line( $line, $self->tags(), $self->opts() );
85             }
86              
87             sub add_args
88             {
89 64     64   85 my $self = shift;
90 64         68 push @{ $self->{args} }, @_;
  64         150  
91             }
92              
93             {
94 14     14   124 no strict 'refs';
  14         30  
  14         6774  
95             for my $attribute (qw( level opts tags type ))
96             {
97 1795     1795   11935 *{ $attribute } = sub { $_[0]{$attribute} };
98             }
99             }
100              
101             sub merge
102             {
103 360     360   598 my ($self, $next_block) = @_;
104              
105 360 100       954 return $next_block unless $self->type() eq $next_block->type();
106 90 100       313 return $next_block unless $self->level() == $next_block->level();
107              
108 64         213 $self->add_text( $next_block->text() );
109 64         218 $self->add_args( $next_block->all_args() );
110 64         194 return;
111             }
112              
113             sub nests
114             {
115 186     186   327 my $self = shift;
116 186         476 return exists $self->{tags}{nests}{ $self->type() };
117             }
118              
119             sub nest
120             {
121 151     151   208 my ($self, $next_block) = @_;
122              
123 151 100       254 return unless $next_block = $self->merge( $next_block );
124 146 100 100     515 return $next_block unless $self->nests() and $next_block->nests();
125 13 100       32 return $next_block unless $self->level() < $next_block->level();
126              
127             # if there's a nested block at the end, maybe it can nest too
128 12         30 my $last_item = ( $self->text() )[-1];
129 12 100       46 return $last_item->nest( $next_block ) if blessed( $last_item );
130              
131 10         23 $self->add_text( $next_block );
132 10         32 return;
133             }
134              
135             package Text::WikiFormat::Block::code;
136              
137 14     14   100 use base 'Text::WikiFormat::Block';
  14         25  
  14         11329  
138              
139 13     13   751 sub formatter { $_[1] }
140              
141             package Text::WikiFormat::Blocks;
142              
143             1;
144             __END__