File Coverage

blib/lib/Text/Names/Abbreviate.pm
Criterion Covered Total %
statement 29 31 93.5
branch 10 14 71.4
condition 3 4 75.0
subroutine 4 4 100.0
pod 0 1 0.0
total 46 54 85.1


line stmt bran cond sub pod time code
1             package Text::Names::Abbreviate;
2              
3 1     1   290223 use strict;
  1         3  
  1         66  
4 1     1   5 use warnings;
  1         2  
  1         60  
5 1     1   9 use Exporter 'import';
  1         1  
  1         512  
6              
7             our @EXPORT_OK = qw(abbreviate);
8             our $VERSION = '0.01';
9              
10             =head1 NAME
11              
12             Text::Names::Abbreviate - Create abbreviated name formats from full names
13              
14             =head1 SYNOPSIS
15              
16             use Text::Names::Abbreviate qw(abbreviate);
17              
18             say abbreviate("John Quincy Adams"); # "J. Q. Adams"
19             say abbreviate("Adams, John Quincy"); # "J. Q. Adams"
20             say abbreviate("George R R Martin", format => 'initials'); # "G.R.R.M."
21              
22             =head1 DESCRIPTION
23              
24             This module provides simple abbreviation logic for full personal names,
25             with multiple formatting options and styles.
26              
27             =head1 OPTIONS
28              
29             =over
30              
31             =item format
32              
33             One of: default, initials, compact, shortlast
34              
35             =item style
36              
37             One of: first_last, last_first
38              
39             =item separator
40              
41             Customize the spacing/punctuation for initials (default: ". ")
42              
43             =back
44              
45             =cut
46              
47             sub abbreviate {
48 4     4 0 682 my ($name, %opts) = @_;
49              
50 4   100     17 my $format = $opts{format} // 'default'; # default, initials, compact, shortlast
51 4   50     15 my $style = $opts{style} // 'first_last'; # first_last or last_first
52 4 50       11 my $sep = defined $opts{separator} ? $opts{separator} : '. ';
53              
54             # Normalize commas (e.g., "Adams, John Q." -> ("Adams", "John Q."))
55 4         5 my ($last, $rest);
56 4 100       16 if ($name =~ /,/) {
57 1         7 ($last, $rest) = map { s/^\s+|\s+$//gr } split(/\s*,\s*/, $name, 2);
  2         12  
58 1         2 $name = "$rest $last";
59             }
60              
61 4         12 my @parts = split /\s+/, $name;
62 4 50       9 return '' unless @parts;
63              
64 4         8 my $last_name = pop @parts;
65 4         10 my @initials = map { substr($_, 0, 1) } @parts;
  9         23  
66              
67 4 100       12 if ($format eq 'compact') {
    100          
    50          
68 1         6 return join('', @initials, substr($last_name, 0, 1));
69             }
70             elsif ($format eq 'initials') {
71 1         10 return join('.', @initials, substr($last_name, 0, 1)) . '.';
72             }
73             elsif ($format eq 'shortlast') {
74 0         0 return join(' ', map { "$_." } @initials) . " $last_name";
  0         0  
75             }
76             else { # default: "J. Q. Adams"
77 2         4 my $joined = join(' ', map { "$_." } @initials);
  4         10  
78 2 50       15 return $style eq 'last_first'
79             ? "$last_name, $joined"
80             : "$joined $last_name";
81             }
82             }
83              
84             1;
85              
86             __END__