File Coverage

blib/lib/Text/Indent.pm
Criterion Covered Total %
statement 39 39 100.0
branch 8 8 100.0
condition 8 13 61.5
subroutine 10 10 100.0
pod 4 6 66.6
total 69 76 90.7


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             Text::Indent - simple indentation of text shared among modules
4              
5             =head1 SYNOPSIS
6              
7             In your main program:
8              
9             use Text::Indent;
10             my $indent = Text::Indent->new;
11             $indent->spaces(2);
12              
13             In a module to produce indented output:
14              
15             use Text::Indent;
16             my $indent = Text::Indent->instance;
17             $indent->increase;
18             print $indent->indent("this will be indented two spaces");
19             $indent->increase(2);
20             print $indent->indent("this will be indented six spaces");
21             $indent->decrease(3);
22              
23             =head1 DESCRIPTION
24              
25             Text::Indent is designed for use in programs which need to produce output
26             with multiple levels of indent when the source of the output comes from
27             different modules that know nothing about each other.
28              
29             For example take module A, whose output includes the indented output of
30             module B. Module B can also produce output directly, so it falls to module B
31             to know whether it should indent it's output or not depending on it's
32             calling context.
33              
34             Text::Indent allows programs and modules to cooperate to choose an
35             appropriate indent level that is shared within the program context. In the
36             above example, module A would increase the indent level prior to calling the
37             output routines of module B. Module B would simply use the Text::Indent
38             instance confident that if it were being called directly no indent would be
39             applied but if module A was calling it then it's output would be indented
40             one level.
41              
42             =cut
43              
44             package Text::Indent;
45              
46 9     9   11717 use strict;
  9         21  
  9         267  
47 9     9   44 use warnings;
  9         19  
  9         386  
48              
49             our $VERSION = '0.033';
50              
51 9     9   5025 use Params::Validate qw|:all|;
  9         85980  
  9         2150  
52              
53             use Class::MethodMaker(
54 9         75 new_with_init => 'new',
55             static_get_set => '_instance',
56             get_set => [ qw|
57             spaces
58             spacechar
59             |],
60             counter => 'level',
61             boolean => 'add_newline',
62 9     9   5384 );
  9         157390  
63              
64             =head1 CONSTRUCTOR
65              
66             The constructor for Text::Indent should only be called once by the main
67             program using modules that produce indented text. Modules which wish
68             to produce indented text should use the instance accessor described below.
69              
70             To construct a new Text::Indent object, call the B method, passing
71             one or more of the following parameters as a hash:
72              
73             =over 4
74              
75             =item * B
76              
77             the number of spaces to used for each level of indentation. Defaults to 2.
78              
79             =item * B
80              
81             the character to be used for indentation. Defaults to a space (ASCII 32)
82              
83             =item * B
84              
85             The initial indentation level to set. Defaults to 0.
86              
87             =item * B
88              
89             Whether the B method should automatically add a newline to the input
90             arguments. Defaults to TRUE.
91              
92             =item * B
93              
94             Whether the newly constructed Text::Indent object should become the new
95             singleton instance returned by the B accessor. Defaults to TRUE.
96              
97             =back
98              
99             =cut
100              
101             sub init
102             {
103            
104 9     9 0 8818 my $self = shift;
105 9   33     42 my $class = ref $self || $self;
106            
107             # validate args
108 9         545 my %args = validate(@_,{
109             Spaces => { type => SCALAR,
110             default => 2 },
111             SpaceChar => { type => SCALAR,
112             default => ' ' },
113             Level => { type => SCALAR,
114             default => 0 },
115             AddNewLine => { type => BOOLEAN,
116             default => 1 },
117             Instance => { type => BOOLEAN,
118             default => 1 }
119             });
120            
121             # populate object
122 8         264 $self->spaces( $args{Spaces} );
123 8         303 $self->spacechar( $args{SpaceChar} );
124 8         276 $self->level( $args{Level} );
125 8         771 $self->add_newline( $args{AddNewLine} );
126            
127             # set as the current instance unless told not to
128 8 100 66     174 unless( exists $args{Instance} && ! $args{Instance} ) {
129 7         190 $class->_instance( $self );
130             }
131            
132 8         252 return $self;
133            
134             }
135              
136             =head1 INSTANCE ACCESSOR
137              
138             The instance accessor is designed to be used by modules wishing to produce
139             indented output. If the instance already exists (as will be the case if the
140             main program using the module constructed a Text::Indent object) then both
141             the program and the module will use the same indentation scheme.
142              
143             If the instance does not exist yet, the instance accessor dispatches it's
144             arguments to the constructor. As such, any of the parameters that the
145             constructor takes may also be passed to the instance accessor. Be mindful
146             that if the instance does exist, any parameters passed to the instance
147             accessor are ignored.
148              
149             =cut
150              
151             sub instance
152             {
153            
154 3     3 0 5466 my $self = shift;
155 3   33     15 my $class = ref $self || $self;
156            
157             # return the class instance if we have one, otherwise
158             # dispatch to the constructor
159 3 100       88 return $class->_instance ? $class->_instance
160             : $class->new(@_);
161            
162             }
163              
164             =head1 METHODS
165              
166             =head2 increase($how_many)
167              
168             This method increases the level of indentation by $how_many levels. If
169             not provided, $how_many defaults to 1.
170              
171             =cut
172              
173             sub increase
174             {
175            
176 3     3 1 1252 my $self = shift;
177 3   100     15 my $how_many = shift || 1;
178            
179 3         93 $self->level_incr($how_many);
180            
181 3         348 return $self;
182            
183             }
184              
185             =head2 decrease
186              
187             This method decreases the level of indentation by $how_many levels. If
188             not provided, $how_many defaults to 1.
189              
190             =cut
191              
192             sub decrease
193             {
194            
195 3     3 1 1272 my $self = shift;
196 3   100     15 my $how_many = shift || 1;
197            
198 3         94 $self->level_incr( - $how_many );
199            
200 3         348 return $self;
201            
202             }
203              
204             =head2 reset
205              
206             This method resets the level of indentation to 0. It is functionally
207             equivalent to $indent->level(0).
208              
209             =cut
210              
211             sub reset
212             {
213            
214 3     3 1 1327 my $self = shift;
215            
216 3         95 $self->level_reset;
217            
218 3         18 return $self;
219            
220             }
221              
222             =head2 indent(@what)
223              
224             This is the primary workhorse method of Text::Indent. It takes a list of
225             arguments to be indented and returns the indented string.
226              
227             The string returned is composed of the following list:
228              
229             =over 4
230              
231             =item * the 'space' character repeated x times, where x is the number of
232             spaces multiplied by the indent level.
233              
234             =item * the stringification of arguments passed to the method (note that
235             this means that list arguments will have spaces inserted in between them).
236              
237             =item * a newline if the 'add_newline' attribute of the Text::Indent object
238             is set.
239              
240             =back
241              
242             If the indent level drops is a negative value, no indent is applied.
243              
244             =cut
245              
246             sub indent
247             {
248            
249 7     7 1 20 my $self = shift;
250 7         15 my @args = @_;
251            
252 7 100       172 return ($self->spacechar x ($self->spaces * ($self->level < 0 ? 0 : $self->level))) .
    100          
253             "@args" . ($self->add_newline ? "\n" : '');
254            
255             }
256              
257             # keep require happy
258             1;
259              
260              
261             __END__