File Coverage

blib/lib/Text/SuDocs.pm
Criterion Covered Total %
statement 55 56 98.2
branch 21 24 87.5
condition 8 14 57.1
subroutine 9 9 100.0
pod 3 4 75.0
total 96 107 89.7


line stmt bran cond sub pod time code
1             package Text::SuDocs;
2             {
3             $Text::SuDocs::VERSION = '0.014';
4             }
5              
6             # ABSTRACT: parse and normalize SuDocs numbers
7              
8 5     5   346188 use 5.10.0;
  5         25  
  5         265  
9              
10 5     5   5862 use Any::Moose;
  5         281378  
  5         40  
11 5     5   12295 use namespace::autoclean;
  5         144776  
  5         37  
12 5     5   451 use Carp;
  5         11  
  5         2188  
13              
14             our @subfields = qw{agency subagency committee series relatedseries document};
15              
16             has [qw(original), @subfields] => (
17             is => 'rw',
18             isa => 'Maybe[Str]',
19             );
20              
21             around BUILDARGS => sub {
22             my $orig = shift;
23             my $class = shift;
24              
25             if (@_ == 1 && !ref $_[0]) {
26             return $class->$orig(original => $_[0]);
27             }
28             else {
29             return $class->$orig(@_);
30             }
31             };
32              
33             sub BUILD {
34 1112     1112 1 1918 my $self = shift;
35 1112 100       3715 if($self->original) {
36 1105         3267 $self->parse;
37             }
38             }
39              
40             around 'original' => sub {
41             my $orig = shift;
42             my $self = shift;
43              
44             if (scalar @_) {
45             $self->$orig(@_);
46             $self->parse();
47             }
48              
49             return $self->$orig();
50             };
51              
52             sub parse {
53 1106     1106 0 2301 my $self = shift;
54 1106   33     11906 my $original = shift // $self->original;
55 1106 50       3942 return if ! defined $original;
56              
57 1106         20963 chomp($original);
58 5 100   5   6348 croak 'Invalid characters' if $original =~ qr{[^\p{IsAlnum}\s:/\-.<>()]};
  5         64  
  5         199  
  1106         16116  
59 1104         4594 $original = uc $original;
60 1104         15368 $original =~ s{^\s+|\s+$}{}g;
61 1104         31055 $original =~ s{\s+}{ }g;
62 1104         6190 $original =~ s{:$}{};
63              
64 1104 100       7418 if ($original =~ /^(XJH|XJS)$/) {
65 5         127 $self->agency($1);
66 5         97 return $self;
67             }
68              
69 1099         43823 $original =~ qr{
70             ^(\p{IsAlpha}+)\s* #Agency
71             (\p{IsDigit}+)\s*\.\s* #Subagency
72             (?:(\p{IsAlpha}+)\s+)? #Committee
73             (\p{IsDigit}+) #Series
74             (?:/(\p{IsAlnum}+)(-\p{IsAlnum}+)?)?\s* #RelSeries
75             (?::\s*(.*))?$ #Document
76             }x;
77 1099 50 66     17770 croak 'Unable to determine stem' if (!($1 && $2 && $4));
      33        
78              
79 1089         11243 $self->agency($1);
80 1089         6620 $self->subagency($2);
81 1089         19346 $self->committee($3);
82 1089         8132 $self->series($4);
83 1089 100       6673 my $relseries =
    100          
84             (!$5) ? undef :
85             ($6) ? $5.$6 : $5;
86 1089         11080 $self->relatedseries($relseries);
87 1089         26199 $self->document($7);
88              
89 1089         5482 return $self;
90             }
91              
92             sub normal_string {
93 1137     1137 1 967203 my $self = shift;
94 1137 50       9479 my %args = (ref $_[0]) ? %{$_[0]} : @_;
  0         0  
95              
96 1137 100       6161 return $self->agency if ($self->agency =~ /^(?:XJH|XJS)$/);
97              
98 1122 100       20983 my $sudocs = sprintf(
    100          
99             '%s %d.%s%s%s',
100             $self->agency,
101             $self->subagency,
102             ($self->committee) ? $self->committee . q{ } : '',
103             $self->series,
104             ($self->relatedseries) ? '/'.$self->relatedseries : '',
105             );
106              
107 1122 100 100     22864 unless ($args{class_stem} || !$self->document) {
108 1100         3170 $sudocs .= ':'.$self->document;
109             }
110 1122         7865 return $sudocs;
111             }
112              
113             sub sortable_string {
114 22     22 1 44 my $self = shift;
115 22   50     807 my $pad = shift // 8;
116              
117 22         57 my $s = $self->normal_string;
118 22         81 my $format = sprintf '%%0%dd', $pad;
119 22         251 $s =~ s/\b(\d+)\b/sprintf $format, $1/xge;
  70         1483  
120 22         189 $s =~ s/\s/_/g;
121              
122 22         218 return $s;
123             }
124              
125             __PACKAGE__->meta()->make_immutable();
126             1;
127              
128             __END__