1 # This module is part of da_reference, and is released under the terms
2 # of the GPL version 2, or any later version, at your option. See the
3 # file README and COPYING for more information.
4 # Copyright 2004 by Don Armstrong <don@donarmstrong.com>.
7 package Reference::Output::Bibtex;
11 Reference::Output::Bibtex -- Output references in BibTeX format
15 print bibtex($reference);
17 Returns a reference formatted in bibtex format.
21 Knows how to handle the reference-> bibtex field mapping for many
22 reference types, but overridden types may need to provide their own
34 use vars qw($REVISION $DEBUG @EXPORT @EXPORT_OK %EXPORT_TAGS);
36 use base qw(Exporter);
39 ($REVISION) = q$LastChangedRevision$ =~ /\$LastChangedRevision:\s+([^\s+])/;
40 $DEBUG = 0 unless defined $DEBUG;
44 %EXPORT_TAGS = (output => [qw(bibtex)],
46 Exporter::export_ok_tags(qw(output));
47 $EXPORT_TAGS{all} = [@EXPORT_OK];
51 # Assigned and discussed at the end of this file
55 use Params::Validate qw(:types validate_with);
61 print bibtex $reference;
62 %bibtex = bibtex $reference;
63 print bibtex($reference,mapping=>{...})
65 In scalar context, returns a formatted bibtex entry, suitable for
66 printing. In list context, returns a hash of key, value pairs which
67 can be used to print a formatted bibtex entry.
69 You can also pass an optional mapping to be used for making the bibtex
70 entry. See B<bibtex_mapping> for the details.
72 The mappings are obeyed in the following order, the first taking
73 precedence over the last.
79 =item Object's bibtex_mapping
81 =item Internal bibtex_mapping (%Reference::Output::Bibtex::bibtex_mapping)
85 Returns a SCALAR bibtex reference in scalar context, a HASH bibtex
86 reference in list context
91 my $reference = shift;
93 # Parse options if any
94 my %param = validate_with(params => \@_,
95 spec => {mapping => {type => HASHREF,
103 # Use our mapping by default if it exists
104 $mapping = $bibtex_mapping{lc($reference->{type})} if exists $bibtex_mapping{lc($reference->{type})};
105 # Override that with the module's mapping
106 $mapping = $reference->{bibtex_mapping} if exists $reference->{bibtex_mapping};
107 # Finally, override everything with passed mapping
108 $mapping = $param{mapping} if exists $param{mapping};
110 if (not defined $mapping) {
111 carp "This reference type doesn't support bibtex output.";
116 foreach my $bibtex_field (keys %{$mapping->{mapping}}) {
118 if (ref $bibtex_field) {
119 $params = $$bibtex_field{params} if exists $$bibtex_field{params};
120 $bibtex_field = $$bibtex_field{field};
122 my $function = $reference->can($mapping->{mapping}->{$bibtex_field});
123 next unless $function;
124 $bibtex_entry{$bibtex_field} = &{$function}($reference,output=>'bibtex',@$params);
125 # dereference the entries if necessesary.
126 next unless wantarray;
127 # Make new copies of the entries if necessary so we can
128 # mogrify to our hearts content.
129 if (ref($bibtex_entry{$bibtex_field}) eq 'HASH') {
130 $bibtex_entry{$bibtex_field} = {%{$bibtex_entry{$bibtex_field}}};
132 elsif (ref($bibtex_entry{$bibtex_field}) eq 'ARRAY') {
133 $bibtex_entry{$bibtex_field} = [@{$bibtex_entry{$bibtex_field}}];
136 # Return the entries in hash form if desired.
137 return %bibtex_entry if wantarray;
138 # Ok, stich the bibtex entry together...
140 $bibtex_entry = '@'.$mapping->{order}[0].'{'.$bibtex_entry{$mapping->{order}[0]}.",\n";
141 foreach my $bibtex_field (@{$mapping->{order}}[1..$#{$mapping->{order}}]) {
142 next unless defined $bibtex_entry{$bibtex_field};
143 if (ref $bibtex_entry{$bibtex_field} eq 'ARRAY') {
144 if (ref $mapping->{mapping}{$bibtex_field}) {
145 if (exists $mapping->{mapping}{$bibtex_field}{code}) {
146 local $_ = $bibtex_entry{$bibtex_field};
147 eval $mapping->{mapping}{$bibtex_field}{code};
148 carp "Error while executing code to assemble bibtex entry: $@" if $@;
150 elsif (exists $mapping->{mapping}{$bibtex_field}{join}) {
151 $bibtex_entry{$bibtex_field} = join($mapping->{mapping}{$bibtex_field}{join},
152 @{$bibtex_entry{$bibtex_field}});
155 carp "$bibtex_field is an ARRAYREF, joining using commas";
156 $bibtex_entry{$bibtex_field} = join(', ', @{$bibtex_entry{$bibtex_field}});
160 carp "$bibtex_field is an ARRAYREF, joining using commas";
161 $bibtex_entry{$bibtex_field} = join(', ', @{$bibtex_entry{$bibtex_field}});
164 my $entry = $bibtex_entry{$bibtex_field};
166 $bibtex_entry .= wrap(' ' x 4,' ' x 8 . ' ' x length($bibtex_field),"$bibtex_field = {".$entry."},\n");
168 $bibtex_entry .= "}\n";
169 return $bibtex_entry;
172 =head2 bibtex_mapping
174 $Reference::Output::Bibtex::bibtex_mapping{Article} =
175 {mapping => {author => {field => 'author',
183 order => [qw(name author volume foo)],
186 This variable holds the mapping to bibtex output.
188 Each type of reference has its own keys. Currently the following types
189 are supported by the Bibtex output method:
201 If you wish to add support for your own custom reference type, you
202 merely need to add a bibtex_mapping element to your class's hashref,
203 or add to this variable. [Preferbly the former, as the latter should
204 only be used by the end user.]
206 The mapping key in the reference type hashref is a hashref containing
207 key value pairs according to the following metric:
211 =item If the mapping key value is not a reference, the value is used
212 as the name function to call via C<$reference->field>. [In the example
213 above, the volume mapping is built by a call to
214 C<$reference->volume>].
216 =item If the mapping key value is a hashref, the hashref contains two
217 keys. The C<field> key contains the name of the function to call. The
218 C<params> key contains the parameters
222 The order key in the reference type hashref is an arrayref which
223 defines the order in which keys are listed in the BibTeX
224 output. Values in the arrayref should be the keys of the mapping
225 hashref. [The first value listed is the type of reference/reference
233 (article => {mapping => {Article => 'name',
236 journal => 'journal',
243 abstract => 'abstract',
245 mlid => 'medline_id',
250 order => [qw(Article author title journal
251 year key volume number pages
252 month abstract pmid mlid doi
256 book => {mapping => {Book => 'name',
265 abstract => 'abstract',
270 order => [qw(Article author title journal
271 year key volume number pages
272 month abstract doi html pdf),