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