File Coverage

blib/lib/Text/MediawikiFormat/Blocks.pm
Criterion Covered Total %
statement 66 66 100.0
branch 19 22 86.3
condition 8 9 88.8
subroutine 20 20 100.0
pod n/a
total 113 117 96.5


line stmt bran cond sub pod time code
1             package Text::MediawikiFormat::Blocks;
2              
3 14     14   67 use strict;
  14         22  
  14         621  
4 14     14   78 use warnings::register;
  14         17  
  14         2199  
5              
6             our $VERSION = '1.02';
7              
8             sub import
9             {
10 14     14   46 my $caller = caller();
11 14     14   76 no strict 'refs';
  14         28  
  14         1807  
12 14         357 *{ $caller . '::new_block' } = sub
13             {
14 315     315   2949 my $type = shift;
15 315         395 my $class = "Text::MediawikiFormat::Block::$type";
16            
17 315 100       1888 *{ $class . '::ISA' } = [ 'Text::MediawikiFormat::Block' ]
  49         628  
18             unless $class->can( 'new' );
19              
20 315         800 return $class->new( type => $type, @_ );
21 14         68 };
22             }
23              
24             package Text::MediawikiFormat::Block;
25              
26 14     14   88 use Scalar::Util qw( blessed reftype );
  14         26  
  14         5970  
27              
28             sub new
29             {
30 315     315   953 my ($class, %args) = @_;
31              
32 315   100     1150 $args{text} = $class->arg_to_ref (delete $args{text} || '');
33 315   100     914 $args{args} = [$class->arg_to_ref (delete $args{args} || [])];
34              
35 315         1148 bless \%args, $class;
36             }
37              
38             sub arg_to_ref
39             {
40 630     630   570 my ($class, $value) = @_;
41 630 100 100     2475 return $value if ( reftype( $value ) || '' ) eq 'ARRAY';
42 309         706 return [ $value ];
43             }
44              
45             sub shift_args
46             {
47 32     32   29 my $self = shift;
48 32         27 my $args = shift @{ $self->{args} };
  32         43  
49 32 50       109 return wantarray ? @$args : $args;
50             }
51              
52             sub all_args
53             {
54 83     83   100 my $args = $_[0]{args};
55 83 50       250 return wantarray ? @$args : $args;
56             }
57              
58             sub text
59             {
60 262     262   446 my $text = $_[0]{text};
61 262 50       651 return wantarray ? @$text : $text;
62             }
63              
64             sub add_text
65             {
66 100     100   96 my $self = shift;
67 100         157 push @{ $self->{text} }, @_;
  100         181  
68             }
69              
70             sub formatted_text
71             {
72 130     130   141 my $self = shift;
73 234 100       708 return map
74             {
75 130         231 blessed( $_ ) ? $_ : $self->formatter( $_ )
76             } $self->text();
77             }
78              
79             sub formatter
80             {
81 216     216   232 my ($self, $line) = @_;
82 216         370 Text::MediawikiFormat::format_line ($line, $self->tags(),
83             $self->opts());
84             }
85              
86             sub add_args
87             {
88 83     83   75 my $self = shift;
89 83         74 push @{ $self->{args} }, @_;
  83         119  
90             }
91              
92             {
93 14     14   82 no strict 'refs';
  14         18  
  14         4259  
94             for my $attribute (qw( level opts tags type ))
95             {
96 2073     2073   7411 *{ $attribute } = sub { $_[0]{$attribute} };
97             }
98             }
99              
100             sub merge
101             {
102 274     274   210 my ($self, $next_block) = @_;
103              
104 274 100       353 return $next_block unless $self->type() eq $next_block->type();
105 112 100       256 return $next_block unless $self->level() == $next_block->level();
106              
107 83         275 $self->add_text( $next_block->text() );
108 83         194 $self->add_args( $next_block->all_args() );
109 83         264 return;
110             }
111              
112             sub nests
113             {
114 191     191   255 my ($self, $maynest) = @_;
115 191         175 my $tags = $self->{tags};
116              
117 191   66     340 return exists $tags->{nests}{$self->type()}
118             && exists $tags->{nests}{$maynest->type()}
119             && $self->level() < $maynest->level()
120             # tags nest anywhere, regardless of level and parent
121             || exists $tags->{nests_anywhere}{$maynest->type()};
122             }
123              
124             sub nest
125             {
126 274     274   249 my ($self, $next_block) = @_;
127              
128 274 100       436 return unless $next_block = $self->merge ($next_block);
129 191 100       387 return $next_block unless $self->nests ($next_block);
130              
131             # if there's a nested block at the end, maybe it can nest too
132 40         65 my $last_item = ( $self->text() )[-1];
133 40 100       106 return $last_item->nest( $next_block ) if blessed( $last_item );
134              
135 17         28 $self->add_text( $next_block );
136 17         28 return;
137             }
138              
139             1;
140             __END__