File Coverage

blib/lib/Text/Flow/Wrap.pm
Criterion Covered Total %
statement 31 31 100.0
branch 3 4 75.0
condition n/a
subroutine 7 7 100.0
pod 5 5 100.0
total 46 47 97.8


line stmt bran cond sub pod time code
1              
2             package Text::Flow::Wrap;
3 4     4   82357 use Moose;
  4         1441552  
  4         35  
4              
5             our $VERSION = '0.01';
6             our $AUTHORITY = 'cpan:STEVAN';
7              
8             has 'check_width' => (
9             is => 'rw',
10             isa => 'CodeRef',
11             required => 1,
12             );
13              
14             has 'word_boundry' => (is => 'rw', isa => 'Str', default => " ");
15             has 'paragraph_boundry' => (is => 'rw', isa => 'Str', default => "\n");
16              
17             has 'word_break' => (is => 'rw', isa => 'Str', default => " ");
18             has 'line_break' => (is => 'rw', isa => 'Str', default => "\n");
19             has 'paragraph_break' => (is => 'rw', isa => 'Str', default => "\n\n");
20              
21             sub wrap {
22 6     6 1 8947 my ($self, $text) = @_;
23 6         25 $self->reassemble_paragraphs(
24             $self->disassemble_paragraphs($text)
25             );
26             }
27              
28             sub reassemble_paragraphs {
29 15     15 1 33 my ($self, $paragraphs) = @_;
30 25         132 join $self->paragraph_break => map {
31 15         601 $self->reassemble_paragraph($_)
32             } @$paragraphs;
33             }
34              
35             sub reassemble_paragraph {
36 25     25 1 47 my ($self, $paragraph) = @_;
37 25         1136 join $self->line_break => @$paragraph;
38             }
39              
40             sub disassemble_paragraphs {
41 10     10 1 24 my ($self, $text) = @_;
42            
43 10         568 my @paragraphs = split $self->paragraph_boundry => $text;
44            
45 10         62 my @output;
46 10         27 foreach my $paragraph (@paragraphs) {
47 20         70 push @output => $self->disassemble_paragraph($paragraph);
48             }
49            
50 10         77 return \@output;
51             }
52              
53             sub disassemble_paragraph {
54 20     20 1 44 my ($self, $text) = @_;
55            
56 20         52 my @output = ('');
57            
58 20         745 my @words = split $self->word_boundry => $text;
59            
60 20         886 my $work_break = $self->word_break;
61            
62 20         49 foreach my $word (@words) {
63 1250         2844 my $padded_word = ($word . $work_break);
64 1250         10009 my $canidate = ($output[-1] . $padded_word);
65 1250 100       66609 if ($self->check_width->($canidate)) {
66 1053         6373 $output[-1] = $canidate;
67             }
68             else {
69 197         1618 push @output => ($padded_word);
70             }
71             }
72            
73             # NOTE:
74             # remove that final word break character
75 20 50       114 chop $output[-1] if substr($output[-1], -1, 1) eq $work_break;
76            
77 20         309 return \@output;
78             }
79              
80 4     4   50017 no Moose;
  4         10  
  4         26  
81              
82             1;
83              
84             __END__
85              
86             =pod
87              
88             =head1 NAME
89              
90             Text::Flow::Wrap - Flexible word wrapping for not just ASCII output.
91              
92             =head1 SYNOPSIS
93              
94             use Text::Flow::Wrap;
95            
96             # for regular ASCII usage ...
97             my $wrapper = Text::Flow::Wrap->new(
98             check_width => sub { length($_[0]) < 70 },
99             );
100            
101             # for non-ASCII usage ...
102             my $wrapper = Text::Flow::Wrap->new(
103             check_width => sub { $pdf->get_text_width($_[0]) < 500 },
104             );
105            
106             my $text = $wrapper->wrap($text);
107              
108             =head1 DESCRIPTION
109              
110             The main purpose of this module is to provide text wrapping features
111             without being tied down to ASCII based output and fixed-width fonts.
112              
113             My needs were for sophisticated test control in PDF and GIF output
114             formats in particular.
115              
116             =head1 METHODS
117              
118             =over 4
119              
120             =item B<new (%params)>
121              
122             This constructs a new Text::Flow::Wrap module whose C<%params> set the
123             values of the attributes listed below.
124              
125             =item B<wrap ($text)>
126              
127             This method will accept a bunch of text, it will then return a new string
128             which is wrapped to the expected width.
129              
130             =back
131              
132             =head2 Attribute Accessors
133              
134             =over 4
135              
136             =item B<check_width (\&code)>
137              
138             This attribute is required, and must be a CODE reference. This will be
139             used to determine if the width of the text is appropriate. It will get
140             as an argument, a string which is should check the width of. It should
141             return a Boolean value, true if the string is not exceeded the max width
142             and false if it has.
143              
144             =item B<line_break ($str)>
145              
146             This is the line break character used when assembling and disassembling
147             the text, it defaults to the newline character C<\n>.
148              
149             =item B<paragraph_boundry ($str)>
150              
151             This is the paragraph boundry marker used when disassembling the text,
152             it defaults to the string C<\n>.
153              
154             =item B<paragraph_break ($str)>
155              
156             This is the paragraph breaker used when re-assembling the text, it defaults
157             to the string C<\n\n>.
158              
159             =item B<word_boundry ($str)>
160              
161             This is the word boundry marker used when disassembling the text,
162             it defaults to a single space character.
163              
164             =item B<word_break ($str)>
165              
166             This is the paragraph breaker used when re-assembling the text, it defaults
167             to a single space character.
168              
169             =back
170              
171             =head2 Paragraph Disassembling
172              
173             These methods deal with breaking up the paragraphs into its parts, which
174             can then be processed through the re-assembling methods.
175              
176             These methods are mostly used internally, but more sophisticated tools
177             might need to access them as well (see Text::Flow).
178              
179             =over 4
180              
181             =item B<disassemble_paragraph>
182              
183             =item B<disassemble_paragraphs>
184              
185             =back
186              
187             =head2 Paragraph Reassembling
188              
189             These methods deal with putting the paragraph parts back together after the
190             disassembling methods have done thier work.
191              
192             These methods are mostly used internally, but more sophisticated tools
193             might need to access them as well (see Text::Flow)
194              
195             =over 4
196              
197             =item B<reassemble_paragraph>
198              
199             =item B<reassemble_paragraphs>
200              
201             =back
202              
203             =head2 Introspection
204              
205             =over 4
206              
207             =item B<meta>
208              
209             Returns the Moose meta object associated with this class.
210              
211             =back
212              
213             =head1 BUGS
214              
215             All complex software has bugs lurking in it, and this module is no
216             exception. If you find a bug please either email me, or add the bug
217             to cpan-RT.
218              
219             =head1 AUTHOR
220              
221             Stevan Little E<lt>stevan@iinteractive.comE<gt>
222              
223             =head1 COPYRIGHT AND LICENSE
224              
225             Copyright 2007 by Infinity Interactive, Inc.
226              
227             L<http://www.iinteractive.com>
228              
229             This library is free software; you can redistribute it and/or modify
230             it under the same terms as Perl itself.
231              
232             =cut
233              
234