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.93';
4             }
5              
6 19     19   281934 use warnings;
  19         53  
  19         1199  
7 19     19   141 use strict;
  19         49  
  19         11726  
8              
9             require BibTeX::Parser::Author; # mutual dependencies
10             require BibTeX::Parser;
11              
12             sub new {
13 130     130 1 1096255 my ($class, $type, $key, $parse_ok, $fieldsref) = @_;
14              
15 130 100       849 my %fields = defined $fieldsref ? %$fieldsref : ();
16 130         279 my $i=0;
17 130         455 foreach my $field (keys %fields) {
18 93 50       386 if ($field !~ /^_/) {
19 93         276 $fields{_fieldnums}->{$field}=$i;
20 93         210 $i++;
21             }
22             }
23 130 100       406 if (defined $type) {
24 93         310 $fields{_type} = uc($type);
25             }
26 130         308 $fields{_key} = $key;
27 130         257 $fields{_parse_ok} = $parse_ok;
28 130         361 $fields{_raw} = '';
29 130         641 return bless \%fields, $class;
30             }
31              
32              
33              
34             sub parse_ok {
35 51     51 1 5194 my $self = shift;
36 51 100       147 if (@_) {
37 34         92 $self->{_parse_ok} = shift;
38             }
39 51         156 $self->{_parse_ok};
40             }
41              
42              
43             sub error {
44 2     2 1 3 my $self = shift;
45 2 50       6 if (@_) {
46 2         11 $self->{_error} = shift;
47 2         5 $self->parse_ok(0);
48             }
49 2 50       18 return $self->parse_ok ? undef : $self->{_error};
50             }
51              
52              
53             sub type {
54 65 100   65 1 922 if (scalar @_ == 1) {
55             # get
56 28         54 my $self = shift;
57 28         124 return $self->{_type};
58             } else {
59             # set
60 37         92 my ($self, $newval) = @_;
61 37         168 $self->{_type} = uc($newval);
62             }
63             }
64              
65              
66             sub key {
67 90 100   90 1 2583 if (scalar @_ == 1) {
68             # get
69 58         92 my $self = shift;
70 58         438 return $self->{_key};
71             } else {
72             # set
73 32         158 my ($self, $newval) = @_;
74 32         207 $self->{_key} = $newval;
75             }
76              
77             }
78              
79              
80             sub field {
81 332 100   332 1 855 if (scalar @_ == 2) {
82             # get
83 195         473 my ($self, $field) = @_;
84 195         861 return $self->{ lc( $field ) };
85             } else {
86 137         371 my ($self, $key, $value) = @_;
87 137         232 my $field = lc ($key);
88 137         413 $self->{$field} = $value; #_sanitize_field($value);
89 137 100       382 if (!exists($self->{_fieldnums}->{$field})) {
90 136         179 my $num = scalar keys %{$self->{_fieldnums}};
  136         334  
91 136         358 $self->{_fieldnums}->{$field} = $num;
92             }
93             }
94              
95             }
96              
97 19     19   10864 use LaTeX::ToUnicode qw( convert );
  19         539752  
  19         7097  
98              
99              
100             sub cleaned_field {
101 91     91 1 263 my ( $self, $field, @options ) = @_;
102 91 50       268 if ( $field =~ /author|editor/i ) {
103 0         0 return $self->field( $field );
104             } else {
105 91         406 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         5 $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   4 my ( $self, $authors, @options ) = @_;
123             map {
124 1         3 my $author = $_;
  2         4  
125 2         12 my $new_author = BibTeX::Parser::Author->new;
126             map {
127 4         18 $new_author->$_( convert( $author->$_, @options ) )
128 2         6 } grep { defined $author->$_ } qw( first von last jr );
  8         29  
129 2         13 $new_author;
130             } @$authors;
131             }
132              
133 19     19   203 no LaTeX::ToUnicode;
  19         37  
  19         25208  
134              
135             sub _handle_author_editor {
136 33     33   69 my $type = shift;
137 33         68 my $self = shift;
138 33 50       94 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 33 100       132 unless ( defined $self->{"_$type"}) {
165 17   100     97 my @names = BibTeX::Parser::_split_braced_string($self->{$type} || "", '\s+and\s+' );
166 17         62 $self->{"_$type"} = [map {new BibTeX::Parser::Author $_} @names];
  32         187  
167             }
168 33         55 return @{$self->{"_$type"}};
  33         146  
169             }
170             }
171              
172              
173              
174             sub author {
175 24     24 1 1223 _handle_author_editor('author', @_);
176             }
177              
178              
179             sub editor {
180 9     9 1 712 _handle_author_editor('editor', @_);
181             }
182              
183              
184             sub fieldlist {
185 1     1 1 3 my $self = shift;
186            
187 1         6 return grep {!/^_/} keys %$self;
  7         23  
188             }
189              
190              
191             sub has {
192 3     3 1 10 my ($self, $field) = @_;
193              
194 3         18 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 36     36 1 56 my $self = shift;
211 36 50       123 if (@_) {
212 36         81 $self->{_raw} = shift;
213             }
214 36         74 return $self->{_raw};
215             }
216              
217             sub pre {
218 39     39 1 82 my $self = shift;
219 39 100       112 if (@_) {
220 36         112 $self->{_pre} = shift;
221             }
222 39         142 return $self->{_pre};
223             }
224              
225              
226             sub to_string {
227 15     15 1 118 my $self = shift;
228 15         45 my %options=@_;
229 15 100       50 if (!exists($options{canonize_names})) {
230 14         30 $options{canonize_names}=1;
231             }
232 15         107 my @fields = grep {!/^_/} keys %$self;
  180         365  
233             @fields = sort {
234 15         79 $self->{_fieldnums}->{$a} <=>
235 86         222 $self->{_fieldnums}->{$b}} @fields;
236 15         26 my $result = '';
237 15 100       43 if ($options{print_pre}) {
238 3         8 $result .= $self->pre()."\n";
239             }
240 15         40 my $type = $self->type;
241 15 100       39 if (exists($options{type_capitalization})) {
242 3 100       12 if ($options{type_capitalization} eq 'Lowercase') {
243 1         3 $type = lc $type;
244             }
245 3 100       9 if ($options{type_capitalization} eq 'Titlecase') {
246 1         3 $type = ucfirst lc $type;
247             }
248             }
249 15         44 print STDERR $self->key, "\n";
250 15         44 $result .= '@'.$type."{".$self->key.",\n";
251 15         36 foreach my $field (@fields) {
252 73         141 my $value = $self->field($field);
253 73 100 100     182 if ($field eq 'author' && $options{canonize_names}) {
254 14         41 my @names = ($self->author);
255 14         126 $value = join(' and ', @names);
256             }
257 73 100 100     164 if ($field eq 'editor' && $options{canonize_names}) {
258 8         22 my @names = ($self->editor);
259 8         26 $value = join(' and ', @names);
260             }
261 73 100       137 if (exists($options{field_capitalization})) {
262 15 100       37 if ($options{field_capitalization} eq 'Uppercase') {
263 5         12 $field = uc $field;
264             }
265 15 100       36 if ($options{field_capitalization} eq 'Titlecase') {
266 5         43 $field = ucfirst $field;
267             }
268             }
269 73         246 $result .= " $field = {"."$value"."},\n";
270             }
271 15         26 $result .= "}";
272 15         98 return $result;
273             }
274              
275             1; # End of BibTeX::Entry
276              
277             __END__