File Coverage

blib/lib/Text/Parser/Multiline.pm
Criterion Covered Total %
statement 57 57 100.0
branch 22 22 100.0
condition 3 3 100.0
subroutine 15 15 100.0
pod n/a
total 97 97 100.0


line stmt bran cond sub pod time code
1 11     11   8549 use strict;
  11         28  
  11         406  
2 11     11   66 use warnings;
  11         21  
  11         554  
3              
4             package Text::Parser::Multiline 1.000;
5              
6             # ABSTRACT: To be used to add custom line-unwrapping routines to the Text::Parser object.
7              
8 11     11   74 use Moose::Role;
  11         24  
  11         155  
9              
10              
11             requires(
12                 qw(save_record multiline_type lines_parsed __read_file_handle),
13                 qw(join_last_line is_line_continued _set_this_line this_line)
14             );
15              
16 11     11   66506 use Text::Parser::Error;
  11         32  
  11         128  
17              
18             around save_record => \&__around_save_record;
19             around is_line_continued => \&__around_is_line_continued;
20             after __read_file_handle => \&__after__read_file_handle;
21              
22             my $orig_save_record = sub {
23                 return;
24             };
25              
26             my %save_record_proc = (
27                 join_last => \&__join_last_proc,
28                 join_next => \&__join_next_proc,
29             );
30              
31             sub __around_save_record {
32 361     361   4413     my ( $orig, $self ) = ( shift, shift );
33 361         562     $orig_save_record = $orig;
34 361 100       935     return $orig->( $self, @_ ) if not defined $self->multiline_type;
35 320         795     my $type = $self->multiline_type;
36 320         934     $save_record_proc{$type}->( $orig, $self, @_ );
37             }
38              
39             sub __around_is_line_continued {
40 322     322   3491     my ( $orig, $self, $line ) = ( shift, shift, shift );
41 322 100 100     738     return $orig->( $self, $line )
42                     if not defined $self->multiline_type
43                     or $self->multiline_type eq 'join_next';
44 202 100       577     return 0 if not $orig->( $self, $line );
45 143 100       4071     return 1 if $self->lines_parsed() > 1;
46 3         38     parser_exception("join_last continuation character on first line $line");
47             }
48              
49             sub __after__read_file_handle {
50 39     39   351     my $self = shift;
51 39 100       154     return if not defined $self->multiline_type;
52 34 100       263     return $self->__test_safe_eof()
53                     if $self->multiline_type eq 'join_next';
54 25         99     $self->_set_this_line( $self->__pop_last_line );
55 25         812     $orig_save_record->( $self, $self->this_line );
56             }
57              
58             sub __test_safe_eof {
59 9     9   21     my $self = shift;
60 9         30     my $last = $self->__pop_last_line();
61 9 100       40     return if not defined $last;
62 3         115     my $lnum = $self->lines_parsed();
63 3         37     parser_exception(
64                     "join_next continuation character in last line ($lnum \"$last\"): unexpected EoF"
65                 );
66             }
67              
68             sub __join_next_proc {
69 119     119   202     my ( $orig, $self ) = ( shift, shift );
70 119         290     $self->__append_last_stash(@_);
71 119 100       331     return if $self->is_line_continued(@_);
72 18         93     $self->__call_orig_save_rec($orig);
73             }
74              
75             sub __call_orig_save_rec {
76 50     50   89     my $self = shift;
77 50         97     my $orig = shift;
78 50         111     $self->_set_this_line( $self->__pop_last_line );
79 50         1516     $orig->( $self, $self->this_line );
80             }
81              
82             sub __join_last_proc {
83 201     201   444     my ( $orig, $self ) = ( shift, shift );
84 201 100       487     return $self->__append_last_stash(@_) if $self->__more_may_join_last(@_);
85 32         158     $self->__call_orig_save_rec($orig);
86 32         578     $self->__append_last_stash(@_);
87             }
88              
89             sub __more_may_join_last {
90 201     201   327     my $self = shift;
91 201 100       514     $self->is_line_continued(@_) or not defined $self->_joined_line;
92             }
93              
94             has _joined_line => (
95                 is => 'rw',
96                 isa => 'Str|Undef',
97                 default => undef,
98                 clearer => '_delete_joined_line',
99             );
100              
101             sub __append_last_stash {
102 316     316   633     my ( $self, $line ) = @_;
103 316 100       9195     return $self->_joined_line($line) if not defined $self->_joined_line;
104 237         577     my $joined_line = $self->join_last_line( $self->__pop_last_line, $line );
105 236         8553     $self->_joined_line($joined_line);
106             }
107              
108             sub __pop_last_line {
109 321     321   570     my $self = shift;
110 321         9311     my $last_line = $self->_joined_line();
111 321         10968     $self->_delete_joined_line;
112 321         1758     return $last_line;
113             }
114              
115 11     11   15347 no Moose::Role;
  11         37  
  11         86  
116              
117              
118             1;
119              
120             __END__
121            
122             =pod
123            
124             =encoding UTF-8
125            
126             =head1 NAME
127            
128             Text::Parser::Multiline - To be used to add custom line-unwrapping routines to the Text::Parser object.
129            
130             =head1 VERSION
131            
132             version 1.000
133            
134             =head1 SYNOPSIS
135            
136             Input text file:
137            
138             This is a line that is wrapped with a trailing percent sign %
139             like the last one. This may seem unusual, but hey, it's an %
140             example.
141            
142             The code required to unwrap this:
143            
144             use Text::Parser;
145            
146             my $parser = Text::Parser->new(multiline_type => 'join_next');
147             $parser->custom_line_unwrap_routines(
148             is_wrapped => sub { # A method to detect if this line is wrapped
149             my ($self, $this_line) = @_;
150             $this_line =~ /\%\s*$/;
151             },
152             unwrap_routine => sub { # Method to unwrap line, gets called only on line after % sign
153             my ($self, $last_line, $this_line) = @_;
154             chomp $last_line;
155             $last_line =~ s/\%\s*$//g;
156             "$last_line $this_line";
157             },
158             );
159            
160             When C<$parser> gets to C<read> the input text, those three lines get unwrapped and processed by the rules as if it were a single line.
161            
162             =head1 DESCRIPTION
163            
164             You should not C<use> this module directly in your code. The functionality of this L<role|Moose::Role> is accessed through L<Text::Parser>. The purpose of this L<role|Moose::Role> is to write custom routines to unwrap line-wrapped text input, using an object of L<Text::Parser>.
165            
166             =head1 SEE ALSO
167            
168             =over 4
169            
170             =item *
171            
172             L<Text::Parser>
173            
174             =back
175            
176             =head1 BUGS
177            
178             Please report any bugs or feature requests on the bugtracker website
179             L<http://github.com/balajirama/Text-Parser/issues>
180            
181             When submitting a bug or request, please include a test-file or a
182             patch to an existing test-file that illustrates the bug or desired
183             feature.
184            
185             =head1 AUTHOR
186            
187             Balaji Ramasubramanian <balajiram@cpan.org>
188            
189             =head1 COPYRIGHT AND LICENSE
190            
191             This software is copyright (c) 2018-2019 by Balaji Ramasubramanian.
192            
193             This is free software; you can redistribute it and/or modify it under
194             the same terms as the Perl 5 programming language system itself.
195            
196             =cut
197