1# $Id: natbib.perl,v 1.21 2001/11/08 00:50:15 RRM Exp $
2# natbib.perl - LaTeX2HTML support for the LaTeX2e natbib package
3#  (flexible author-year citations)
4# Martin Wilck, 20.5.1996 (martin@tropos.de)
5#
6# Change Log:
7# jcl = Jens Lippmann <lippmann@rbg.informatik.tu-darmstadt.de>
8# mwk = Martin Wilck
9# rrm = Ross Moore <ross@mpce.mq.edu.au>
10# jab = James A. Bednar <jbednar@cs.utexas.edu>
11#
12# $Log: natbib.perl,v $
13# Revision 1.21  2001/11/08 00:50:15  RRM
14#  --  bibtex inserts \penalty<num> in places that can cause page-numbers
15#      to be lost. Now a simple scan removes these.
16#      Thanks to Stephan Marsland for reporting the problem.
17#
18# Revision 1.20  1999/04/09 18:14:19  JCL
19# changed my e-Mail address
20#
21# Revision 1.19  1999/02/24 10:33:38  RRM
22#  --  fixed the 'exec' instead of 'eval' typo, with  \harvarditem
23#
24# Revision 1.18  1998/12/02 02:32:48  RRM
25#  --  corrections, updates and implementation of package options
26# 	by Bruce Miller
27#  --  adaptation of certain user-commands for indirection,
28# 	e.g. to work correctly with frames
29#  --  cosmetic edits
30#
31# Revision 1.17  1998/06/29 05:13:11  RRM
32#  --  loads the new  babelbst.perl  module as well
33#
34# Revision 1.16  1998/06/18 11:39:24  RRM
35#  --  removed a looping problem, with empty citations
36#  --  cosmetic edits
37#
38# Revision 1.15  1998/06/05 05:23:57  latex2html
39#  --  allow redefinition of names (e.g. \bibname ) and counter-outputs
40#     (e.g. \theequation, \thesection etc.)
41#
42# Revision 1.14  1998/06/01 07:52:35  latex2html
43#  --  fixed the memory problem due to recursion in do_env_bibliography
44#  	thanks to Uli Wortmann for the test-file
45#  --  properly implemented use of &bibitem_style and $BIBITEM_STYLE
46#  --  removed the redundant  $has_punct
47#
48# Revision 1.13  1998/05/24 05:56:27  latex2html
49#  --  fixed \citet  so that it works as in LaTeX now
50#  --  cosmetic changes so that this file's code is more easily readable
51#  --  changed a use of local($_) which grew memory !
52# 	was this the cause of Uli's problem ?
53#
54# Revision 1.12  1998/05/23 13:33:51  latex2html
55#  --  James Bednar's modifications/simplifications
56#  --  also \citeauthor \citeyear etc. working with multiple citations
57# from James Bednar: <jbednar@cs.utexas.edu>
58#  --  consolidated all non-Harvard cite commands except \cite and
59#      \cite* into one-line calls to a single function do_cite_common
60#      to ensure uniform processing of optional arguments
61#  --  fixed \citep -- had $cite_year_mark instead of $cite_par_mark
62#  --  changed do_cite_keys to always include every optional argument
63#  --  made \citeauthor, \citeauthor*, and \citefullauthor ignore
64#      whether mode is numeric (i.e., they should never get any parens)
65#  --  made \citealp act like \citealt (temporary)
66#
67# Revision 1.11  1998/04/29 10:11:07  latex2html
68#  --  use the &bibitem_style function, which can be user-defined
69#
70# Revision 1.10  1998/02/19 22:24:30  latex2html
71# th-darmstadt -> tu-darmstadt
72#
73# Revision 1.9  1997/10/07 06:59:44  RRM
74#  --  moved the code to  do_cmd_citestar  up to just after do_cmd_cite
75#  --  implemented \citep*  (oops, forgot it last time)
76#  --  fixed \harvardurl to work properly and without html.sty
77# 	thanks to James A. Bednar <jbednar@cs.utexas.edu> for noticing
78#
79# Revision 1.8  1997/09/19 10:57:44  RRM
80#      Updated for compatibility with natbib.sty v6.6
81#  --  all \cite... commands have a *-version and 2 optional arguments
82#  --  Harvard emulation is now automatic
83#
84# Revision 1.7  1997/07/11 11:28:52  RRM
85#  -  replace  (.*) patterns with something allowing \n s included
86#
87# Revision 1.6  1997/06/13 13:52:45  RRM
88#  -  renamed $citefile hash to  $citefiles  to avoid clash with scalar
89#  -  cosmetic changes in this file
90#
91# Revision 1.5  1997/04/27 06:29:17  RRM
92#      Cosmetic changes, to be more compatible with  Perl 4.
93#      (more changes may still be required, for complete compatibility.)
94#
95# Revision 1.4  1997/03/15 10:53:00  RRM
96# Cosmetic.
97#
98# Revision 1.3  1997/01/26 08:48:42  RRM
99# RRM: fixed minor bugs.
100#
101# Revision 1.2  1996/12/24 10:30:08  JCL
102# took &remove_general_markers out of the module, LaTeX2HTML will call
103# the cite mark hook in any case (hope that's ok?)
104#
105# modified for document segmentation by
106# Ross Moore, 28.5.1996 <ross@mpce.mq.edu.au>
107#
108# mwk -- 20.5.1996 -- created
109
110package main;
111
112# CUSTOMIZATION: Delimiters for citations in text
113#   (in natbib.sty, per default round parentheses)
114#   POSSIBLE IMPROVEMENT: It should be possible to alter these
115#       variables with options to the natbib package
116#       (requires change in texexpand)
117# The LaTeX \bibpunct command changes the punctuation
118# variables
119$CITE_OPEN_DELIM = '(' unless $CITE_OPEN_DELIM;
120$CITE_CLOSE_DELIM = ')' unless $CITE_CLOSE_DELIM;
121
122# CUSTOMIZATION: Delimiters for seperation of multiple citations
123$CITE_ENUM = '; ' unless $CITE_ENUM;
124
125# CUSTOMIZATION: whether multiple citations should be sorted. (BRM)
126$SORT_MULTIPLE = 0 unless $SORT_MULTIPLE;
127
128# CUSTOMIZATION: 1 for numeric citations
129$NUMERIC=0 unless defined ($NUMERIC);
130
131# CUSTOMIZATION: Delimiter between author and year in parentheses
132#  i.e. comma in "(Jones et al., 1990)"
133$BEFORE_PAR_YEAR=', ' unless $BEFORE_PAR_YEAR;
134
135# CUSTOMIZATION: Delimiter between multiple citations if authors are common
136#  i.e. comma in "Jones et al. (1990,1991)" or "Jones (1990a,b)"
137$COMMON_AUTHOR_SEP=',' unless $COMMON_AUTHOR_SEP;
138
139# CUSTOMIZATION: Delimiter before a note in a citation
140#  i.e. 2nd comma in "(Jones et al., 1990, page 267)"
141$POST_NOTE=',' unless $POST_NOTE;
142
143# CUSTOMIZATION:
144# Boolean value that determines if citations are put in the index
145# Can be modified in the text by the \citeindextrue and
146# \citeindexfalse commands
147$CITEINDEX=0 unless defined ($CITEINDEX);
148
149# The variable $HARVARD makes natbib.perl emulate harvard.perl
150# It is usually set to one in the "fake harvard.perl" before
151# calling natbib.perl.
152# Users normally shouldn't have to set it "by hand".
153$HARVARD=0 unless defined ($HARVARD);
154
155# Instead of $cite_mark, different markers for different manners
156# of citation
157
158# Jones et al. (1990)
159$cite_mark = '<tex2html_cite_mark>';
160# Jones, Baker, and Williams (1990)
161$cite_full_mark = '<tex2html_cite_full_mark>';
162
163# (Jones et al., 1990)
164$cite_par_mark = '<tex2html_cite_par_mark>';
165# (Jones, Baker, and Williams, 1990)
166$cite_par_full_mark = '<tex2html_cite_par_full_mark>';
167
168# Jones et al. [21]
169$citet_mark = '<tex2html_citet_mark>';
170# Jones, Baker, and Williams [21]
171$citet_full_mark = '<tex2html_citet_full_mark>';
172$citet_ext_mark = '<tex2html_citet_ext_mark>';
173
174# Jones et al., 1990
175$citealp_mark = '<tex2html_citealp_mark>';
176# Jones, Baker, and Williams, 1990
177$citealp_full_mark = '<tex2html_citealp_full_mark>';
178
179# Jones et al. 1990
180$citealt_mark = '<tex2html_citealt_mark>';
181# Jones, Baker, and Williams 1990
182$citealt_full_mark = '<tex2html_citealt_full_mark>';
183
184# Jones et al.
185$cite_author_mark = '<tex2html_cite_author_mark>';
186# Jones, Baker, and Williams
187$cite_author_full_mark = '<tex2html_cite_author_full_mark>';
188# 1990
189$cite_year_mark = '<tex2html_cite_year_mark>';
190
191# marker for multiple citations
192$cite_multiple_mark = '<tex2html_cite_multiple_mark>';
193
194$HARVARDAND="&amp;";
195
196# bibpunct arrays for citestyle command
197@citestyle_chicago  =('(',  ')',  '; ',  'a',  ', ',  ',' );
198@citestyle_named    =('[',  ']',  '; ',  'a',  ', ',  ',' );
199@citestyle_agu      =('[',  ']',  '; ',  'a',  ', ',  ', ');
200@citestyle_egs      =('(',  ')',  '; ',  'a',  ', ',  ',' );
201@citestyle_agsm     =('(',  ')',  ', ',  'a',  ''  ,  ',' );
202@citestyle_kluwer   =('(',  ')',  ', ',  'a',  ''  ,  ',' );
203@citestyle_dcu      =('(',  ')',  '; ',  'a',  '; ',  ',' );
204@citestyle_aa       =('(',  ')',  '; ',  'a',  ''  ,  ',' );
205@citestyle_pass     =('(',  ')',  '; ',  'a',  ', ',  ',' );
206@citestyle_anngeo   =('(',  ')',  '; ',  'a',  ', ',  ',' );
207@citestyle_nlinproc =('(',  ')',  '; ',  'a',  ', ',  ',' );
208
209$HARVARDAND_dcu = 'and';
210
211# Implementations of package options (BRM)
212sub do_natbib_round {
213    $CITE_OPEN_DELIM = '(';
214    $CITE_CLOSE_DELIM = ')'; }
215sub do_natbib_square {
216    $CITE_OPEN_DELIM = '[';
217    $CITE_CLOSE_DELIM = ']'; }
218sub do_natbib_curly {
219    $CITE_OPEN_DELIM = '{';
220    $CITE_CLOSE_DELIM = '}'; }
221sub do_natbib_angle {
222    $CITE_OPEN_DELIM = '&lt;';
223    $CITE_CLOSE_DELIM = '&gt;'; }
224sub do_natbib_colon {
225    $CITE_ENUM = '; '; }
226sub do_natbib_comma {
227    $CITE_ENUM = ', '; }
228sub do_natbib_authoryear {
229    $NUMERIC=0; }
230sub do_natbib_numbers {
231    $NUMERIC=1; }
232sub do_natbib_sectionbib {
233    $section_commands{'bibliography'} = 3; }
234sub do_natbib_sort {
235    $SORT_MULTIPLE = 1; }
236
237sub do_cmd_cite {
238    local($_) = @_;
239    local($cite_key, @cite_keys);
240# Look for options of the command in a seperate subroutine
241    local($has_optional,$optional1,$optional2)=&cite_check_options;
242# Select the correct marker
243    local ($c_mark) = ($has_optional ? $cite_par_mark : $cite_mark);
244# In numeric mode, all citations except those by \citet and \citet*
245# are marked by $cite_par_mark
246    $c_mark = $cite_par_mark if ($NUMERIC);
247# The following is standard from the original latex2html routine
248    s/^\s*\\space//o;		# Hack - \space is inserted in .aux
249    s/$next_pair_pr_rx//o;
250    if ($cite_key = $2) {
251	local ($br_id)=$1;
252	$_ = join(''
253# Second argument of &do_cite_keys set to TRUE in numeric mode
254# -> surround citation with parentheses
255	    , &do_cite_keys($br_id,($has_optional || $NUMERIC)
256		,$optional1,$optional2,$c_mark,$cite_key )
257	    , $_);
258    } else {print "Cannot find citation argument\n";}
259    $_;
260}
261
262sub do_cmd_citestar {
263# Same as do_cmd_cite, but uses full author information
264    local($_) = @_;
265    local($cite_key, @cite_keys);
266    local($has_optional,$optional1,$optional2)=&cite_check_options;
267    local ($c_mark) = ($has_optional ? $cite_par_full_mark : $cite_full_mark);
268    $c_mark = $cite_par_mark if ($NUMERIC);
269    s/^\s*\\space//o;           # Hack - \space is inserted in .aux
270    s/$next_pair_pr_rx//o;
271    if ($cite_key = $2) {
272        local ($br_id)=$1;
273        $_ = join('',
274            &do_cite_keys($br_id,($has_optional || $NUMERIC)
275                ,$optional1,$optional2,$c_mark,$cite_key), $_);
276    } else {print "Cannot find citation argument\n";}
277    $_;
278}
279
280
281# The following are Harvard-specific, but generally defined,
282# since they don't conflict with natbib syntax
283# They are therefore available in L2H inside a
284# htmlonly environment
285sub do_cmd_citeaffixed {
286# second argument for additional text inside the parentheses
287# before the citation
288    local($_) = @_;
289    local($cite_key, @cite_keys);
290    local ($optional1,$dummy)=&get_next_optional_argument;
291    s/^\s*\\space//o;		# Hack - \space is inserted in .aux
292    s/$next_pair_pr_rx//o;
293    $cite_key=$2;
294# read 2nd argument
295    s/$next_pair_pr_rx//o;
296    local($optional2)=$2;
297    if ($cite_key) {
298	local ($br_id)=$1;
299	$_ = join('',
300	    &do_cite_keys($br_id,1,
301		$optional1,$optional2,$cite_par_mark,$cite_key), $_);
302    } else {print "Cannot find citation argument\n";}
303    $_;
304}
305
306sub do_cmd_citeaffixedstar {
307    local($_) = @_;
308    local($cite_key, @cite_keys);
309    local ($optional1,$dummy)=&get_next_optional_argument;
310    s/^\s*\\space//o;		# Hack - \space is inserted in .aux
311    s/$next_pair_pr_rx//o;
312    $cite_key=$2;
313    s/$next_pair_pr_rx//o;
314    local($optional2)=$2;
315    if ($cite_key) {
316	local ($br_id)=$1;
317	$_ = join('',
318	    &do_cite_keys($br_id,1,
319		$optional1,$optional2,
320		  ($NUMERIC ? $cite_par_mark: $cite_par_full_mark),
321		  $cite_key), $_);
322    } else {print "Cannot find citation argument\n";}
323    $_;
324}
325
326sub do_cmd_citeasnoun {
327# Harvard:
328# Jones et al. (1990)
329    local($_) = @_;
330    local($cite_key, @cite_keys);
331# All harvard citation commands take one optional argument:
332#   Text to be inserted *after* the citation
333    local($optional1,$dummy)=&get_next_optional_argument;
334    s/^\s*\\space//o;		# Hack - \space is inserted in .aux
335    s/$next_pair_pr_rx//o;
336    if ($cite_key = $2) {
337	local ($br_id)=$1;
338	$_ = join('',
339	    &do_cite_keys($br_id,$NUMERIC,
340		$optional1,'',($NUMERIC? $cite_par_mark : $cite_mark)
341			  ,$cite_key), $_);
342    } else {print "Cannot find citation argument\n";}
343    $_;
344}
345
346sub do_cmd_citeasnounstar {
347# Harvard:
348# Jones, Baker and Williams (1990)
349    local($_) = @_;
350    local($cite_key, @cite_keys);
351    local($optional1,$dummy)=&get_next_optional_argument;
352    s/^\s*\\space//o;		# Hack - \space is inserted in .aux
353    s/$next_pair_pr_rx//o;
354    if ($cite_key = $2) {
355	local ($br_id)=$1;
356	$_ = join('',
357	    &do_cite_keys($br_id,$NUMERIC,
358		$optional1,'',($NUMERIC? $cite_par_mark : $cite_full_mark)
359			  ,$cite_key), $_);
360    } else {print "Cannot find citation argument\n";}
361    $_;
362}
363
364sub do_cmd_possessivecite {
365# Harvard:
366# Jones et al.'s (1990)
367# Uses the $citealt_mark marker (only in HARVARD mode)
368    local($_) = @_;
369    local($cite_key, @cite_keys);
370# All harvard citation commands take one optional argument:
371#   Text to be inserted *after* the citation
372    local($optional1,$dummy)=&get_next_optional_argument;
373    s/^\s*\\space//o;		# Hack - \space is inserted in .aux
374    s/$next_pair_pr_rx//o;
375    if ($cite_key = $2) {
376	local ($br_id)=$1;
377	$_ = join('',
378	    &do_cite_keys($br_id,$NUMERIC,
379		$optional1,'',($NUMERIC? $cite_par_mark : $citealt_mark)
380			  ,$cite_key), $_);
381    } else {print "Cannot find citation argument\n";}
382    $_;
383}
384
385sub do_cmd_possessivecitestar {
386# Harvard:
387# Jones, Baker, and Williams's (1990)
388    local($_) = @_;
389    local($cite_key, @cite_keys);
390    local($optional1,$dummy)=&get_next_optional_argument;
391    s/^\s*\\space//o;		# Hack - \space is inserted in .aux
392    s/$next_pair_pr_rx//o;
393    if ($cite_key = $2) {
394	local ($br_id)=$1;
395	$_ = join('',
396	    &do_cite_keys($br_id,$NUMERIC,
397		$optional1,'',($NUMERIC? $cite_par_mark : $citealt_full_mark)
398			  ,$cite_key), $_);
399    } else {print "Cannot find citation argument\n";}
400    $_;
401}
402
403sub do_cmd_citename {
404# "Jones et al."
405    local($_) = @_;
406    local($cite_key, @cite_keys);
407    local($optional1,$dummy)=&get_next_optional_argument;
408    s/^\s*\\space//o;		# Hack - \space is inserted in .aux
409    s/$next_pair_pr_rx//o;
410    if ($cite_key = $2) {
411	local ($br_id)=$1;
412	$_ = join('',
413	    &do_cite_keys($br_id,$NUMERIC,$optional1,'',
414		($NUMERIC ? $cite_par_mark : $cite_author_mark)
415		,$cite_key),$_);
416    }
417    else {print "Cannot find citation argument\n";}
418    $_;
419}
420
421sub do_cmd_citenamestar {
422# "Jones, Baker, and Williams"
423    local($_) = @_;
424    local($optional1,$dummy)=&get_next_optional_argument;
425    local($cite_key, @cite_keys);
426    s/^\s*\\space//o;		# Hack - \space is inserted in .aux
427    s/$next_pair_pr_rx//o;
428    if ($cite_key = $2) {
429	local ($br_id)=$1;
430	$_ = join('',
431	    &do_cite_keys($br_id,$NUMERIC,$optional1,'',
432		($NUMERIC ? $cite_par_mark :$cite_author_full_mark)
433		,$cite_key),$_);
434    }
435    else {print "Cannot find citation argument\n";}
436    $_;
437}
438
439sub do_cmd_harvardparenthesis {
440# Harvard command for customizing parentheses.
441# \harvardyearparenthesis is ignored, since natbib
442# doesn't distinguish the parentheses for citations
443# and parentheses for years
444    local ($_)=@_;
445    s/$next_pair_pr_rx//o;
446    local($arg)=$2;
447  SWITCH: {
448      $arg =~ /round/ && do {
449	  $CITE_OPEN_DELIM='(';
450	  $CITE_CLOSE_DELIM=')';
451	  last SWITCH};
452      $arg =~ /curly/ && do {
453	  $CITE_OPEN_DELIM='{';
454	  $CITE_CLOSE_DELIM='}';
455	  last SWITCH};
456      $arg =~ /square/ && do {
457	  $CITE_OPEN_DELIM='[';
458	  $CITE_CLOSE_DELIM=']';
459	  last SWITCH};
460      $arg =~ /angle/ && do {
461	  $CITE_OPEN_DELIM='&lt';
462	  $CITE_CLOSE_DELIM='&gt';
463	  last SWITCH};
464      $arg =~ /none/ && do {
465	  $CITE_OPEN_DELIM='';
466	  $CITE_CLOSE_DELIM='';
467	  last SWITCH};
468      print "\nInvalid argument to \\harvardparenthesis: $arg!\n"
469      }
470    $_;
471}
472
473## special subroutine definition for Harvard emulation
474#if ($HARVARD) {
475#
476#print "\nnatbib.perl: Operating in Harvard emulation mode.\n";
477
478# BRM: These should produce the year even in numeric mode.
479sub do_cmd_citeyear    {
480# "1990a"
481    do_cite_common($HARVARD,($HARVARD ? $cite_par_mark : $cite_year_mark), # BRM
482	$cite_year_mark,@_); }
483
484sub do_cmd_citeyearpar {
485# "(1990a)"
486    do_cite_common(1,$cite_year_mark,$cite_year_mark,@_); } # BRM
487
488# Does this command even exist?
489sub do_cmd_citeyearstar {
490# "1990a"
491    do_cite_common($NUMERIC,$cite_par_mark,$cite_year_mark,@_) }
492
493# Does this command even exist?
494sub do_cmd_citeyearparstar {
495# "(1990a)"
496    do_cite_common($NUMERIC,$cite_par_mark,$cite_year_mark,@_) }
497
498
499##End of special HARVARD definitions
500#} else {
501## citeyear syntax differs between natbib and harvard
502#print "\nnatbib.perl: Operating in natbib mode.\n";
503#
504#};
505
506# Citation commands specific for natbib
507
508sub do_cmd_citet {
509# Special citation style in natbib 6.x: Jones et al [21]
510# Except in numeric mode, acts like \cite (-> same marker)
511# In numeric mode, uses $cite_mark
512#    do_cite_common('',$cite_mark,$citet_mark,@_) }
513# BRM: actually, it should produce the same output except year -> reference #
514    do_cite_common('',$citet_mark,$citet_mark,@_) }
515
516sub do_cmd_citetstar {
517# Special citation style in natbib 6.x: Jones, Baker, and Williams [21]
518#    do_cite_common('',$cite_full_mark,$citet_full_mark,@_) }
519# BRM: actually, it should produce the same output except year -> reference #
520    do_cite_common('',$citet_full_mark,$citet_full_mark,@_) }
521
522sub do_cmd_citep {
523# Shortcut for parenthetical citation
524    do_cite_common(1,$cite_par_mark,$cite_par_mark,@_) }
525
526sub do_cmd_citepstar {
527# Shortcut for full parenthetical citation
528    do_cite_common(1,$cite_par_mark,$cite_par_full_mark,@_) }
529
530sub do_cmd_citealt {
531# Alternative form of citation: No punctuation between author and year
532#    i.e. "Jones et al. 1990"
533# First argument = $NUMERIC (In numeric mode, always use parentheses)
534# Same in the next subroutine
535#    do_cite_common($NUMERIC,$cite_par_mark,$citealt_mark,@_) }
536# BRM: actually, it should produce the same output except year -> reference #
537    do_cite_common(0,$citealt_mark,$citealt_mark,@_); }
538
539sub do_cmd_citealtstar {
540# Full alternative citation, i.e. "Jones, Baker, and Williams 1990"
541#    do_cite_common($NUMERIC,$cite_par_mark,$citealt_full_mark,@_) }
542# BRM: actually, it should produce the same output except year -> reference #
543    do_cite_common(0,$citealt_full_mark,$citealt_full_mark,@_); }
544
545sub do_cmd_citealp {
546# Alternative form of citation: like citep without parentheses
547#    i.e. "Jones et al., 1990"
548    do_cite_common(0,$cite_par_mark,$citealp_mark,@_) }
549
550sub do_cmd_citealpstar {
551# Full alternative citation, i.e. "Jones, Baker, and Williams, 1990"
552    do_cite_common(0,$cite_par_mark,$citealp_full_mark,@_) }
553
554sub do_cmd_citeauthor {
555# "Jones et al."
556    do_cite_common(0,$cite_author_mark,$cite_author_mark,@_) }
557
558sub do_cmd_citeauthorstar {   &do_cmd_citefullauthor(@_); }
559
560sub do_cmd_citefullauthor {
561# "Jones, Baker, and Williams"
562    do_cite_common(0,$cite_author_full_mark,$cite_author_full_mark,@_) }
563
564sub do_cite_common {
565# Common interface for citation commands taking two optional
566# arguments, except for \cite and \cite* which have special behavior
567# when no optional arguments are present
568    local($has_parens,$num_mark,$norm_mark,$_) = @_;
569    local($cite_key, @cite_keys);
570    local($has_optional,$optional1,$optional2)=&cite_check_options;
571    s/^\s*\\space//o;		# Hack - \space is inserted in .aux
572    if (s/$next_pair_pr_rx//) {
573	$cite_key = $2;
574	local ($br_id)=$1;
575	$_ = join(''
576	    , &do_cite_keys ($br_id, $has_parens, $optional1, $optional2
577		,($NUMERIC ? $num_mark : $norm_mark)
578		,$cite_key)
579	    , $_);
580    } else {print "Cannot find citation argument\n";}
581    $_;
582}
583
584
585sub cite_check_options {
586# Check if there's an optional argument (even if it's empty)
587# In this case, citation in parentheses is desired.
588# If Harvard syntax is selected, just look for one nonempty optional
589    if ($HARVARD) {
590	local($opt1,$dummy)=&get_next_optional_argument;
591# Always pretend there was an optional, since harvard \cite means
592# parenthetical citation
593	(1,$opt1,'')
594    } else {
595	local($hasopt) = (/^\s*\[([^]]*)\]/ && (! $`));
596# Look for two possible optional arguments
597        local($opt1,$dummy)= &get_next_optional_argument;
598        local($opt2,$dummy)= &get_next_optional_argument;
599# If optional Nr. 2 is present, exchange 1 and 2
600        if ($dummy) {
601	    ($opt1,$opt2) = ($opt2,$opt1);
602#        if ($opt2) {
603#            local($hopt)=$opt1;
604#	    $opt1=$opt2;
605#	    $opt2=$hopt;
606        };
607        ($hasopt,$opt1,$opt2)
608   }
609}
610
611sub do_cite_keys{
612# $hasopt indicates that citations should be enclosed in parentheses
613    local($br_id,$hasopt,$first,$second,$c_mark,$cite_key) = @_;
614    local(@cite_keys) = (split(/,/,$cite_key));
615    local ($multiple,$cite_anchor,$key,$extra);
616# Create index entries if desired
617    if (($CITEINDEX) && (! $NUMERIC)) {
618	foreach $key (@cite_keys) {$cite_anchor=&make_cite_index("$br_id",$key);};};
619# Is there more than 1 citation ?
620# If yes, the multiple citations are enclosed by $cite_multiple_mark's
621    if ($#cite_keys > 0){ $multiple = $cite_multiple_mark;}
622    else { $multiple = '';};
623    local($citauth)=($c_mark =~ /($cite_author_mark|$cite_author_full_mark)/);
624    $first = "$POST_NOTE $first" if ($first && !($HARVARD && $citauth));
625    grep ( do { &cite_check_segmentation($_);
626# MW: change 25.6.: throw out the reference to $bbl_mark.
627# The second pair of # remains empty unless we are in HARVARD mode
628# and have a single citation with optional text
629	if (($first && !$multiple) &&
630		(($HARVARD &&!$hasopt)||($c_mark =~ /citet/))) {
631	    $extra = $first; $first = '';
632	} else { $extra = '' }
633	$_ = "#$_#$c_mark#". $extra ."#";}
634#	$_ = "#$_#$c_mark#".(($HARVARD && (!$hasopt) && (!$multiple))? $first: "")."#";}
635	    , @cite_keys);
636    # Add parentheses and delimiters as appropriate
637    #
638    $second .= ' ' if ($second);
639    local($this_cite);
640    if ($hasopt) {
641	$this_cite = join('', $CITE_OPEN_DELIM, $second,$multiple
642	        , join($CITE_ENUM,@cite_keys)
643		, (($first&&($c_mark =~/^($citet_mark|$citet_full_mark)$/))?
644			$first.'#'.$citet_ext_mark.$multiple : $multiple.$first)
645		, $CITE_CLOSE_DELIM
646		);
647    } else {
648	$this_cite = join ('',$second,$multiple
649		, join($CITE_ENUM,@cite_keys)
650		, (($first&&($c_mark =~/^($citet_mark|$citet_full_mark)$/))?
651			$first.'#'.$citet_ext_mark.$multiple : $multiple.$first)
652		);
653    }
654    join ('',$cite_anchor,$this_cite);
655}
656
657sub make_cite_index {
658    local ($br_id,$cite_key) =@_;
659    local ($index_key)="$cite_short{$cite_key} ($cite_year{$cite_key})";
660    local ($sort_key)="$cite_short{$cite_key}$cite_year{$cite_key}$cite_key";
661#    local ($bib_label)="<A NAME=\"III${cite_key}\"<\/A>";
662    if (defined  &named_index_entry ) {
663	&named_index_entry($br_id,"$sort_key\@$index_key") }
664    elsif ($br_id > 0) {
665	&do_cmd_index("$OP$br_id$CP$index_key$OP$br_id$CP") }
666    else { $name++; &do_cmd_index("$OP$name$CP$index_key$OP$name$CP") }
667}
668
669sub parse_citeauthoryear {
670    local($_) = @_;
671    s/$comment_mark\d+.*\n//gs;		# Strip out darned EOL comments
672    s/\n//gs;		# Strip out darned EOL comments
673    my ($long,$short,$year);
674    s/^\\protect\\citeauthoryear//;
675    $long = &missing_braces unless (
676	(s/$next_pair_pr_rx/$long=$2;''/eo)
677	||(s/$next_pair_rx/$long=$2;''/eo));
678    $long =~ s/($O|$OP)(\d+)($C|$CP)($O|$OP)\2($C|$CP)//go; # Remove empty braces
679    $short = &missing_braces unless (
680	(s/$next_pair_pr_rx/$short=$2;''/eo)
681	||(s/$next_pair_rx/$short=$2;''/eo));
682    $short =~ s/($O|$OP)(\d+)($C|$CP)($O|$OP)\2($C|$CP)//go; # Remove empty braces
683    $year = &missing_braces unless (
684	(s/$next_pair_pr_rx/$year=$2;''/eo)
685	||(s/$next_pair_rx/$year=$2;''/eo));
686    $year =~ s/($O|$OP)(\d+)($C|$CP)($O|$OP)\2($C|$CP)//go; # Remove empty braces
687    ($long,$short,$year);
688}
689
690# Translate \citeauthoryear{long}{short}{year} form bibitems into form
691# Not actually used ...
692sub do_cmd_citeauthoryear {
693    local($_) = @_;
694    my ($long,$short,$year) = parse_citeauthoryear($_);
695    join('', "$short($year)$long",$_);
696}
697
698sub do_real_bibitem {
699# Process the \bibitem command.
700    local($thisfile, $_) = @_;
701    local ($tmp,$label);
702    $bbl_cnt++;
703    local($label, $dummy) = &get_next_optional_argument;
704    local($short, $year, $long, $supported);
705    # BRM: Add check to translate \citeuthordate formatted bibitems.
706    # (Mainly to avoid the `not supported' messages!
707    if ($label =~ /^\\protect\\citeauthoryear/) {
708	($long,$short,$year)=parse_citeauthoryear($label);
709	$supported=1;
710    } else {
711	# Check if label is of the natbib form ...(1994abc)...
712	$tmp = ($label =~ /([^\(]*)(\([^\)]*\))([\w\W]*)$/s);
713	($supported) = ($tmp && !($label =~ /\\protect/));
714	# Short name: before year, long name: after year
715	($short, $year, $long) = ($1,$2,($3 ? $3 : $1));
716    }
717
718# If numeric citation is chosen -> standard procedure
719    if (! $NUMERIC) { $year =~ s/[\(\)]//g; }
720    else { $label=++$bibitem_counter; };
721# BRM: parens should be removed in ANY case and put back only if needed
722    $year =~ s/[\(\)]//g;
723# Throw out brackets that may stem from 1990{\em a} or similar
724    $year =~ s/($O|$OP)\d+($C|$CP)//g;
725
726# The compulsory argument is the LaTeX label
727    $cite_key = &missing_braces unless (
728	(s/$next_pair_pr_rx/$cite_key=$2;''/eo)
729	||(s/$next_pair_rx/$cite_key=$2;''/eo));
730    $cite_key = &translate_commands($2);
731    if ($cite_key) {
732# remove tags resulting from excess braces
733	$tmp = $_;
734	$_ = $short;
735	s/$next_pair_pr_rx//o;
736	if (!($2 eq $cite_key))
737	    {$short =$2; $short =~ s/$OP[^\#>]*$CP//go; }
738	$_ = $long;
739	s/$next_pair_pr_rx//o;
740	if (!($2 eq $cite_key))
741	    {$long = $2; $long =~ s/$OP[^\#>]*$CP//go; }
742	$_ = "$tmp";
743# Three hashes are used to store the information for text citations
744	if ($supported) {
745	    $cite_short{$cite_key} = &translate_commands($short);
746	    $cite_year{$cite_key} = &translate_commands($year);
747	    $cite_long{$cite_key} = &translate_commands($long)}
748	else {
749	    &write_warnings(
750	"\n\\bibitem label format not supported, using \\bibcite information!");
751	}
752# Update the $ref_file entry, if necessary, making sure changes are saved.
753	if (!($ref_files{'cite_'."$cite_key"} eq $thisfile)) {
754	    $ref_files{'cite_'."$cite_key"} = $thisfile;
755	    $changed = 1; }
756	$citefiles{$cite_key} = $thisfile;
757# Create an anchor around the citation
758	$_=&make_cite_reference ($cite_key,$_);
759    } else {
760	#RRM: apply any special styles
761	$label = &bibitem_style($label) if (defined &bibitem_style);
762	print "Cannot find bibitem labels: $label\n";
763	$_=join('',"\n<DT>$label\n<DD>", $_);
764    }
765    $_;
766}
767
768sub make_cite_reference {
769# Make the anchor
770    local ($cite_key,$_)=@_;
771    local($label)=$cite_info{$cite_key};
772    local($next_lines, $after_lines);
773    local($sort_key, $indexdata);
774    if (defined  &named_index_entry ) { #  makeidx.perl  is loaded
775	$sort_key = "$cite_short{$cite_key}$cite_year{$cite_key}$cite_key";
776        $sort_key =~ tr/A-Z/a-z/;
777    } else {$sort_key = "$cite_short{$cite_key} ($cite_year{$cite_key})";}
778    if ($index{$sort_key}) {
779# append the index entries as a list of citations
780	$indexdata = $index{$sort_key};
781	$indexdata =~ s/[\|] $//;
782	$indexdata = join('',"\n<DD>cited: ", "$indexdata");
783# Create index entry to the Bibliography entry only, if desired
784	$index{$sort_key} = '';
785	if ($CITEINDEX) { &make_cite_index("$cite_key",$cite_key);}
786	elsif (defined  &named_index_entry ) {$printable_key{$sort_key} = '';}
787    } else { $indexdata = '';}
788    $indexdata .= "\n<P>";
789
790    local ($found) = /(\\bibitem|\\harvarditem)/o;
791    if ($found) { $after_lines = $&.$'; $next_lines = $`;}
792    else { $after_lines = ''; $next_lines = $_;}
793    $next_lines .= $indexdata;
794    $indexdata = '';
795    $_ = $next_lines.$after_lines;
796
797    if ($NUMERIC) {
798	#RRM: apply any special styles
799	if (defined &bibitem_style) {
800	    $label = &bibitem_style($label);
801	} else {
802	    $label = '<STRONG>'.$label.'</STRONG>';
803	};
804	join('',"\n<DT><A NAME=\"$cite_key\">$label</A>\n<DD>",$_);
805    } else {
806# For Author-year citation: Don't print the label to the bibliography
807# Use the first line of the bib entry as description title instead
808# First line ends with \newblock or with the next \bibitem  command
809#	$found = /\\newblock/o;	# these have been converted to  <BR>s
810	$found = /\<BR\>/o;
811	local($nbefore,$nafter) = ($`,$');
812	if ($found) {
813	    if (defined &bibitem_style) {
814		$nbefore = &bibitem_style($nbefore);
815	    } elsif ($nbefore =~/\\/) {
816		$nbefore = &translate_commands($nbefore);
817	    } else {
818		$nbefore = join('','<STRONG>',$nbefore,'</STRONG>');
819	    }
820	    join('',"\n<DT><A NAME=\"$cite_key\">", $nbefore
821		 , "</A>\n<DD>", &translate_commands($nafter));
822	} else {
823	    $found= /(\\bibitem|\\harvarditem)/o;
824	    if ($found) {
825		local($nbefore,$nafter) = ($`,$');
826		if (defined &bibitem_style) {
827		    $nbefore = &bibitem_style($nbefore);
828		} elsif ($nbefore =~/\\/) {
829		    $nbefore = &translate_commands($nbefore);
830		} else {
831		    $nbefore = join('','<STRONG>',$nbefore,'</STRONG>');
832		}
833#		print "\nBIBITEM:$nafter";
834#		$nafter =~ s/\s*<P>\s*<BR>\s*<P>\s*$/\n/s;
835		join('',"\n<DT><A NAME=\"$cite_key\">", $nbefore
836		    ,"</A>\n<DD>", $nafter );
837# No call to &translate_commands on $': Avoid recursion
838	    } else {
839		if (defined &bibitem_style) {
840		    $_ = &bibitem_style($_);
841		} elsif ($_ =~ /\\/) {
842		    $_ = &translate_commands($_);
843		} else {
844		    $_ = join('','<STRONG>',$_,'</STRONG>');
845		}
846		# remove extraneous space between items
847		join('',"\n<DT><A NAME=\"$cite_key\">", $_,"</A>\n<DD>",' ');
848	    };
849	};
850    }
851}
852
853if (!(defined &do_cmd_harvarditem)) {
854    eval 'sub do_cmd_harvarditem { &do_real_harvarditem($CURRENT_FILE, @_) }';
855} else {
856    print "\n *** sub do_cmd_harvarditem  is already defined. ***\n"
857}
858sub do_real_harvarditem {
859# natbib.sty also reads files created by harvard bibstyles
860# (harvard, kluwer, ...)
861    local ($thisfile,$_)=@_;
862    local ($dum,$short)=&get_next_optional_argument;
863    $short =~ s/[\[\]]//g;
864    $bbl_cnt++;
865# Get full citation text
866    s/$next_pair_pr_rx//o; local ($long)=$2;
867# Get year
868    s/$next_pair_pr_rx//o; local ($year)=$2;
869    $year =~ s/<#\d+#>//g;
870# Get the key
871    s/$next_pair_pr_rx//o; local ($cite_key)=$2;
872    if ($cite_key) {
873	if (!($short)) {$short=$long};
874# remove tags resulting from excess braces
875	local($tmp) = $_;
876	$_ = $short;
877	s/$next_pair_pr_rx//o;
878	if (!($2 eq $cite_key))
879	    {$short =$2; $short =~ s/<\#[^\#>]*\#>//go; };
880	$_ = $long;
881	s/$next_pair_pr_rx//o;
882	if (!($2 eq $cite_key))
883	    {$long = $2; $long =~ s/<\#[^\#>]*\#>//go; };
884	$_ = "$tmp";
885# Three hashes are used to store the information for text citations
886        $cite_short{$cite_key} = &translate_commands($short);
887        $cite_year{$cite_key} = &translate_commands($year);
888        $cite_long{$cite_key} = &translate_commands($long);
889# Update the $ref_file entry, if necessary, making sure changes are saved.
890# $citefile is set by  do_env_thebibliography
891#	$citefiles{$cite_key} = $citefile;
892	if (!($ref_files{'cite_'."$cite_key"} eq $thisfile)) {
893	    $ref_files{'cite_'."$cite_key"} = $thisfile;
894	    $changed = 1; }
895	$citefiles{$cite_key} = $thisfile;
896	&make_harvard_reference ($cite_key,$year,$_);
897    } else {
898	#RRM: apply any special styles
899	$label = &bibitem_style($label) if (defined &bibitem_style);
900	print "Cannot find bibitem labels: $label\n";
901	join('',"\n<DT><STRONG>$label</STRONG>\n<DD>", $_);
902    }
903}
904
905sub make_harvard_reference {
906# Almost the same as &make_cite_reference.
907    local ($cite_key,$year,$_)=@_;
908    local($label)=$cite_info{$cite_key};
909    local($next_lines, $after_lines);
910    local($sort_key, $indexdata);
911    if (defined  &named_index_entry ) { #  makeidx.perl  is loaded
912	$sort_key = "$cite_short{$cite_key}$cite_year{$cite_key}$cite_key";
913        $sort_key =~ tr/A-Z/a-z/;
914    } else {$sort_key = "$cite_short{$cite_key} ($cite_year{$cite_key})";}
915    if ($index{$sort_key}) {
916# append the index entries as a list of citations
917	$indexdata = $index{$sort_key};
918	$indexdata =~ s/[\|] $//;
919	$indexdata = join('',"\n<DD>cited: ", "$indexdata");
920# Create index entry to the Bibliography entry only, if desired
921	$index{$sort_key} = '';
922	if ($CITEINDEX) { &make_cite_index("$cite_key",$cite_key);}
923	elsif (defined  &named_index_entry ) {$printable_key{$sort_key} = '';}
924    } else { $indexdata = '';}
925    $indexdata .= "\n<P>";
926    local ($found) = /(\\bibitem|\\harvarditem)/o;
927    if ($found) { $after_lines = $&.$'; $next_lines = $`;}
928    else { $after_lines = ''; $next_lines = $_;}
929    $next_lines .= $indexdata;
930    $indexdata = '';
931    $_ = $next_lines.$after_lines;
932    if ($NUMERIC) {
933	#RRM: apply any special styles
934	$label = &bibitem_style($label) if (defined &bibitem_style);
935	join('',"\n<DT><A NAME=\"$cite_key\"><STRONG>$label</STRONG></A>\n<DD>",$_);
936    } else {
937# For Author-year citation: Don't print the label to the bibliography
938# Difference to &make_cite_reference:
939# \newblocks are not be used, so use the year stored in $year as delimiter
940# for the first line
941#	local ($found)= /$year([.:;,\s\)\]\!\?\}]|\\harvardyearright)*/s;
942# Extract the numeric part of the year, to avoid confusion by 1991{\em b} or similar
943	$year =~ /\d+/;
944	local($numyear) = $&;
945# Look for the year followed by anything and a punctuation character or newline
946	local ($found)= /$numyear(.*?)[.,:;\n]/s;
947	if ($found) {
948	    join('',"\n<DT><A NAME=\"$cite_key\"><STRONG>",
949		 &translate_commands($`.$&),"</STRONG></A>\n<DD>",
950# No call to &translate_commands on $': Avoid recursion
951		 $')
952	} else {
953	    $found= /(\\bibitem|\\harvarditem)/o;
954	    if ($found) {
955		join('',"\n<DT><A NAME=\"$cite_key\"><STRONG>",
956		     &translate_commands($`),"</STRONG></A>\n<DD>",
957# No call to &translate_commands on $': Avoid recursion
958		     $');
959	    } else {
960		join('',"\n<DT><A NAME=\"$cite_key\"><STRONG>",
961		     &translate_commands($_),"</STRONG></A>\n<DD>",' ');
962	    };
963	};
964    }
965}
966
967sub do_cmd_harvardand {
968    &translate_commands("$HARVARDAND".$_[0]);
969}
970sub do_cmd_harvardleft {
971    &translate_commands("$CITE_OPEN_DELIM".$_[0]);
972}
973sub do_cmd_harvardright {
974    &translate_commands("$CITE_CLOSE_DELIM".$_[0]);
975}
976sub do_cmd_harvardyearleft {
977    &translate_commands("$CITE_OPEN_DELIM".$_[0]);
978}
979sub do_cmd_harvardyearright {
980    &translate_commands("$CITE_CLOSE_DELIM".$_[0]);
981}
982sub do_cmd_harvardurl{
983    local($_) = @_;
984    local($text, $url, $href);
985    local($name, $dummy) = &get_next_optional_argument;
986    $url = &missing_braces unless (
987	(s/$next_pair_pr_rx/$url = $2;''/eo)
988	||(s/$next_pair_rx/$url = $2;''/eo));
989    $url = &translate_commands($url) if ($url=~/\\/);
990    $text = "<b>URL:</b> ".$url;
991    if ($name) { $href = &make_named_href($name,$url,$text) }
992    else { $href = &make_href($url,$text) }
993    print "\nHREF:$href" if ($VERBOSITY > 3);
994    $_ =~ s/^[ \t]*\n?/\n/;
995    join ('',$href,$_);
996}
997
998sub do_cmd_bibcite {
999# !! This routine reads bibcite commands produced by natbib 6.0 or later !!
1000# It is used to build the citation information
1001# (hash tables %cite_info, %cite_short, %cite_long, %cite_year)
1002    local($_) = @_;
1003	# extract the key
1004    s/$next_pair_pr_rx//o;
1005    local($br_id, $cite_key) = ($1, $2);
1006	# next group is the information
1007#    $cite_key =~ s/\W//g;
1008    s/$next_pair_pr_rx//o;
1009    local($br_id, $print_key) = ($1, $2);
1010    local($rest) = "$_";
1011    $_ = $print_key;
1012	# first is the numeric value...
1013    s/$next_pair_pr_rx//o;
1014    ($br_id, $print_key) = ($1, $2);
1015    $print_key =~ s/<\#[^\#>]*\#>//go;
1016# Complain if no label is found: This is not a proper natbib \bibcite command
1017    print ("\nWARNING: natbib.perl: no valid citation key found in \bibitem.",
1018	   "\n    Perhaps you are running a natbib.sty version earlier than 6.x?",
1019	   "\n    Unable to generate citation references correctly.\n")
1020	if (! $print_key);
1021    $cite_info{$cite_key} = &translate_commands($print_key);
1022	# then comes the year
1023    s/$next_pair_pr_rx//o;
1024    ($br_id, $print_key) = ($1, $2);
1025    $print_key =~ s/<\#[^\#>]*\#>//go;
1026    $cite_year{$cite_key} = &translate_commands($print_key);
1027# then the short citation
1028    s/$next_pair_pr_rx//o;
1029    ($br_id, $print_key) = ($1, $2);
1030    $print_key =~ s/<\#[^\#>]*\#>//go;
1031    $cite_short{$cite_key} = &translate_commands($print_key);
1032	# then the long citation
1033    s/$next_pair_pr_rx//o;
1034    ($br_id, $print_key) = ($1, $2);
1035    $print_key =~ s/<\#[^\#>]*\#>//go;
1036    if ($print_key) {
1037	$cite_long{$cite_key} = &translate_commands($print_key);}
1038    else {$cite_long{$cite_key}=$cite_short{$cite_key}};
1039# Switch to numeric mode if author or year is undefined
1040# (this happens if natbib.sty is used with a numerical bibstyle like
1041# "plain.bst")
1042    $NUMERIC=($NUMERIC ||
1043	      (! $cite_short{$cite_key}) ||
1044	      (! $cite_year{$cite_key}));
1045    # just in case anything is left over...
1046    $rest;
1047}
1048
1049sub do_cmd_harvardcite {
1050# This is used to build the citation information
1051# (hash tables %cite_info, %cite_short, %cite_long, %cite_year)
1052# from \harvardcite commands produced by the harvard package.
1053    local($_) = @_;
1054	# extract the key
1055    s/$next_pair_pr_rx//o;
1056    local($br_id, $cite_key) = ($1, $2);
1057	# next group is the long citation
1058    s/$next_pair_pr_rx//o;
1059    $cite_long{$cite_key}=&translate_commands($2);
1060	# next group is the short citation
1061    s/$next_pair_pr_rx//o;
1062    $cite_short{$cite_key}=&translate_commands($2);
1063	# next group is the year
1064    s/$next_pair_pr_rx//o;
1065    $cite_year{$cite_key}=&translate_commands($2);
1066    $cite_year{$cite_key} =~ s/<#\d+#>//g;
1067    $_;
1068}
1069
1070# Now come to the correct replacements for all citation styles.
1071# Text is assembled from the
1072# $cite_short, $cite_year, and $cite_long hash tables
1073sub replace_cite_references_hook {
1074    local($target) = 'contents';
1075# Handle multiple citations first!
1076    if (/$cite_multiple_mark/) {&replace_multiple_cite_references };
1077    &replace_nat_cite_references if
1078/$cite_mark|$cite_full_mark|$cite_year_mark|$cite_par_mark|$cite_par_full_mark|$cite_author_mark|$cite_author_full_mark|$citealt_mark|$citealt_full_mark|$citealp_mark|$citealp_full_mark|$citet_mark|$citet_full_mark/;
1079}
1080
1081sub replace_multiple_cite_references {
1082# Look for $cite_multiple_mark pairs
1083    local($saved) = $_ ;
1084    while (s/$cite_multiple_mark(.*?)$cite_multiple_mark/&do_multiple_citation($1)/se) {
1085	last if ($_ eq $saved);
1086	$saved = $_;
1087    };
1088    undef $saved;
1089}
1090
1091sub do_multiple_citation {
1092    local($cit)=@_;
1093    local($before_year,$after_year);
1094    local($author,$thisyear,$lastyear,$lastauth,$theauth,$year);
1095    local($thetext,$lasttext,$thekey,$lastkey);
1096    local($mark,$key,$extra,$citet_ext,%second,@sorted);
1097    local($useindex) = $NUMERIC;
1098# Clear arrays & hash tables
1099    undef %second;
1100    undef @sorted;
1101# Construct hash table with the labels of the multiple citation as keys
1102# (Values of hash %second are actually unimportant)
1103    while ($cit =~
1104# BRM +)* ??? Perl got hung up here!
1105#	s/#([^#]+)#(<tex2html_cite\w*_mark>)#([^#]*)#($CITE_ENUM)?(($OP|$CP|[^#]+)*#$citet_ext_mark)?//) {
1106	s/#([^#]+)#(<tex2html_cite\w*_mark>)#([^#]*)#($CITE_ENUM)?((($OP|$CP|[^#])*)#$citet_ext_mark)?//) {
1107	$mark=$2;
1108	$extra=$3;
1109	$citet_ext = $6 if (($mark eq $citet_mark)||($mark eq $citet_full_mark));
1110	($key=$1) =~ s/[\s]//g;
1111	%second=(%second,$key,$extra.$citet_ext);
1112     };
1113
1114#     if ($NUMERIC) {
1115# BRM: Actually, \citet can give textual entries too, so do it the hard way.
1116if (0){
1117# Numerical Citation: normal procedure
1118# sort the entries in ascending bibliographic order
1119# DO WE REALLY WANT THIS ??
1120#	@sorted=sort {$cite_info{$a} cmp $cite_info{$b}} (keys (%second));
1121# BRM: No not in general.
1122	@sorted = keys (%second);
1123	@sorted=sort {$cite_info{$a} cmp $cite_info{$b}} @sorted if $SORT_MULTIPLE;
1124	$_=join($CITE_ENUM,
1125# make_href is used for anchor creation!
1126		map { &make_href("$citefiles{$_}#$_","$cite_info{$_}");}
1127		@sorted);
1128    } else {
1129# Author-year citation
1130# Different punctuation for parenthetical, normal, and alternative
1131# Author-year citation
1132# citations (\cite[] or \citep, \cite, and \citealt resp. starred versions)
1133
1134      SWITCH:	{
1135	# Parenthetical type (\cite[],\citep)
1136	$mark =~ /^$cite_par_mark|$cite_par_full_mark/ && do {
1137	    if ($NUMERIC) {
1138		($before_year,$after_year)=('','');
1139	    } else {
1140		($before_year,$after_year)=($BEFORE_PAR_YEAR,'');
1141	    }
1142	    last SWITCH;};
1143
1144	# normal type (\cite)
1145	$mark =~ /^$cite_mark|$cite_full_mark/ && do {
1146	      ($before_year,$after_year)=
1147		  (" $CITE_OPEN_DELIM","$CITE_CLOSE_DELIM");
1148	      last SWITCH;};
1149
1150	# normal-t type (\citet)
1151	# optional arg goes inside parens; how to do this ?
1152	$mark =~ /^$citet_mark|$citet_full_mark/ && do {
1153              ($before_year,$after_year) =
1154		  (" $CITE_OPEN_DELIM","$CITE_CLOSE_DELIM");
1155              last SWITCH;};
1156
1157	# alternative type (\citealp)
1158	$mark =~ /^$citealp_mark|$citealp_full_mark/ && do {
1159              ($before_year,$after_year)=($BEFORE_PAR_YEAR,'');
1160              last SWITCH;};
1161
1162	$mark =~ /^$cite_year_mark/ && do {
1163	    ($before_year,$after_year)=(' ','');
1164	    $useindex=0;
1165	    last SWITCH;};
1166
1167	# alternative type (\citealt)
1168	  ($before_year,$after_year)=(' ','');
1169	}
1170
1171# Reference $author is set to %cite_long if full author name citation is
1172# requested, to  %cite_short otherwise
1173	if ($NUMERIC && $mark =~ /^$cite_par_mark|$cite_par_full_mark/) { # BRM
1174	    $author='';
1175	} elsif ($mark =~
1176    /^$cite_par_full_mark|$cite_full_mark|$citet_full_mark|$citealt_full_mark|$citealp_full_mark|$cite_author_full_mark/)
1177		{ $author=\%cite_long;
1178	} else { $author=\%cite_short; }
1179# Sort the citation list according to author and year fields
1180#   => only subsequent entries must be compared afterwards.
1181# The citations are always sorted in ascending alphabetic order!
1182# DO WE REALLY WANT THIS ??
1183# BRM: No, not generally.
1184	@sorted = keys (%second);
1185	@sorted = sort {$$author{$a}.$cite_year{$a} cmp $$author{$b}.$cite_year{$b}}
1186		@sorted if $SORT_MULTIPLE;
1187# First entry
1188	$lastkey=shift(@sorted);
1189	($lastauth,$lastyear)=($$author{$lastkey},$cite_year{$lastkey});
1190	$lasttext=join(''
1191		, (($mark =~ /$cite_year_mark/)? '' : $$author{$lastkey})
1192		, (($mark =~ /$cite_author_mark|$cite_author_full_mark/)? ''
1193			: $before_year
1194		   . ($useindex ? $cite_info{$lastkey}:$cite_year{$lastkey})) # BRM
1195		, $second{$lastkey}
1196		);
1197	$_='';
1198# The text for the entry can only be written to $_ AFTER the next entry
1199# was analyzed (different punctuation whether next entry has the same authors
1200# or not!)
1201#
1202# iterate through the other entries
1203	while ($thekey=shift(@sorted)) {
1204	    ($theauth,$theyear)=($$author{$thekey},
1205		 ($useindex ? $cite_info{$thekey}:$cite_year{$thekey})); # BRM
1206	    if ($lastauth eq $theauth) {
1207# If authors are the same as last entry: suppress printing
1208# author information
1209# Truncate last year field to numeric part ("1994", usually)
1210		$lastyear =~ /^\d+/;
1211		$year=$&;
1212# If year is equal to that of last entry, keep only additional info
1213# I.e. 1994a, 1994b -> 1994a,b
1214		$thetext=($theyear =~ /^$year/ ? $' : ' '.$theyear);
1215# This line is for bibstyles that don't distinguish articles with
1216# common author list & year by appending letters (1990a, 1990b)
1217# In this case, $thetext might be empty after execution of the last line
1218		$thetext=' '.$theyear unless ($thetext);
1219# At this point, the PRECEDING entry may be written to $_
1220# Note use of &make_href.
1221		$_=join('',
1222			$_,
1223			&make_href("$citefiles{$lastkey}#$lastkey",
1224				   $lasttext),
1225			$COMMON_AUTHOR_SEP);
1226	    } else {
1227# New author(s): new list entry
1228# The last entry needs an $after year character (e.g., ")"), since it's
1229# the last one in a series of articles by common authors
1230# This character should go into the anchor text.
1231		$lasttext=$lasttext.$after_year;
1232# The new entry will be printed out completely
1233		$thetext=join(''
1234		, (($mark =~ /$cite_year_mark/)? '' : $$author{$thekey})
1235		, (($mark =~ /$cite_author_mark|$cite_author_full_mark/)? ''
1236		: $before_year
1237		    . ($useindex ? $cite_info{$thekey}:$cite_year{$thekey})) # BRM
1238		, $second{$thekey}
1239		);
1240# Write the preceding entry
1241		$_=join('',
1242			$_,
1243			&make_href("$citefiles{$lastkey}#$lastkey",
1244				   $lasttext),
1245			$CITE_ENUM);
1246	    };
1247# Shift last entry
1248	    ($lastkey,$lastauth,$lastyear,$lasttext)=
1249		($thekey,$theauth,$theyear,$thetext);
1250	};
1251# write the last entry of the list
1252	$_=join('',$_,
1253		&make_href("$citefiles{$lastkey}#$lastkey",
1254			   $lasttext.$after_year));
1255    };
1256    $_;
1257}
1258
1259sub replace_nat_cite_references {
1260# Modifies $_
1261# Uses $citefile set by the thebibliography environment
1262# Creates hyperrefs EXCLUSIVELY by calling &make_href
1263# Note that %citefile is indexed by the latex label ($1) rather than $bbl_nr ($2)
1264# MW 25.6.96: second pair of #'s may now be empty!
1265    local($savedRS) = $/; $/='';
1266    if ($NUMERIC) {
1267	s/#([^#]+)#$cite_par_mark#([^#]*)#/&make_named_href(""
1268		,"$citefiles{$1}#$1",$cite_info{$1})/ge;
1269	s/#([^#]+)#$cite_mark#([^#]*)#/&make_named_href(""
1270		,"$citefiles{$1}#$1"
1271		,"$cite_short{$1} $CITE_OPEN_DELIM"."$cite_info{$1}$CITE_CLOSE_DELIM")/ge;
1272	s/#([^#]+)#$cite_full_mark#([^#]*)#/&make_named_href("","$citefiles{$1}#$1"
1273		,"$cite_long{$1} $CITE_OPEN_DELIM"."$cite_info{$1}$CITE_CLOSE_DELIM")/ge;
1274	# BRM: These next several patterns should also appear in numeric mode.
1275	s/#([^#]+)#$cite_year_mark#([^#]*)#/&make_named_href("","$citefiles{$1}#$1"
1276		,"$cite_year{$1}$2")/ge;
1277	s/#([^#]+)#$cite_author_mark#([^#]*)#/&make_named_href("","$citefiles{$1}#$1"
1278		,"$cite_short{$1}".($2? " $CITE_OPEN_DELIM$2$CITE_CLOSE_DELIM": ""))/ge;
1279	s/#([^#]+)#$cite_author_full_mark#([^#]*)#/&make_named_href("","$citefiles{$1}#$1"
1280		,"$cite_long{$1}".($2? " $CITE_OPEN_DELIM$2$CITE_CLOSE_DELIM": ""))/ge;
1281	# The main (only?) difference between these & their non-numeric counterparts is
1282	# that the $cite_year is replaced by $cite_info (the reference number)
1283	s/#([^#]+)#$citet_mark#([^#]*)#((($OP|$CP|[^#\n])*)#$citet_ext_mark)?/
1284	    &make_named_href(""
1285		, "$citefiles{$1}#$1"
1286			     # BRM: Modified to include delimiters and PRE-text
1287		, join(''
1288		    ,"$cite_short{$1} $CITE_OPEN_DELIM$cite_info{$1}$2"
1289		    , ($3 ? $BEFORE_PAR_YEAR.$4 : ''), $CITE_CLOSE_DELIM)
1290	 	)
1291	/ge;
1292	s/#([^#]+)#$citet_full_mark#([^#]*)#((($OP|$CP|[^#\n])*)#$citet_ext_mark)?/
1293	    &make_named_href(""
1294		, "$citefiles{$1}#$1"
1295			     # BRM: Modified to include delimiters around year & pretext.
1296		, join(''
1297		    ,"$cite_long{$1} $CITE_OPEN_DELIM$cite_info{$1}$2"
1298		    , ($3 ? $BEFORE_PAR_YEAR.$3 : ''), $CITE_CLOSE_DELIM)
1299		)
1300	/ge;
1301	s/#([^#]+)#$citealt_mark#([^#]*)#/&make_named_href(""
1302		,"$citefiles{$1}#$1","$cite_short{$1} $cite_info{$1}")/ge;
1303	s/#([^#]+)#$citealt_full_mark#([^#]*)#/&make_named_href(""
1304		,"$citefiles{$1}#$1","$cite_long{$1} $cite_info{$1}")/ge
1305    } else {
1306# MW 25.6.96: use $2 eventually as optional text for harvard citations
1307	s/#([^#]+)#$cite_mark#([^#]*)#/&make_named_href("","$citefiles{$1}#$1"
1308		,"$cite_short{$1} ". "$CITE_OPEN_DELIM$cite_year{$1}$2$CITE_CLOSE_DELIM")/ge;
1309	s/#([^#]+)#$cite_full_mark#([^#]*)#/&make_named_href("","$citefiles{$1}#$1"
1310		,"$cite_long{$1} "."$CITE_OPEN_DELIM$cite_year{$1}$2$CITE_CLOSE_DELIM")/ge;
1311	if ($HARVARD) {
1312# in HARVARD mode, $citealt_mark stands for \possessivecite commands
1313	    s/#([^#]+)#$citealt_mark#([^#]*)#/&make_named_href(""
1314		,"$citefiles{$1}#$1"
1315		,"$cite_short{$1}\'s "."$CITE_OPEN_DELIM$cite_year{$1}$2$CITE_CLOSE_DELIM")/ge;
1316	    s/#([^#]+)#$citealt_full_mark#([^#]*)#/&make_named_href("","$citefiles{$1}#$1"
1317		,"$cite_long{$1}\'s "."$CITE_OPEN_DELIM$cite_year{$1}$2$CITE_CLOSE_DELIM")/ge
1318	} else {
1319# in usual natbib mode, it stands for \citealt commands
1320	    s/#([^#]+)#$citealt_mark#([^#]*)#/&make_named_href(""
1321		,"$citefiles{$1}#$1","$cite_short{$1} $cite_year{$1}")/ge;
1322	    s/#([^#]+)#$citealt_full_mark#([^#]*)#/&make_named_href(""
1323		,"$citefiles{$1}#$1","$cite_long{$1} $cite_year{$1}")/ge
1324	}
1325	s/#([^#]+)#$citealp_mark#([^#]*)#/&make_named_href(""
1326		,"$citefiles{$1}#$1","$cite_short{$1}$BEFORE_PAR_YEAR$cite_year{$1}")/ge;
1327	s/#([^#]+)#$citealp_full_mark#([^#]*)#/&make_named_href(""
1328		,"$citefiles{$1}#$1","$cite_long{$1}$BEFORE_PAR_YEAR$cite_year{$1}")/ge;
1329# BRM: Somehow the +)* hangs up perl!!!
1330#	s/#([^#]+)#$citet_mark#([^#]*)#(($OP|$CP|[^#\n]+)*#$citet_ext_mark)?/
1331# This works
1332	s/#([^#]+)#$citet_mark#([^#]*)#((($OP|$CP|[^#\n])*)#$citet_ext_mark)?/
1333	    &make_named_href(""
1334		, "$citefiles{$1}#$1"
1335			     # BRM: Modified to include delimiters and PRE-text
1336		, join(''
1337		    ,"$cite_short{$1} $CITE_OPEN_DELIM$cite_year{$1}$2"
1338		    , ($3 ? $BEFORE_PAR_YEAR.$4 : ''), $CITE_CLOSE_DELIM)
1339	 	)
1340	/ge;
1341# BRM: Somehow the +)* hangs up perl!!!
1342#	s/#([^#]+)#$citet_full_mark#([^#]*)#(($OP|$CP|[^#\n]+)*#$citet_ext_mark)?/
1343	s/#([^#]+)#$citet_full_mark#([^#]*)#((($OP|$CP|[^#\n])*)#$citet_ext_mark)?/
1344	    &make_named_href(""
1345		, "$citefiles{$1}#$1"
1346			     # BRM: Modified to include delimiters around year.
1347		, join(''
1348		    ,"$cite_long{$1} $CITE_OPEN_DELIM$cite_year{$1}$2"
1349		    , ($3 ? $BEFORE_PAR_YEAR.$4 : ''), $CITE_CLOSE_DELIM)
1350		)
1351	    /ge;
1352	s/#([^#]+)#$cite_par_mark#([^#]*)#/&make_named_href("",
1353		"$citefiles{$1}#$1","$cite_short{$1}$BEFORE_PAR_YEAR$cite_year{$1}")/ge;
1354	s/#([^#]+)#$cite_par_full_mark#([^#]*)#/&make_named_href("",
1355		"$citefiles{$1}#$1","$cite_long{$1}$BEFORE_PAR_YEAR$cite_year{$1}")/ge;
1356	s/#([^#]+)#$cite_year_mark#([^#]*)#/&make_named_href("","$citefiles{$1}#$1"
1357		,"$cite_year{$1}$2")/ge;
1358	s/#([^#]+)#$cite_author_mark#([^#]*)#/&make_named_href("","$citefiles{$1}#$1"
1359		,"$cite_short{$1}".($2? " $CITE_OPEN_DELIM$2$CITE_CLOSE_DELIM": ""))/ge;
1360	s/#([^#]+)#$cite_author_full_mark#([^#]*)#/&make_named_href("","$citefiles{$1}#$1"
1361		,"$cite_long{$1}".($2? " $CITE_OPEN_DELIM$2$CITE_CLOSE_DELIM": ""))/ge;
1362    }
1363    $/ = $savedRS;
1364}
1365
1366sub cite_check_segmentation {
1367    local($c_key)=@_;
1368# This is based on code by Ross Moore
1369# Important for file segments
1370# It sets $citefile from the hash $ref_files:
1371    if  ($ref_files{"cite_$c_key"})  {
1372	$citefiles{$c_key} = $ref_files{"cite_$c_key" };
1373    };
1374## or $external_labels:   not needed (RRM)
1375# elsif  ($external_labels{"cite_$c_key"}) {
1376#	$citefiles{$c_key} = $external_labels{"cite_$c_key" };};
1377    $citefiles{$c_key};
1378}
1379
1380sub do_env_thebibliography {
1381    # Sets $citefile and $citations defined in translate
1382    # gives a nicely formatted .html file --- RRM
1383    local($_) = @_;
1384    $bibitem_counter = 0;
1385    $citefile = $CURRENT_FILE;
1386    $citefiles{$bbl_nr} = $citefile;
1387    s/$next_pair_rx//o;
1388#    s/^\s*$//g;	# Remove empty lines (otherwise will have paragraphs!)
1389#    s/\n//g;	# Remove all \n s --- we format the HTML file ourselves.
1390#    $* = 0;			# Multiline matching OFF
1391    s/\\newblock/\<BR\>/gm;	# break at each \newblock
1392    s/\\penalty\d+//mg;		# Remove \penalty declarations
1393
1394    local($this_item,$this_kind, $title);
1395    # skip to the first bibliography entry
1396    s/\\(bibitem|harvarditem)/$this_kind=$1;''/eo;
1397    $_ = $';
1398#    $citations = join('',"\n<DL COMPACT>",
1399#		&translate_commands(&translate_environments($_)),"\n</DL>");
1400    local(@bibitems) = split(/\\(bib|harvard)item/, $_);
1401    while (@bibitems) {
1402	$this_item = shift (@bibitems);
1403	# remove extraneous space due to blank lines between items
1404	$this_item =~ s/$par_rx\s*$/\n/;
1405	$this_item = &translate_environments("\\$this_kind $this_item\\newblock");
1406	$citations .= &translate_commands($this_item);
1407	last unless  (@bibitems);
1408	$this_kind = shift (@bibitems).'item';
1409    }
1410    $citations = join('',"\n<DL COMPACT>",$citations,"\n</DL>");
1411    $citations{$bbl_nr} = $citations;
1412    if (defined &do_cmd_bibname) {
1413	$title = &translate_commands('\bibname');
1414    } else { $title = $bib_title }
1415    $_ = join('','<P>' , "\n<H2><A NAME=\"SECTIONREF\">"
1416	      , "$title</A>\n</H2>\n$bbl_mark#$bbl_nr#");
1417    $bbl_nr++ if $bbl_cnt > 1;
1418    $_;
1419}
1420
1421sub do_cmd_bibpunct {
1422    local($_) = @_;
1423# six arguments
1424    local($post, $dummy) = &get_next_optional_argument;
1425    $POST_NOTE=$post." " if ($post);
1426    s/$next_pair_pr_rx//o;
1427    $CITE_OPEN_DELIM=$2;
1428    s/$next_pair_pr_rx//o;
1429    $CITE_CLOSE_DELIM=$2;
1430    s/$next_pair_pr_rx//o;
1431    $CITE_ENUM=$2." " if ($2);
1432    s/$next_pair_pr_rx//o;
1433    local($style)=$2;
1434    $NUMERIC=($style =~ /[ns]/);
1435    s/$next_pair_pr_rx//o;
1436    $BEFORE_PAR_YEAR=$2." " if ($2);
1437    s/$next_pair_pr_rx//o;
1438    $COMMON_AUTHOR_SEP=$2;
1439    $_;
1440}
1441
1442sub do_cmd_citeindexfalse {
1443    $CITEINDEX=0; $_[0];
1444}
1445
1446sub do_cmd_citeindextrue {
1447    $CITEINDEX=1; $_[0];
1448}
1449
1450sub do_cmd_citestyle {
1451    local($_) = @_;
1452    s/$next_pair_pr_rx//o;
1453    local($style)="citestyle_$2";
1454    if (defined @$style) {
1455	($CITE_OPEN_DELIM,
1456	 $CITE_CLOSE_DELIM,
1457	 $CITE_ENUM,
1458	 $NUMERIC,
1459	 $BEFORE_PAR_YEAR,
1460	 $COMMON_AUTHOR_SEP)=@$style;
1461	$NUMERIC=($NUMERIC =~ /[sn]/);
1462	local($and)="HARVARDAND_$2";
1463	defined $$and && do { $HARVARDAND=$$and }
1464    } else { print "\nnatbib.perl: invalid argument to \\citestyle!" };
1465    $_;
1466}
1467
1468sub do_cmd_citationstyle {
1469    &do_cmd_citestyle
1470}
1471
1472#print "\nLoading $LATEX2HTMLSTYLES/babelbst.perl"
1473#    if (require "$LATEX2HTMLSTYLES/babelbst.perl");
1474&do_require_package('babelbst');
1475
1476&ignore_commands ( <<_IGNORED_CMDS_);
1477bibsection # {}
1478bibfont # {}
1479bibhang # &ignore_numeric_argument
1480bibsep # &ignore_numeric_argument
1481citeindextype # {}
1482harvardyearparenthesis # {}
1483_IGNORED_CMDS_
1484
14851;                              # This must be the last line
1486
1487