Text-Funktion "truncate" nach Common verschoben, dokumentiert, getestet
authorMoritz Bunkus <m.bunkus@linet-services.de>
Thu, 4 Apr 2013 08:50:04 +0000 (10:50 +0200)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Fri, 19 Apr 2013 12:19:39 +0000 (14:19 +0200)
SL/Common.pm
SL/Presenter/Text.pm
t/common.t [new file with mode: 0644]

index 159609d..ff6c721 100644 (file)
@@ -46,6 +46,21 @@ sub tmpname {
   return "/tmp/kivitendo-tmp-" . unique_id();
 }
 
+sub truncate {
+  my ($text, %params) = @_;
+
+  $params{at}       //= 50;
+  $params{at}         =  3 if 3 > $params{at};
+
+  $params{strip}    //= '';
+
+  $text =~ s/[\r\n]+$//g if $params{strip} =~ m/^(?: 1 | newlines? | full )$/x;
+  $text =~ s/[\r\n]+/ /g if $params{strip} =~ m/^(?:     newlines? | full )$/x;
+
+  return $text if length($text) <= $params{at};
+  return substr($text, 0, $params{at} - 3) . '...';
+}
+
 sub retrieve_parts {
   $main::lxdebug->enter_sub();
 
@@ -576,3 +591,46 @@ sub check_params_x {
 }
 
 1;
+__END__
+
+=pod
+
+=encoding utf8
+
+=head1 NAME
+
+Common - Common routines used in a lot of places.
+
+=head1 SYNOPSIS
+
+  my $short_text = Common::truncate($long_text, at => 10);
+
+=head1 FUNCTIONS
+
+=over 4
+
+=item C<truncate $text, %params>
+
+Truncates C<$text> at a position and insert an ellipsis if the text is
+longer. The maximum number of characters to return is given with the
+paramter C<at> which defaults to 50.
+
+The optional parameter C<strip> can be used to remove unwanted line
+feed/carriage return characters from the text before truncation. It
+can be set to C<1> (only strip those at the end of C<$text>) or
+C<full> (replace consecutive line feed/carriage return characters in
+the middle by a single space and remove tailing line feed/carriage
+return characters).
+
+=back
+
+=head1 BUGS
+
+Nothing here yet.
+
+=head1 AUTHOR
+
+Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>,
+Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
+
+=cut
index 637bff6..af37323 100644 (file)
@@ -12,12 +12,7 @@ use Carp;
 sub truncate {
   my ($self, $text, %params) = @_;
 
-  $params{at}             ||= 50;
-  $params{at}               =  3 if 3 > $params{at};
-  $params{at}              -= 3;
-
-  return $text if length($text) < $params{at};
-  return substr($text, 0, $params{at}) . '...';
+  return Common::truncate($text, %params);
 }
 
 sub simple_format {
@@ -77,15 +72,11 @@ it, e.g. C<2 PT 2 h> for the value C<18> and German.
 If the parameter C<skip_zero> is trueish then C<---> is returned
 instead of the normal formatting if C<$value> equals 0.
 
-=item C<truncate $text, [%params]>
+=item C<truncate $text, %params>
 
 Returns the C<$text> truncated after a certain number of
-characters.
-
-The number of characters to truncate at is determined by the parameter
-C<at> which defaults to 50. If the text is longer than C<$params{at}>
-then it will be truncated and postfixed with '...'. Otherwise it will
-be returned unmodified.
+characters. See L<Common/truncate> for the actual implementation and
+supported parameters.
 
 =item C<simple_format $text>
 
diff --git a/t/common.t b/t/common.t
new file mode 100644 (file)
index 0000000..b68cba2
--- /dev/null
@@ -0,0 +1,49 @@
+use strict;
+
+use Test::More;
+
+use lib 't';
+use Support::TestSetup;
+
+Support::TestSetup::login();
+
+use SL::Common;
+
+sub test_truncate {
+  is(Common::truncate('nothing to do', at => -1),  '...',           'truncation length < 0: at least 3');
+  is(Common::truncate('nothing to do', at => 0),   '...',           'truncation length = 0: at least 3');
+  is(Common::truncate('nothing to do', at => 1),   '...',           'truncation length = 1: at least 3');
+  is(Common::truncate('nothing to do', at => 2),   '...',           'truncation length = 2: at least 3');
+  is(Common::truncate('nothing to do', at => 3),   '...',           'truncation length = 3: at least 3');
+  is(Common::truncate('nothing to do', at => 4),   'n...',          'truncation length = 4');
+  is(Common::truncate('nothing to do', at => 9),   'nothin...',     'text length equal to truncation + 4');
+  is(Common::truncate('nothing to do', at => 10),  'nothing...',    'text length equal to truncation + 3');
+  is(Common::truncate('nothing to do', at => 11),  'nothing ...',   'text length equal to truncation + 2');
+  is(Common::truncate('nothing to do', at => 12),  'nothing t...',  'text length equal to truncation + 1');
+  is(Common::truncate('nothing to do', at => 13),  'nothing to do', 'text length equal to truncation');
+  is(Common::truncate('nothing to do', at => 14),  'nothing to do', 'text length equal to truncation - 1');
+  is(Common::truncate('nothing to do', at => 15),  'nothing to do', 'text length equal to truncation - 2');
+  is(Common::truncate('nothing to do', at => 16),  'nothing to do', 'text length equal to truncation - 3');
+  is(Common::truncate('nothing to do', at => 200), 'nothing to do', 'text length smaller than truncation');
+
+  is(Common::truncate('012345678901234567890123456789012345678901234567890123456789'), '01234567890123456789012345678901234567890123456...', 'default truncation length of 50');
+
+  # Test stripping
+  is(Common::truncate("nothing\n\rat\rall\n\n", at => 50, strip => 1), "nothing\n\rat\rall", 'strip = 1, at = 50');
+  is(Common::truncate("nothing\n\rat\rall\n\n", at => 13, strip => 1), "nothing\n\ra...",    'strip = 1, at = 13');
+
+  is(Common::truncate("nothing\n\rat\rall\n\n", at => 50, strip => 'full'), "nothing at all", 'strip = full, at = 50');
+  is(Common::truncate("nothing\n\rat\rall\n\n", at => 13, strip => 'full'), "nothing at...",  'strip = full, at = 13');
+
+  is(Common::truncate("nothing\n\rat\rall\n\n", at => 50, strip => 'newlines'), "nothing at all", 'strip = newlines, at = 50');
+  is(Common::truncate("nothing\n\rat\rall\n\n", at => 13, strip => 'newlines'), "nothing at...",  'strip = newlines, at = 13');
+
+  is(Common::truncate("nothing\n\rat\rall\n\n", at => 50, strip => 'newline'), "nothing at all", 'strip = newline, at = 50');
+  is(Common::truncate("nothing\n\rat\rall\n\n", at => 13, strip => 'newline'), "nothing at...",  'strip = newline, at = 13');
+}
+
+test_truncate();
+
+done_testing;
+
+1;