File Coverage

blib/lib/BibTeX/Parser/Entry.pm
Criterion Covered Total %
statement 126 155 81.2
branch 44 56 78.5
condition 8 8 100.0
subroutine 21 23 91.3
pod 16 16 100.0
total 215 258 83.3


line stmt bran cond sub pod time code
1             package BibTeX::Parser::Entry;
2             {
3             $BibTeX::Parser::Entry::VERSION = '1.95';
4             }
5              
6 20     20   167281 use warnings;
  20         35  
  20         964  
7 20     20   86 use strict;
  20         40  
  20         9604  
8              
9             require BibTeX::Parser::Author; # mutual dependencies
10             require BibTeX::Parser;
11              
12             sub new {
13 140     140 1 952398 my ($class, $type, $key, $parse_ok, $fieldsref) = @_;
14              
15 140 100       436 my %fields = defined $fieldsref ? %$fieldsref : ();
16 140         194 my $i=0;
17 140         303 foreach my $field (keys %fields) {
18 93 50       228 if ($field !~ /^_/) {
19 93         165 $fields{_fieldnums}->{$field}=$i;
20 93         124 $i++;
21             }
22             }
23 140 100       253 if (defined $type) {
24 93         160 $fields{_type} = uc($type);
25             }
26 140         218 $fields{_key} = $key;
27 140         174 $fields{_parse_ok} = $parse_ok;
28 140         188 $fields{_raw} = '';
29 140         446 return bless \%fields, $class;
30             }
31              
32              
33              
34             sub parse_ok {
35 74     74 1 3826 my $self = shift;
36 74 100       139 if (@_) {
37 45         68 $self->{_parse_ok} = shift;
38             }
39 74         172 $self->{_parse_ok};
40             }
41              
42              
43             sub error {
44 4     4 1 7 my $self = shift;
45 4 50       10 if (@_) {
46 4         16 $self->{_error} = shift;
47 4         11 $self->parse_ok(0);
48             }
49 4 50       8 return $self->parse_ok ? undef : $self->{_error};
50             }
51              
52              
53             sub type {
54 75 100   75 1 749 if (scalar @_ == 1) {
55             # get
56 29         41 my $self = shift;
57 29         99 return $self->{_type};
58             } else {
59             # set
60 46         93 my ($self, $newval) = @_;
61 46         160 $self->{_type} = uc($newval);
62             }
63             }
64              
65              
66             sub key {
67 108 100   108 1 2446 if (scalar @_ == 1) {
68             # get
69 68         89 my $self = shift;
70 68         412 return $self->{_key};
71             } else {
72             # set
73 40         120 my ($self, $newval) = @_;
74 40         94 $self->{_key} = $newval;
75             }
76              
77             }
78              
79              
80             sub field {
81 372 100   372 1 623 if (scalar @_ == 2) {
82             # get
83 199         306 my ($self, $field) = @_;
84 199         583 return $self->{ lc( $field ) };
85             } else {
86 173         392 my ($self, $key, $value) = @_;
87 173         282 my $field = lc ($key);
88 173         348 $self->{$field} = $value; #_sanitize_field($value);
89 173 100       436 if (!exists($self->{_fieldnums}->{$field})) {
90 172         198 my $num = scalar keys %{$self->{_fieldnums}};
  172         300  
91 172         359 $self->{_fieldnums}->{$field} = $num;
92             }
93             }
94              
95             }
96              
97 20     20   9368 use LaTeX::ToUnicode qw( convert );
  20         433306  
  20         5671  
98              
99              
100             sub cleaned_field {
101 91     91 1 157 my ( $self, $field, @options ) = @_;
102 91 50       135 if ( $field =~ /author|editor/i ) {
103 0         0 return $self->field( $field );
104             } else {
105 91         218 return convert( $self->field( lc $field ), @options );
106             }
107             }
108              
109              
110             sub cleaned_author {
111 1     1 1 3 my $self = shift;
112 1         2 $self->_handle_cleaned_author_editor( [ $self->author ], @_ );
113             }
114              
115              
116             sub cleaned_editor {
117 0     0 1 0 my $self = shift;
118 0         0 $self->_handle_cleaned_author_editor( [ $self->editor ], @_ );
119             }
120              
121             sub _handle_cleaned_author_editor {
122 1     1   3 my ( $self, $authors, @options ) = @_;
123             map {
124 1         2 my $author = $_;
  2         4  
125 2         6 my $new_author = BibTeX::Parser::Author->new;
126             map {
127 4         35 $new_author->$_( convert( $author->$_, @options ) )
128 2         4 } grep { defined $author->$_ } qw( first von last jr );
  8         16  
129 2         6 $new_author;
130             } @$authors;
131             }
132              
133 20     20   151 no LaTeX::ToUnicode;
  20         40  
  20         20702  
134              
135             sub _handle_author_editor {
136 34     34   52 my $type = shift;
137 34         62 my $self = shift;
138 34 50       91 if (@_) {
139 0 0       0 if (@_ == 1) { #single string
140             # my @names = split /\s+and\s+/i, $_[0];
141 0         0 $_[0] =~ s/^\s*//;
142 0         0 $_[0] =~ s/\s*$//;
143 0         0 my @names = BibTeX::Parser::_split_braced_string($_[0],
144             '\s+and\s+');
145 0 0       0 if (!scalar @names) {
146 0         0 $self->error('Bad names in author/editor field');
147 0         0 return;
148             }
149 0         0 $self->{"_$type"} = [map {new BibTeX::Parser::Author $_} @names];
  0         0  
150 0         0 $self->field($type, join " and ", @{$self->{"_$type"}});
  0         0  
151             } else {
152 0         0 $self->{"_$type"} = [];
153 0         0 foreach my $param (@_) {
154 0 0       0 if (ref $param eq "BibTeX::Author") {
155 0         0 push @{$self->{"_$type"}}, $param;
  0         0  
156             } else {
157 0         0 push @{$self->{"_$type"}}, new BibTeX::Parser::Author $param;
  0         0  
158             }
159            
160 0         0 $self->field($type, join " and ", @{$self->{"_$type"}});
  0         0  
161             }
162             }
163             } else {
164 34 100       103 unless ( defined $self->{"_$type"}) {
165 18   100     94 my @names = BibTeX::Parser::_split_braced_string($self->{$type} || "", '\s+and\s+' );
166 18         40 $self->{"_$type"} = [map {new BibTeX::Parser::Author $_} @names];
  36         186  
167             }
168 34         47 return @{$self->{"_$type"}};
  34         143  
169             }
170             }
171              
172              
173              
174             sub author {
175 25     25 1 1124 _handle_author_editor('author', @_);
176             }
177              
178              
179             sub editor {
180 9     9 1 796 _handle_author_editor('editor', @_);
181             }
182              
183              
184             sub fieldlist {
185 1     1 1 13 my $self = shift;
186            
187 1         6 return grep {!/^_/} keys %$self;
  7         21  
188             }
189              
190              
191             sub has {
192 3     3 1 10 my ($self, $field) = @_;
193              
194 3         16 return defined $self->{$field};
195             }
196              
197             sub _sanitize_field {
198 0     0   0 my $value = shift;
199 0         0 for ($value) {
200 0         0 tr/\{\}//d;
201 0         0 s/\\(?!=[ \\])//g;
202 0         0 s/\\\\/\\/g;
203             }
204 0         0 return $value;
205             }
206              
207              
208              
209             sub raw_bibtex {
210 45     45 1 59 my $self = shift;
211 45 50       91 if (@_) {
212 45         88 $self->{_raw} = shift;
213             }
214 45         87 return $self->{_raw};
215             }
216              
217             sub pre {
218 48     48 1 84 my $self = shift;
219 48 100       103 if (@_) {
220 45         107 $self->{_pre} = shift;
221             }
222 48         99 return $self->{_pre};
223             }
224              
225              
226             sub to_string {
227 16     16 1 55 my $self = shift;
228 16         37 my %options=@_;
229 16 100       48 if (!exists($options{canonize_names})) {
230 15         24 $options{canonize_names}=1;
231             }
232 16         58 my @fields = grep {!/^_/} keys %$self;
  190         280  
233             @fields = sort {
234 16         57 $self->{_fieldnums}->{$a} <=>
235 104         153 $self->{_fieldnums}->{$b}} @fields;
236 16         20 my $result = '';
237 16 100       34 if ($options{print_pre}) {
238 3         7 $result .= $self->pre()."\n";
239             }
240 16         33 my $type = $self->type;
241 16 100       32 if (exists($options{type_capitalization})) {
242 3 100       7 if ($options{type_capitalization} eq 'Lowercase') {
243 1         2 $type = lc $type;
244             }
245 3 100       6 if ($options{type_capitalization} eq 'Titlecase') {
246 1         2 $type = ucfirst lc $type;
247             }
248             }
249 16         32 print STDERR $self->key, "\n";
250 16         34 $result .= '@'.$type."{".$self->key.",\n";
251 16         29 foreach my $field (@fields) {
252 77         148 my $value = $self->field($field);
253 77 100 100     172 if ($field eq 'author' && $options{canonize_names}) {
254 15         38 my @names = ($self->author);
255 15         129 $value = join(' and ', @names);
256             }
257 77 100 100     136 if ($field eq 'editor' && $options{canonize_names}) {
258 8         16 my @names = ($self->editor);
259 8         16 $value = join(' and ', @names);
260             }
261 77 100       107 if (exists($options{field_capitalization})) {
262 15 100       21 if ($options{field_capitalization} eq 'Uppercase') {
263 5         7 $field = uc $field;
264             }
265 15 100       18 if ($options{field_capitalization} eq 'Titlecase') {
266 5         8 $field = ucfirst $field;
267             }
268             }
269 77         154 $result .= " $field = {"."$value"."},\n";
270             }
271 16         20 $result .= "}";
272 16         71 return $result;
273             }
274              
275             1; # End of BibTeX::Entry
276              
277             __END__