File Coverage

blib/lib/Pod/Cats/Parser/MGC.pm
Criterion Covered Total %
statement 43 43 100.0
branch 9 10 90.0
condition 1 2 50.0
subroutine 7 7 100.0
pod 2 2 100.0
total 62 64 96.8


line stmt bran cond sub pod time code
1             package Pod::Cats::Parser::MGC;
2 5     5   25 use strict;
  5         9  
  5         117  
3 5     5   23 use warnings;
  5         8  
  5         102  
4 5     5   69 use 5.010;
  5         16  
5              
6 5     5   1412 use parent qw(Parser::MGC);
  5         630  
  5         33  
7              
8             our $VERSION = '0.08';
9              
10             =head1 NAME
11              
12             Pod::Cats::Parser::MGC - Parser for C<< X >> in L
13              
14             =head1 DESCRIPTION
15              
16             Entities in Pod::Cats can be demarcated by any set of delimiters, configured in
17             L. That configuration ends up here.
18              
19             Given a string with entities so demarcated, recursively extracts the contents of
20             the entities and passes them to the Pod::Cats object for handling.
21              
22             Thus collates a sequence of (normal string, element, normal string), etc. The
23             exact contents of I depends on what your Pod::Cats subclass does with
24             the contents of the element; but the contents of I is just the
25             original text up to the first element.
26              
27             I may, of course, be another sequence of the above, because it's
28             pseudo-recursive (actually it just trundles along iteratively, maintaining a
29             nesting level and an expectation of ending delimiters).
30              
31             =head1 METHODS
32              
33             =head2 new
34              
35             Constructs a new parser object. Accepts a hash of C and C.
36              
37             C is required and must contain a Pod::Cats subclass; C defaults
38             to C<< "<" >>, like normal POD.
39              
40             See L for delimiters.
41              
42             =cut
43              
44             sub new {
45 3     3 1 35 my $self = shift->SUPER::new(@_);
46 3         257 my %o = @_;
47 3 50       17 $self->{obj} = $o{object} or die "Expected argument 'object'";
48 3   50     17 $self->{delimiters} = $o{delimiters} || "<";
49              
50 3         17 return $self;
51             }
52              
53             =head2 parse
54              
55             See L for how parse works. This just finds entities based on the
56             configured delimiters, and fires events to the object provided to L.
57              
58             =cut
59              
60             sub parse {
61 25     25 1 307 my $self = shift;
62 25         39 my $pod_cats = $self->{obj};
63              
64             # Can't grab the whole lot with one re (yet) so I will grab one and expect
65             # more.
66              
67             my $ret = $self->sequence_of(sub {
68 41     41   1975 my $odre;
69 41 100       113 if ($self->scope_level) {
70 12         103 $odre = qr/\Q$self->{delimiters}/;
71             }
72             else {
73 29         253 $odre = qr/[\Q$self->{delimiters}\E]/;
74             }
75              
76             $self->any_of(
77             sub {
78             # After we're in 1 level we've committed to an exact delimiter.
79 41         778 my $tag = $self->expect( qr/[A-Z](?=$odre)/ );
80              
81 13         410 $self->commit;
82              
83 13         79 my $odel;
84            
85 13 100       36 if ($self->scope_level) {
86 3         17 $odel = $self->expect( $self->{delimiters} );
87             }
88             else {
89 10         60 $odel = $self->expect( $odre );
90 10         433 $odel .= $self->expect( qr/\Q$odel\E*/ );
91             }
92              
93 13         486 (my $cdel = $odel) =~ tr/<({[/>)}]/;
94              
95             # The opening delimiter is the same char repeated, never
96             # different ones.
97 13         33 local $self->{delimiters} = $odel;
98              
99 13 100       36 if ($tag eq 'Z') {
100 3         14 $self->expect( $cdel );
101 3         127 $self->{level}--;
102 3         11 return;
103             }
104              
105             my $retval = $pod_cats->handle_entity(
106             $tag => @{
107 10         12 $self->scope_of( undef, \&parse, $cdel )
  10         40  
108             }
109             );
110 10         4721 return $retval;
111             },
112              
113             sub {
114 28 100       2220 if ($self->scope_level) {
115 9         103 return $self->substring_before( qr/[A-Z]\Q$self->{delimiters}/ );
116             }
117             else {
118 19         202 return $self->substring_before( qr/[A-Z]$odre/ );
119             }
120             },
121             )
122 25         163 });
  41         314  
123             }
124              
125             1;