File Coverage

blib/lib/PBib/LabelStyle.pm
Criterion Covered Total %
statement 60 84 71.4
branch 7 14 50.0
condition 9 17 52.9
subroutine 16 20 80.0
pod 0 15 0.0
total 92 150 61.3


line stmt bran cond sub pod time code
1             # --*-Perl-*--
2             # $Id: LabelStyle.pm 10 2004-11-02 22:14:09Z tandler $
3             #
4              
5             package PBib::LabelStyle;
6 1     1   6 use strict;
  1         3  
  1         47  
7 1     1   5 use warnings;
  1         3  
  1         47  
8             #use English;
9              
10             # for debug:
11             #use Data::Dumper;
12              
13             BEGIN {
14 1     1   5 use vars qw($Revision $VERSION);
  1         3  
  1         139  
15 1 50   1   3 my $major = 1; q$Revision: 10 $ =~ /: (\d+)/; my ($minor) = ($1); $VERSION = "$major." . ($minor<10 ? '0' : '') . $minor;
  1         6  
  1         5  
  1         30  
16             }
17              
18             # superclass
19             # use PBib::Style;
20 1     1   16 use base qw(PBib::Style);
  1         2  
  1         1389  
21              
22             # used modules
23             #use ZZZZ;
24              
25             # module variables
26             # our ($mmmm);
27              
28             #
29             #
30             # access methods
31             #
32             #
33              
34 1056     1056 0 1135 sub options { my $self = shift; return $self->converter()->labelOptions(); }
  1056         2080  
35              
36 2     2 0 4 sub items { my $self = shift;
37 2         12 return $self->bibStyle()->items();
38             }
39              
40             #
41             # label options
42             #
43              
44 2     2 0 5 sub useUniqueLabels { my ($self) = @_;
45 2         8 my $opt = $self->option("unique");
46 2 50       12 return defined($opt) ? $opt : 1;
47             }
48 112     112 0 114 sub forceKey { my ($self) = @_;
49             # should the 'Key' field take precedence over the default label?
50 112   50     218 return $self->option("forcekey") || 0;
51             }
52              
53             #
54             # label & field options
55             #
56              
57 110     110 0 122 sub etalNumber { my ($self, $options) = @_;
58             # how many authors until I use the "et al." style?
59 110   50     257 return $self->fieldOption("etal", $options) || 3;
60             }
61 257     257 0 281 sub inlineField { my ($self, $options) = @_;
62             # should this field be inlined (if the style allows), e.g.
63             # Tandler (2001) instead of (Tandler, 2001)
64 257   100     527 return $self->fieldOption("inline", $options) || 0;
65             }
66 257     257 0 286 sub suppressAuthor { my ($self, $options) = @_;
67             # similar to "inline": don't output an author name, e.g.
68             # (2001) instead of (Tandler, 2001).
69             # This can be used, if the author is given already in the text, e.g.
70             # "... as Tandler [ :noauthor | [Tandler-2001]] says ..." will become
71             # "... as Tandler (2001) says ..." or
72             # "... as Tandler [42] says ..." or
73             # "... as Tandler [Tan01] says ..." depending on style.
74 257   50     584 return $self->fieldOption("noauthor", $options) || 0;
75             }
76 108     108 0 111 sub noParens { my ($self, $options) = @_;
77             # produce no surrounding parentheses, e.g.
78             # "Tandler, 2001"
79 108   50     256 return $self->fieldOption("noparens", $options) || 0;
80             }
81              
82 116     116 0 124 sub useBraces { my ($self, $options) = @_;
83             # use [...] instead of (...) for reference.
84             #### This should be a option of class ReferenceStyle instead!!!
85 116   50     251 return $self->fieldOption("useBraces", $options) || 0;
86             }
87              
88              
89              
90             #
91             #
92             # methods
93             #
94             #
95              
96             sub text {
97             #
98             # return the replacement text
99             #
100 141     141 0 170 my ($self, $refID, $options) = @_;
101 141         316 $self->setRefID($refID);
102 141         165 $self->{'fieldOptions'} = $options;
103              
104 141         194 my $labels = $self->{'labels'};
105 141 100       265 if( not defined($labels) ) {
106 2         14 $self->logMessage("generate labels");
107 2         7 $labels = $self->{'labels'} = {};
108 2         6 $self->{'uniqueLabelPostfixes'} = {};
109 2         12 my $items = $self->items();
110 2         6 my $label;
111 2         6 foreach my $item (@$items) {
112 112         330 $self->setRefID($item);
113 112 50 33     212 $label = ($self->forceKey() && $self->entryNotEmpty('Key'))
114             ? $self->entry('Key')
115             : $self->formatLabel($item, $options);
116 112         302 $labels->{$item} = $label;
117             }
118              
119             # check for unique names?
120 2 50       36 if( $self->useUniqueLabels() ) {
121 2         4 my %allLabels;
122 2         7 foreach my $item (@$items) {
123 112         185 $label = $labels->{$item};
124 112         212 while( exists($allLabels{$label}) ) {
125 0         0 $label = $self->uniqueLabel($item, $label, $labels, \%allLabels);
126             }
127 112         128 $labels->{$item} = $label;
128 112         269 $allLabels{$label} = $item;
129             }
130             }
131             # use Data::Dumper;
132             # print Dumper $labels; #, \%allLabels;
133             }
134 141 50       332 if( not exists($labels->{$refID}) ) {
135 0         0 $self->warn("no label for $refID!"); return "<>";
  0         0  
136             }
137             # print "$refID -> $labels->{$refID}\n";
138 141         372 return $labels->{$refID};
139             }
140              
141             sub formatLabel {
142             #
143             # return the label (cite key) for this reference
144             # can be overwritten by subclasses
145             # to implement more sophisticated styles
146             # the default implementation is rather simple ...
147             #
148 0     0 0 0 my ($self, $refID, $options) = @_;
149 0         0 return $refID;
150             }
151              
152             sub formatSeparators {
153 0     0 0 0 my ($self, $refField, $options) = @_;
154 0         0 return $refField;
155             }
156              
157             sub formatField {
158             #
159             # allow to change format of the field,
160             # e.g. add [...], or replace multi-reference separator etc.
161             #
162             # can be overwritten by subclasses
163             # to implement more sophisticated styles
164             # the default implementation is rather simple ...
165             #
166 0     0 0 0 my ($self, $refField, $options) = @_;
167 0         0 return "[$refField]";
168             }
169              
170              
171             #
172             #
173             # helper methods
174             #
175             #
176              
177             sub uniqueLabel {
178             #
179             # generate a unique label from $label
180             #
181 0     0 0 0 my ($self, $item, $label, $labels, $allLabels) = @_;
182 0         0 my $postfixes = $self->{'uniqueLabelPostfixes'};
183 0         0 $self->logMessage("generate unique label for $item ($label), conflict with $allLabels->{$label}");
184              
185             # is this the first collision? (and do we have a year somewhere?)
186 0 0       0 if( $label =~ s/([a-z])$// ) {
187             # there is a latter already appended -> inc. it
188 0         0 my $postfix = chr(ord($1) + 1);
189 0         0 $label .= $postfix;
190 0         0 $postfixes->{$item} = $postfix;
191 0         0 return $label;
192             }
193              
194             # this is the first collision => we have to append 'a' to the
195             # previous label as well! (but don't remove it from allLabels!)
196              
197             # get the item that we have a collision with
198 0         0 my $other = $allLabels->{$label};
199 0         0 $labels->{$other} = "${label}a";
200 0         0 $allLabels->{"${label}a"} = $label;
201 0         0 $label .= 'b';
202 0         0 $postfixes->{$other} = 'a';
203 0         0 $postfixes->{$item} = 'b';
204 0         0 return $label;
205             }
206              
207              
208             sub postfix {
209 112     112 0 139 my ($self, $refID) = @_;
210 112   50     544 return $self->{'uniqueLabelPostfixes'}->{$refID} || '';
211             }
212              
213              
214             1;
215              
216             #
217             # $Log: LabelStyle.pm,v $
218             # Revision 1.6 2003/09/30 14:35:12 tandler
219             # useBraces option for Label styles, not really nicely implemented, i.e. should be changed ...
220             #
221             # Revision 1.5 2003/09/23 11:40:08 tandler
222             # new label-style option :noparens
223             # use Biblio::Util's xname mode in splitname
224             #
225             # Revision 1.4 2002/11/03 22:14:36 peter
226             # support postfix for unique labels
227             #
228             # Revision 1.3 2002/10/11 10:14:29 peter
229             # unchanged
230             #
231             # Revision 1.2 2002/08/22 10:40:21 peter
232             # - fix option "unique"
233             #
234             # Revision 1.1 2002/03/27 10:00:50 Diss
235             # new module structure, not yet included in LitRefs/LitUI (R2)
236             #