File Coverage

blib/lib/Hub/Console/Output.pm
Criterion Covered Total %
statement 6 121 4.9
branch 0 64 0.0
condition 0 12 0.0
subroutine 2 6 33.3
pod 4 4 100.0
total 12 207 5.8


line stmt bran cond sub pod time code
1             package Hub::Console::Output;
2 1     1   5 use strict;
  1         3  
  1         40  
3 1     1   6 use Hub qw/:lib/;
  1         2  
  1         5  
4             our $VERSION = '4.00043';
5             our @EXPORT = qw//;
6             our @EXPORT_OK = qw/
7             fw
8             ps
9             fcols
10             indenttext
11             /;
12              
13             # ------------------------------------------------------------------------------
14             # fw - fixed-width (default padding is a space)
15             #
16             # Warning, many calls to this method is a performance hit!
17             #
18             # usage examples:
19             #
20             # Hub::fw( 5, "Hello World" ) "Hello"
21             # Hub::fw( 5, "Hello World", '-clip=0' ) "Hello world"
22             # Hub::fw( 5, "Hi" ) "Hi "
23             # Hub::fw( 5, "Hi", '-align=r' ) " Hi"
24             # Hub::fw( 5, "Hi", '-align=l' ) "Hi "
25             # Hub::fw( 5, "Hi", '-align=c' ) " Hi "
26             # Hub::fw( 5, "Hi", '-repeat' ) "HHHHH"
27             # Hub::fw( 5, "Hi", '-pad=x' ) "Hixxx"
28             # Hub::fw( 5, "Hi", '-pad=x', '-align=r' ) "xxxHi"
29             #
30             # Depricated:
31             #
32             # Hub::fw( 5, "Hi", "right" ) " Hi"
33             # Hub::fw( 5, "Hi", "repeat" ) "HHHHH"
34             # Hub::fw( 5, "Hi", "padding:x" ) "Hixxx"
35             # Hub::fw( 5, "Hi", "padding:x", "right" ) "xxxHi"
36             #
37             # ------------------------------------------------------------------------------
38             sub fw {
39              
40 0     0 1   my $width = shift;
41 0   0       my $the_string = shift || '';
42 0           my $opts = Hub::opts( \@_ );
43 0           my $return = '';
44              
45 0           my $repeat = Hub::bestof( $$opts{'repeat'}, 0 );
46 0           my $justify = Hub::bestof( $$opts{'align'}, 'l' );
47 0           my $padding = Hub::bestof( $$opts{'pad'}, ' ' );
48 0           my $clip = Hub::bestof( $$opts{'clip'}, 1 );
49              
50 0           while( my $option = shift ) {
51 0 0         if( $option =~ s/padding://i ) {
    0          
    0          
52 0           $padding = $option;
53             } elsif( $option =~ /repeat/i ) {
54 0           $repeat = 1;
55             } elsif( $option =~ /right|center/ ) {
56 0           $justify = substr $option, 0, 1;
57             }#if
58             }#while
59 0           my $strlen = length( $the_string );
60 0           my $adjust = $width - $strlen;
61 0 0 0       if( $clip && $adjust < 0 ) {
62 0           $return = substr( $the_string, 0, $width );
63             } else {
64 0 0         if( $repeat ) {
65 0           $padding = substr( $the_string, 0, 1 );
66 0           $adjust = $width;
67 0           $the_string = "";
68             }
69 0           $padding x= $adjust;
70 0 0         if( $justify =~ /r/ ) {
    0          
    0          
71 0           $return = $padding . $the_string;
72             } elsif( $justify =~ /c/ ) {
73 0           my $mid = length($padding) / 2;
74 0           my $lpad = substr $padding, 0, $mid;
75 0           my $rpad = substr $padding, $mid;
76 0           $return = $lpad . $the_string . $rpad;
77             } elsif( $justify =~ /l/ ) {
78 0           $return = $the_string . $padding;
79             }
80             }
81              
82 0           return $return;
83              
84             }#fw
85              
86             #-------------------------------------------------------------------------------
87             # ps
88             #
89             # Aka: Proportional Space
90             #
91             # Split the given string up into multiple lines which will not exceed the
92             # specified character width.
93             #
94             # Default padding is a space.
95             #-------------------------------------------------------------------------------
96             #|test(match) ps( 10, "this is really short but splits on ten chars" );
97             #|
98             #=this is re
99             #=ally short
100             #= but split
101             #=s on ten c
102             #=hars
103             #|
104             #|test(match) ps( 10, "this is really short but splits on ten chars", 3 );
105             #|
106             #=this is re
107             #= ally short
108             #= but split
109             #= s on ten c
110             #= hars
111             #|
112             #|test(match) ps( 10, "this is really short but splits on ten chars", -keepwords );
113             #|
114             #=this is
115             #=really
116             #=short but
117             #=splits on
118             #=ten
119             ##-------------------------------------------------------------------------------
120              
121             sub ps {
122 0     0 1   my $width = shift;
123 0   0       my $str = shift || return;
124 0           my $opts = {
125             'indent' => 0,
126             'padding' => ' ',
127             'keepwords' => 0,
128             };
129 0           Hub::opts(\@_, $opts, '-prefix=--', '-assign=:');
130 0           Hub::opts(\@_, $opts);
131 0 0         @_ and $$opts{'indent'} = shift; # backward compatibility
132 0           $$opts{'padding'} x= $$opts{'indent'};
133 0           my $return_string = '';
134 0 0         if( $$opts{'keepwords'} ) {
135 0           my ($p, $beg, $end) = (0, 0, 0);
136 0           while ($p > -1) {
137 0           $p = Hub::indexmatch($str, '\s', $end);
138 0 0         if (($p - $beg) > $width) {
139 0           $return_string .= "\n";
140 0           $beg = $end;
141             }
142 0           $return_string .= substr $str, $end, (($p - $end) +1);
143 0           $end = $p + 1;
144             }
145             } else {
146 0           $return_string .= substr( $str, 0, $width );
147 0           $return_string =~ s/\n/\n$$opts{'padding'}/g;
148 0           my $last_pos = $width;
149 0           while( my $more_stuff = substr( $str, $last_pos, $width ) ) {
150 0 0         if( $more_stuff =~ s/\n/\n$$opts{'padding'}/g ) {
151 0           $return_string .= $more_stuff;
152             } else {
153 0           $return_string .= "\n$$opts{'padding'}$more_stuff";
154             }#if
155 0           $last_pos += $width;
156 0 0         last if $last_pos > length($str);
157             }#while
158             }#if
159 0           return $return_string;
160             }#ps
161              
162             # ------------------------------------------------------------------------------
163             # fcols STRING, COLS, [OPTIONS]
164             #
165             # Divide text into fixed-width columns.
166             #
167             # Where OPTIONS can be:
168             #
169             # --split:REGEX # Split on regex REGEX (default '\s')
170             # --flow:ttb|ltr # Top-to-bottom or Left-to-right (default 'ttb')
171             # --pad:NUM # Spacing between columns (default 1)
172             # --padwith:STR # Pad with STR (multiplied by --pad)
173             # --width:NUM # Force column width (--pad becomes irrelevant)
174             # --justify:left|center|right # Justify within column
175             #
176             # Examples:
177             #
178             # 1) print fcols( "A B C D E F G", 4, "-flow=ttb" ), "\n";
179             #
180             # A C E G
181             # B D F
182             #
183             # 2) print fcols( "a b c d e f g", 4, "-flow=ltr" ), "\n";
184             #
185             # a b c d
186             # e f g
187             #
188             # ------------------------------------------------------------------------------
189              
190             sub fcols {
191              
192 0     0 1   my $str = shift;
193 0   0       my $cols = shift || 1;
194 0           my $buf = '';
195              
196 0           my ($splitter,$padding,$colwidth,$padwith,$justify,$flow)
197             = ('\s',1,0,' ','left','ttb');
198              
199 0           while( my $opt = shift ) {
200              
201 0 0         if( $opt =~ /-([a-z]+)=?(.*)$/ ) {
202              
203 0 0         $1 eq 'split' and $splitter = $2;
204 0 0         $1 eq 'pad' and $padding = $2;
205 0 0         $1 eq 'width' and $colwidth = $2;
206 0 0         $1 eq 'padwith' and $padwith = $2;
207 0 0         $1 eq 'justify' and $justify = $2;
208 0 0         $1 eq 'flow' and $flow = $2;
209              
210             }#if
211              
212             }#foreach
213              
214 0           my @items = split /$splitter/, $str;
215              
216 0 0         if( @items ) {
217              
218 0           my @grid = ();
219              
220 0           my @width = ();
221              
222 0           my ($d,$r) = Hub::intdiv( $#items, $cols );
223              
224 0 0         my $rowcount = $d ? ($d + 1) : 1;
225              
226 0           my ($colnum,$rownum,$maxlen) = 0;
227              
228 0 0         if( $flow eq 'ttb' ) {
    0          
229              
230 0           foreach my $idx ( 0 .. $#items ) {
231              
232 0 0 0       if( $idx && (($idx % $rowcount) == 0) ) {
233              
234 0           $colnum++;
235              
236 0           $rownum = $maxlen = 0;
237              
238             }#if
239              
240 0           $maxlen = Hub::max($maxlen,length($items[$idx]));
241              
242 0           $width[$colnum] = $maxlen;
243              
244 0           push @{$grid[$rownum++]}, $idx;
  0            
245              
246             }#foreach
247              
248             } elsif( $flow eq 'ltr' ) {
249              
250 0           my $lastbreak = 0;
251              
252 0           foreach my $idx ( 0 .. $#items ) {
253              
254 0 0         if( $idx >= ($lastbreak + $cols) ) {
255              
256 0           $rownum++;
257              
258 0           $colnum = $maxlen = 0;
259              
260 0           $lastbreak = $idx;
261              
262             }#if
263              
264 0           $width[$colnum] = Hub::max($width[$colnum],length($items[$idx]));
265              
266 0           push @{$grid[$rownum]}, $idx;
  0            
267              
268 0           $colnum++;
269              
270             }#foreach
271              
272             }#if
273              
274 0           foreach my $row ( @grid ) {
275              
276 0           $colnum = 0;
277              
278 0 0         $buf and $buf .= "\n";
279              
280 0           foreach my $idx ( @$row ) {
281              
282 0           my $val = $items[$idx];
283              
284 0 0         my $w = $colwidth ? $colwidth : $width[$colnum++] + $padding;
285              
286 0           $buf .= fw( $w, $val, "padding:$padwith", $justify );
287              
288             }#foreach
289              
290             }#foreach
291              
292             }#if
293              
294 0           return $buf;
295              
296             }#fcols
297              
298             # ------------------------------------------------------------------------------
299             # indenttext - Indent text
300             # indenttext $count, $text, [options]
301             #
302             # options:
303             #
304             # -skip_first=1 Do not indent the first line
305             # -pad=CHAR Use this padding character for indenting
306             # ------------------------------------------------------------------------------
307             #|test(match) indenttext(4,"Hello\nWorld")
308             #= Hello
309             #= World
310             # ------------------------------------------------------------------------------
311              
312             sub indenttext {
313 0     0 1   my ($opts,$num,$str) = Hub::opts(\@_,{'pad' => ' ', 'skip_first' => 0});
314 0 0         $$opts{'pad'} =~ /\n/ and die "padding cannot contain newlines";
315 0           $$opts{'pad'} x= $num;
316 0           my $pos = 0;
317 0           while ($pos > -1) {
318 0           $pos = index $str, "\n", $pos;
319 0           my $len = length($str);
320 0 0         if ($pos > -1) {
321 0 0         if (($pos + 1) < $len) {
322 0           substr ($str, $pos, 1, "\n$$opts{'pad'}");
323             }
324 0           $pos++;
325             }
326             }
327 0 0         return $$opts{'skip_first'} ? $str : "$$opts{'pad'}$str";
328             }#indenttext
329              
330             1;
331              
332             __END__