1package BibTeX::Parser::Entry; 2{ 3 $BibTeX::Parser::Entry::VERSION = '1.03'; 4} 5 6use warnings; 7use strict; 8 9use BibTeX::Parser; 10use BibTeX::Parser::Author; 11 12 13 14sub new { 15 my ($class, $type, $key, $parse_ok, $fieldsref) = @_; 16 17 my %fields = defined $fieldsref ? %$fieldsref : (); 18 my $i=0; 19 foreach my $field (keys %fields) { 20 if ($field !~ /^_/) { 21 $fields{_fieldnums}->{$field}=$i; 22 $i++; 23 } 24 } 25 if (defined $type) { 26 $fields{_type} = uc($type); 27 } 28 $fields{_key} = $key; 29 $fields{_parse_ok} = $parse_ok; 30 $fields{_raw} = ''; 31 return bless \%fields, $class; 32} 33 34 35 36sub parse_ok { 37 my $self = shift; 38 if (@_) { 39 $self->{_parse_ok} = shift; 40 } 41 $self->{_parse_ok}; 42} 43 44 45sub error { 46 my $self = shift; 47 if (@_) { 48 $self->{_error} = shift; 49 $self->parse_ok(0); 50 } 51 return $self->parse_ok ? undef : $self->{_error}; 52} 53 54 55sub type { 56 if (scalar @_ == 1) { 57 # get 58 my $self = shift; 59 return $self->{_type}; 60 } else { 61 # set 62 my ($self, $newval) = @_; 63 $self->{_type} = uc($newval); 64 } 65} 66 67 68sub key { 69 if (scalar @_ == 1) { 70 # get 71 my $self = shift; 72 return $self->{_key}; 73 } else { 74 # set 75 my ($self, $newval) = @_; 76 $self->{_key} = $newval; 77 } 78 79} 80 81 82sub field { 83 if (scalar @_ == 2) { 84 # get 85 my ($self, $field) = @_; 86 return $self->{ lc( $field ) }; 87 } else { 88 my ($self, $key, $value) = @_; 89 my $field = lc ($key); 90 $self->{$field} = $value; #_sanitize_field($value); 91 if (!exists($self->{_fieldnums}->{$field})) { 92 my $num = scalar keys %{$self->{_fieldnums}}; 93 $self->{_fieldnums}->{$field} = $num; 94 } 95 } 96 97} 98 99use LaTeX::ToUnicode qw( convert ); 100 101 102sub cleaned_field { 103 my ( $self, $field, @options ) = @_; 104 if ( $field =~ /author|editor/i ) { 105 return $self->field( $field ); 106 } else { 107 return convert( $self->field( lc $field ), @options ); 108 } 109} 110 111 112sub cleaned_author { 113 my $self = shift; 114 $self->_handle_cleaned_author_editor( [ $self->author ], @_ ); 115} 116 117 118sub cleaned_editor { 119 my $self = shift; 120 $self->_handle_cleaned_author_editor( [ $self->editor ], @_ ); 121} 122 123sub _handle_cleaned_author_editor { 124 my ( $self, $authors, @options ) = @_; 125 map { 126 my $author = $_; 127 my $new_author = BibTeX::Parser::Author->new; 128 map { 129 $new_author->$_( convert( $author->$_, @options ) ) 130 } grep { defined $author->$_ } qw( first von last jr ); 131 $new_author; 132 } @$authors; 133} 134 135no LaTeX::ToUnicode; 136 137sub _handle_author_editor { 138 my $type = shift; 139 my $self = shift; 140 if (@_) { 141 if (@_ == 1) { #single string 142 # my @names = split /\s+and\s+/i, $_[0]; 143 $_[0] =~ s/^\s*//; 144 $_[0] =~ s/\s*$//; 145 my @names = BibTeX::Parser::_split_braced_string($_[0], 146 '\s+and\s+'); 147 if (!scalar @names) { 148 $self->error('Bad names in author/editor field'); 149 return; 150 } 151 $self->{"_$type"} = [map {new BibTeX::Parser::Author $_} @names]; 152 $self->field($type, join " and ", @{$self->{"_$type"}}); 153 } else { 154 $self->{"_$type"} = []; 155 foreach my $param (@_) { 156 if (ref $param eq "BibTeX::Author") { 157 push @{$self->{"_$type"}}, $param; 158 } else { 159 push @{$self->{"_$type"}}, new BibTeX::Parser::Author $param; 160 } 161 162 $self->field($type, join " and ", @{$self->{"_$type"}}); 163 } 164 } 165 } else { 166 unless ( defined $self->{"_$type"}) { 167 my @names = BibTeX::Parser::_split_braced_string($self->{$type} || "", '\s+and\s+' ); 168 $self->{"_$type"} = [map {new BibTeX::Parser::Author $_} @names]; 169 } 170 return @{$self->{"_$type"}}; 171 } 172} 173 174 175 176sub author { 177 _handle_author_editor('author', @_); 178} 179 180 181sub editor { 182 _handle_author_editor('editor', @_); 183} 184 185 186sub fieldlist { 187 my $self = shift; 188 189 return grep {!/^_/} keys %$self; 190} 191 192 193sub has { 194 my ($self, $field) = @_; 195 196 return defined $self->{$field}; 197} 198 199sub _sanitize_field { 200 my $value = shift; 201 for ($value) { 202 tr/\{\}//d; 203 s/\\(?!=[ \\])//g; 204 s/\\\\/\\/g; 205 } 206 return $value; 207} 208 209 210 211sub raw_bibtex { 212 my $self = shift; 213 if (@_) { 214 $self->{_raw} = shift; 215 } 216 return $self->{_raw}; 217} 218 219sub pre { 220 my $self = shift; 221 if (@_) { 222 $self->{_pre} = shift; 223 } 224 return $self->{_pre}; 225} 226 227 228sub to_string { 229 my $self = shift; 230 my %options=@_; 231 if (!exists($options{canonize_names})) { 232 $options{canonize_names}=1; 233 } 234 my @fields = grep {!/^_/} keys %$self; 235 @fields = sort { 236 $self->{_fieldnums}->{$a} <=> 237 $self->{_fieldnums}->{$b}} @fields; 238 my $result = ''; 239 if ($options{print_pre}) { 240 $result .= $self->pre()."\n"; 241 } 242 my $type = $self->type; 243 if (exists($options{type_capitalization})) { 244 if ($options{type_capitalization} eq 'Lowercase') { 245 $type = lc $type; 246 } 247 if ($options{type_capitalization} eq 'Titlecase') { 248 $type = ucfirst lc $type; 249 } 250 } 251 print STDERR $self->key, "\n"; 252 $result .= '@'.$type."{".$self->key.",\n"; 253 foreach my $field (@fields) { 254 my $value = $self->field($field); 255 if ($field eq 'author' && $options{canonize_names}) { 256 my @names = ($self->author); 257 $value = join(' and ', @names); 258 } 259 if ($field eq 'editor' && $options{canonize_names}) { 260 my @names = ($self->editor); 261 $value = join(' and ', @names); 262 } 263 if (exists($options{field_capitalization})) { 264 if ($options{field_capitalization} eq 'Uppercase') { 265 $field = uc $field; 266 } 267 if ($options{field_capitalization} eq 'Titlecase') { 268 $field = ucfirst $field; 269 } 270 } 271 $result .= " $field = {"."$value"."},\n"; 272 } 273 $result .= "}"; 274 return $result; 275} 276 2771; # End of BibTeX::Entry 278 279__END__ 280=pod 281 282=head1 NAME 283 284BibTeX::Parser::Entry - Contains a single entry of a BibTeX document. 285 286=head1 SYNOPSIS 287 288This class ist a wrapper for a single BibTeX entry. It is usually created 289by a BibTeX::Parser. 290 291 use BibTeX::Parser::Entry; 292 293 my $entry = BibTeX::Parser::Entry->new($type, $key, $parse_ok, \%fields); 294 295 if ($entry->parse_ok) { 296 my $type = $entry->type; 297 my $key = $enty->key; 298 print $entry->field("title"); 299 my @authors = $entry->author; 300 my @editors = $entry->editor; 301 302 ... 303 304 print $entry->to_string; 305 } 306 307 308 309 310 311=head1 FUNCTIONS 312 313=head2 new 314 315Create new entry. 316 317=head2 parse_ok 318 319If the entry was correctly parsed, this method returns a true value, false otherwise. 320 321=head2 error 322 323Return the error message, if the entry could not be parsed or undef otherwise. 324 325=head2 type 326 327Get or set the type of the entry, eg. 'ARTICLE' or 'BOOK'. Return value is 328always uppercase. 329 330=head2 key 331 332Get or set the reference key of the entry. 333 334=head2 field($name [, $value]) 335 336Get or set the contents of a field. The first parameter is the name of the 337field, the second (optional) value is the new value. 338 339=head2 cleaned_field($name) 340 341Retrieve the contents of a field in a format that is cleaned of TeX markup. 342 343=head2 cleaned_author 344 345Get an array of L<BibTeX::Parser::Author> objects for the authors of this 346entry. Each name has been cleaned of accents and braces. 347 348=head2 cleaned_editor 349 350Get an array of L<BibTeX::Parser::Author> objects for the editors of this 351entry. Each name has been cleaned of accents and braces. 352 353=head2 author([@authors]) 354 355Get or set the authors. Returns an array of L<BibTeX::Author|BibTeX::Author> 356objects. The parameters can either be L<BibTeX::Author|BibTeX::Author> objects 357or strings. 358 359Note: You can also change the authors with $entry->field('author', $authors_string) 360 361=head2 editor([@editors]) 362 363Get or set the editors. Returns an array of L<BibTeX::Author|BibTeX::Author> 364objects. The parameters can either be L<BibTeX::Author|BibTeX::Author> objects 365or strings. 366 367Note: You can also change the authors with $entry->field('editor', $editors_string) 368 369=head2 fieldlist () 370 371Returns a list of all the fields used in this entry. 372 373=head2 has($fieldname) 374 375Returns a true value if this entry has a value for $fieldname. 376 377=head2 pre () 378 379Return the text in BibTeX file before the entry 380 381=head2 raw_bibtex () 382 383Return raw BibTeX entry (if available). 384 385=head2 to_string ([options]) 386 387Returns a text of the BibTeX entry in BibTeX format. Options are 388a hash. 389 390=over 4 391 392=item C<canonize_names> 393 394If true (the default), authors' and editors' 395names are translated into canonical bibtex form. The command 396C<$entry-E<gt>to_string(canonize_names=E<gt>0)> overrides this behavior. 397 398=item C<field_capitalization> 399 400Capitalization of the field names. 401Can take values 'Uppercase', 'Lowercase' (the default) or 'Titlecase' 402 403=item C<print_pre> 404 405False by default. If true, the text in the Bib file before the 406entry is printed. Note that at present we assume the text 407before the entry NEVER has the @ symbol inside 408 409=item C<type_capitalization> 410 411Capitalization of the type names. 412Can take values 'Uppercase' (the default), 'Lowercase' or 'Titlecase' 413 414 415=back 416 417=head1 VERSION 418 419version 1.02 420 421=head1 AUTHOR 422 423Gerhard Gossen <gerhard.gossen@googlemail.com> and 424Boris Veytsman <boris@varphi.com> 425 426=head1 COPYRIGHT AND LICENSE 427 428This software is copyright (c) 2013-2016 by Gerhard Gossen and Boris Veytsman 429 430This is free software; you can redistribute it and/or modify it under 431the same terms as the Perl 5 programming language system itself. 432 433=cut 434 435