File Coverage

blib/lib/SHARYANTO/String/Util.pm
Criterion Covered Total %
statement 98 106 92.4
branch 30 34 88.2
condition 25 27 92.5
subroutine 19 20 95.0
pod 15 16 93.7
total 187 203 92.1


line stmt bran cond sub pod time code
1             package SHARYANTO::String::Util;
2              
3 1     1   20467 use 5.010001;
  1         5  
  1         33  
4 1     1   4 use strict;
  1         2  
  1         27  
5 1     1   4 use warnings;
  1         2  
  1         51  
6              
7             our $VERSION = '0.28'; # VERSION
8              
9 1     1   8 use Exporter;
  1         2  
  1         1841  
10             our @ISA = qw(Exporter);
11             our @EXPORT_OK = qw(
12             ltrim
13             rtrim
14             trim
15             ltrim_lines
16             rtrim_lines
17             trim_lines
18             trim_blank_lines
19             ellipsis
20             indent
21             linenum
22             pad
23             qqquote
24             single_quote
25             double_quote
26             common_prefix
27             common_suffix
28             );
29              
30             sub ltrim {
31 6     6 1 1181 my $str = shift;
32 6         23 $str =~ s/\A\s+//s;
33 6         27 $str;
34             }
35              
36             sub rtrim {
37 6     6 1 2003 my $str = shift;
38 6         24 $str =~ s/\s+\z//s;
39 6         33 $str;
40             }
41              
42             sub trim {
43 6     6 1 1934 my $str = shift;
44 6         24 $str =~ s/\A\s+//s;
45 6         30 $str =~ s/\s+\z//s;
46 6         32 $str;
47             }
48              
49             sub ltrim_lines {
50 6     6 1 2395 my $str = shift;
51 6         31 $str =~ s/^[ \t]+//mg; # XXX other unicode non-newline spaces
52 6         27 $str;
53             }
54              
55             sub rtrim_lines {
56 6     6 1 2130 my $str = shift;
57 6         28 $str =~ s/[ \t]+$//mg;
58 6         25 $str;
59             }
60              
61             sub trim_lines {
62 6     6 1 1866 my $str = shift;
63 6         103 $str =~ s/^[ \t]+//mg;
64 6         20 $str =~ s/[ \t]+$//mg;
65 6         28 $str;
66             }
67              
68             sub trim_blank_lines {
69 2     2 1 1307 local $_ = shift;
70 2 100       15 return $_ unless defined;
71 1         6 s/\A(?:\n\s*)+//;
72 1         8 s/(?:\n\s*){2,}\z/\n/;
73 1         6 $_;
74             }
75              
76             sub ellipsis {
77 6     6 1 14 my ($str, $maxlen, $ellipsis) = @_;
78 6   50     19 $maxlen //= 80;
79 6   100     28 $ellipsis //= "...";
80              
81 6 100       18 if (length($str) <= $maxlen) {
82 3         15 return $str;
83             } else {
84 3         21 return substr($str, 0, $maxlen-length($ellipsis)) . $ellipsis;
85             }
86             }
87              
88             sub indent {
89 2     2 1 6 my ($indent, $str, $opts) = @_;
90 2   100     496 $opts //= {};
91              
92 2 100 100     11 if ($opts->{indent_blank_lines} // 1) {
93 1         9 $str =~ s/^/$indent/mg;
94             } else {
95 1         12 $str =~ s/^([^\r\n]*\S[^\r\n]*)/$indent$1/mg;
96             }
97 2         11 $str;
98             }
99              
100             sub linenum {
101 4     4 1 9 my ($str, $opts) = @_;
102 4   100     13 $opts //= {};
103 4   100     17 $opts->{width} //= 4;
104 4   100     15 $opts->{zeropad} //= 0;
105 4   100     13 $opts->{skip_empty} //= 1;
106              
107 4         6 my $i = 0;
108 4         20 $str =~ s/^(([\t ]*\S)?.*)/
109 20 100 100     277 sprintf(join("",
    100 100        
110             "%",
111             ($opts->{zeropad} && !($opts->{skip_empty}
112             && !defined($2)) ? "0" : ""),
113             $opts->{width}, "s",
114             "|%s"),
115             ++$i && $opts->{skip_empty} && !defined($2) ? "" : $i,
116             $1)/meg;
117              
118 4         22 $str;
119             }
120              
121             sub pad {
122 7     7 1 747 my ($text, $width, $which, $padchar, $is_trunc) = @_;
123 7 100       18 if ($which) {
124 3         6 $which = substr($which, 0, 1);
125             } else {
126 4         8 $which = "r";
127             }
128 7   100     30 $padchar //= " ";
129              
130 7         11 my $w = length($text);
131 7 100 66     24 if ($is_trunc && $w > $width) {
132 1         4 $text = substr($text, 0, $width, 1);
133             } else {
134 6 100       23 if ($which eq 'l') {
    100          
135 1         4 $text = ($padchar x ($width-$w)) . $text;
136             } elsif ($which eq 'c') {
137 2         5 my $n = int(($width-$w)/2);
138 2         7 $text = ($padchar x $n) . $text . ($padchar x ($width-$w-$n));
139             } else {
140 3         10 $text .= ($padchar x ($width-$w));
141             }
142             }
143 7         30 $text;
144             }
145              
146             # BEGIN COPY PASTE FROM Data::Dump
147             my %esc = (
148             "\a" => "\\a",
149             "\b" => "\\b",
150             "\t" => "\\t",
151             "\n" => "\\n",
152             "\f" => "\\f",
153             "\r" => "\\r",
154             "\e" => "\\e",
155             );
156              
157             # put a string value in double quotes
158             sub double_quote {
159 4     4 1 1918 local($_) = $_[0];
160             # If there are many '"' we might want to use qq() instead
161 4         27 s/([\\\"\@\$])/\\$1/g;
162 4 100       39 return qq("$_") unless /[^\040-\176]/; # fast exit
163              
164 1         8 s/([\a\b\t\n\f\r\e])/$esc{$1}/g;
165              
166             # no need for 3 digits in escape for these
167 1         3 s/([\0-\037])(?!\d)/sprintf('\\%o',ord($1))/eg;
  0         0  
168              
169 1         3 s/([\0-\037\177-\377])/sprintf('\\x%02X',ord($1))/eg;
  0         0  
170 1         3 s/([^\040-\176])/sprintf('\\x{%X}',ord($1))/eg;
  0         0  
171              
172 1         5 return qq("$_");
173             }
174             # END COPY PASTE FROM Data::Dump
175              
176             # old name, deprecated, will be removed in the future
177 0     0 0 0 sub qqquote { goto &double_quote; }
178              
179             # will write this in the future, will produce "qq(...)" and "q(...)" literal
180             # representation
181             #sub qq_quote {}
182             #sub q_quote {}
183              
184             sub single_quote {
185 2     2 1 902 local($_) = $_[0];
186 2         21 s/([\\'])/\\$1/g;
187 2         23 return qq('$_');
188             }
189              
190             sub common_prefix {
191 6 50   6 1 865 return undef unless @_;
192 6         12 my $i;
193             L1:
194 6         26 for ($i=0; $i < length($_[0]); $i++) {
195 6         22 for (@_[1..$#_]) {
196 9 50       23 if (length($_) < $i) {
197 0         0 $i--; last L1;
  0         0  
198             } else {
199 9 100       57 last L1 if substr($_, $i, 1) ne substr($_[0], $i, 1);
200             }
201             }
202             }
203 6         33 substr($_[0], 0, $i);
204             }
205              
206             sub common_suffix {
207 6     6 1 1081 require List::Util;
208              
209 6 50       22 return undef unless @_;
210 6         9 my $i;
211             L1:
212 6         25 for ($i = 0; $i < length($_[0]); $i++) {
213 6         21 for (@_[1..$#_]) {
214 9 50       22 if (length($_) < $i) {
215 0         0 $i--; last L1;
  0         0  
216             } else {
217 9 100       53 last L1 if substr($_, -($i+1), 1) ne substr($_[0], -($i+1), 1);
218             }
219             }
220             }
221 6 100       41 $i ? substr($_[0], -$i) : "";
222             }
223              
224             1;
225             # ABSTRACT: String utilities
226              
227             __END__
228              
229             =pod
230              
231             =encoding UTF-8
232              
233             =head1 NAME
234              
235             SHARYANTO::String::Util - String utilities
236              
237             =head1 VERSION
238              
239             This document describes version 0.28 of SHARYANTO::String::Util (from Perl distribution SHARYANTO-String-Util), released on 2014-07-25.
240              
241             =for Pod::Coverage ^(qqquote)$
242              
243             =head1 FUNCTIONS
244              
245             =head2 ltrim($str) => STR
246              
247             Trim whitespaces (including newlines) at the beginning of string. Equivalent to:
248              
249             $str =~ s/\A\s+//s;
250              
251             =head2 ltrim_lines($str) => STR
252              
253             Trim whitespaces (not including newlines) at the beginning of each line of
254             string. Equivalent to:
255              
256             $str =~ s/^\s+//mg;
257              
258             =head2 rtrim($str) => STR
259              
260             Trim whitespaces (including newlines) at the end of string. Equivalent to:
261              
262             $str =~ s/[ \t]+\z//s;
263              
264             =head2 rtrim_lines($str) => STR
265              
266             Trim whitespaces (not including newlines) at the end of each line of
267             string. Equivalent to:
268              
269             $str =~ s/[ \t]+$//mg;
270              
271             =head2 trim($str) => STR
272              
273             ltrim + rtrim.
274              
275             =head2 trim_lines($str) => STR
276              
277             ltrim_lines + rtrim_lines.
278              
279             =head2 trim_blank_lines($str) => STR
280              
281             Trim blank lines at the beginning and the end. Won't trim blank lines in the
282             middle. Blank lines include lines with only whitespaces in them.
283              
284             =head2 ellipsis($str[, $maxlen, $ellipsis]) => STR
285              
286             Return $str unmodified if $str's length is less than $maxlen (default 80).
287             Otherwise cut $str to ($maxlen - length($ellipsis)) and append $ellipsis
288             (default '...') at the end.
289              
290             =head2 indent($indent, $str, \%opts) => STR
291              
292             Indent every line in $str with $indent. Example:
293              
294             indent(' ', "one\ntwo\nthree") # " one\n two\n three"
295              
296             %opts is optional. Known options:
297              
298             =over 4
299              
300             =item * indent_blank_lines => BOOL (default 1)
301              
302             If set to false, does not indent blank lines (i.e., lines containing only zero
303             or more whitespaces).
304              
305             =back
306              
307             =head2 linenum($str, \%opts) => STR
308              
309             Add line numbers. For example:
310              
311             1|line1
312             2|line2
313             |
314             4|line4
315              
316             Known options:
317              
318             =over 4
319              
320             =item * width => INT (default: 4)
321              
322             =item * zeropad => BOOL (default: 0)
323              
324             If turned on, will output something like:
325              
326             0001|line1
327             0002|line2
328             |
329             0004|line4
330              
331             =item * skip_empty => BOOL (default: 1)
332              
333             If set to false, keep printing line number even if line is empty:
334              
335             1|line1
336             2|line2
337             3|
338             4|line4
339              
340             =back
341              
342             =head2 pad($text, $width[, $which[, $padchar[, $truncate]]]) => STR
343              
344             Return C<$text> padded with C<$padchar> to C<$width> columns. C<$which> is
345             either "r" or "right" for padding on the right (the default if not specified),
346             "l" or "left" for padding on the right, or "c" or "center" or "centre" for
347             left+right padding to center the text.
348              
349             C<$padchar> is whitespace if not specified. It should be string having the width
350             of 1 column.
351              
352             =head2 double_quote($str) => STR
353              
354             Quote or encode C<$str> to the Perl double quote (C<">) literal representation
355             of the string. Example:
356              
357             say double_quote("a"); # => "a" (with the quotes)
358             say double_quote("a\n"); # => "a\n"
359             say double_quote('"'); # => "\""
360             say double_quote('$foo'); # => "\$foo"
361              
362             This code is taken from C<quote()> in L<Data::Dump>. Maybe I didn't look more
363             closely, but I couldn't a module that provides a function to do something like
364             this. L<String::Escape>, for example, provides C<qqbackslash> but it does not
365             escape C<$>.
366              
367             =head2 single_quote($str) => STR
368              
369             Like C<double_quote> but will produce a Perl single quote literal representation
370             instead of the double quote ones. In single quotes, only literal backslash C<\>
371             and single quote character C<'> are escaped, the rest are displayed as-is, so
372             the result might span multiple lines or contain other non-printable characters.
373              
374             say single_quote("Mom's"); # => 'Mom\'s' (with the quotes)
375             say single_quote("a\\"); # => 'a\\"
376             say single_quote('"'); # => '"'
377             say single_quote("\$foo"); # => '$foo'
378              
379             =head2 common_prefix(@LIST) => STR
380              
381             Given a list of strings, return common prefix.
382              
383             =head2 common_suffix(@LIST) => STR
384              
385             Given a list of strings, return common suffix.
386              
387             =head1 SEE ALSO
388              
389             L<SHARYANTO>
390              
391             =head1 HOMEPAGE
392              
393             Please visit the project's homepage at L<https://metacpan.org/release/SHARYANTO-String-Util>.
394              
395             =head1 SOURCE
396              
397             Source repository is at L<https://github.com/sharyanto/perl-SHARYANTO-String-Util>.
398              
399             =head1 BUGS
400              
401             Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=SHARYANTO-String-Util>
402              
403             When submitting a bug or request, please include a test-file or a
404             patch to an existing test-file that illustrates the bug or desired
405             feature.
406              
407             =head1 AUTHOR
408              
409             Steven Haryanto <stevenharyanto@gmail.com>
410              
411             =head1 COPYRIGHT AND LICENSE
412              
413             This software is copyright (c) 2014 by Steven Haryanto.
414              
415             This is free software; you can redistribute it and/or modify it under
416             the same terms as the Perl 5 programming language system itself.
417              
418             =cut