Backcite Extension for HyperL^{A}TEX 2ε V2.0

Michael Mehlich 1997/03/01

Contents

1 Introduction 2 2 Usage 2 3 The Realization 3

HyperL^{A}TEX 2ε

April 28, 1997

1 Introduction

For developing documents it is often useful to know the places bibliographic entries have been used in. This subpackage of the hyper–package realizes this by remembering the pages or sections/theorems and so on a \cite command occurs in. The resulting informations are then added to the respectively bibliograhic entries for the citations.

2 Usage

This package is not intended to be used stand alone but only together with the hyper–package. You can invoke it by giving backcitepages respectively backcitesections as optional parameters for the hyper–package.

3 The Realization

First of all, introduce the standard header.

1 ⟨∗backcite⟩

 2 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
 3 \ProvidesPackage{hxt-bc}%
 4 [\filedate\space Backcite extension for HyperLaTeX2e]

Now check whether the \hyper–package already has been loaded. Otherwise, print a warning message and load it.

 5 \@ifpackageloaded{hyper}{}{%
 6 \PackageWarningNoLine{backcite}{%
 7 Backcite extension of hyper package needs hyper package.\MessageBreak
 8 Loading hyper package.%
 9 }%
10 \usepackage[no]{hyper}%

11 }

We have to recognize all the places for the citations; thus, we need a collector for them that introduces a new macro holding this information for each cite and, to check them being unchanged by a latex run, a new token list holding all these macros. Such a collector is defined in a generic way by the following macro. (First time I used \expandafter seven(!) times one after another.)

12 \def\hyper@aux#1#2#3{%
13  \expandafter\ifx\csname hyper@aux@#1@#2\endcsname\relax%
14  \expandafter\global%
15  \expandafter\edef\csname hyper@aux@#1@#2\endcsname%
16  {(#3)}%
17  \else%
18  \expandafter\global%
19  \expandafter\edef\csname hyper@aux@#1@#2\endcsname%
20  {\csname hyper@aux@#1@#2\endcsname(#3)}%
21  \fi%
22  \expandafter\ifx\csname hyper@aux@#1\endcsname\relax%
23  \expandafter\global\expandafter%
24  \newtoks\csname hyper@aux@#1\endcsname%
25  \fi%
26  \def\hyper@tempa{\csname hyper@aux@#1\endcsname}%
27  \expandafter\expandafter\expandafter\expandafter%
28  \expandafter\expandafter\expandafter\global%
29  \expandafter\expandafter\expandafter\expandafter%
30  \expandafter\expandafter\expandafter\hyper@tempa%
31  \expandafter\expandafter\expandafter\expandafter%
32  \expandafter\expandafter\expandafter{%
33  \expandafter\expandafter\expandafter\the\expandafter\hyper@tempa%
34  \csname hyper@aux@#1@#2\endcsname%
35  }%

36 }

To remember the citations between two runs or realize a bibliography in front of a document we have to write the neccessary informations about the occurrences of the citations to the axiliary file and get the informations back when reading this file during startup. Damned, why do different packages handle this differently?

37 \def\hyperbackcite#1#2#3#4{\hyper@aux{br}{#1}{#2,#3,#4}}
38 \def\hyper@back@to@aux#1{%
39 \@bsphack%
40  \protected@write%
41  \@auxout%
42  {}%
43  {\string\hyperbackcite%
44  {#1}%
45  {\@currenthyper}%
46  {\@currentlabel}%
47  {\thepage}%
48  }%
49 \@esphack%

50 }

51 \def\hyper@back@to@aux@list#1{%
52 \@for\@citeb:=#1\do%
53  {\edef\@citeb{\expandafter\@firstofone\@citeb}%
54  \@bsphack%
55  \protected@write%
56  \@auxout%
57  {}%
58  {\string\hyperbackcite%
59  {\@citeb}%
60  {\@currenthyper}%
61  {\@currentlabel}%
62  {\thepage}%
63  }%
64  \@esphack%
65  }%

66 }

67 \let\hyper@citex\@citex%
68 \def\@citex[#1]#2{%
69 \hyper@back@to@aux@list{#2}%
70 \hyper@citex[#1]{#2}%
71 }%
72 \ifx\harvarditem\@undefined\else%
73 \let\hyper@har@citetoaux\HAR@citetoaux%
74 \def\HAR@citetoaux#1{%
75  \hyper@back@to@aux{#1}%
76  \hyper@har@citetoaux{#1}%
77 }%
78 \fi
79 \ifx\NAT@set@cites\@undefined\else%
80 \let\hyper@hyper@natlinkstart\hyper@natlinkstart%
81 \def\hyper@natlinkstart#1#2\hyper@natlinkend{%
82  \hyper@back@to@aux{#1}%
83  \hyper@hyper@natlinkstart{#1}{#2}\hyper@natlinkend%
84 }%
85 \ifnum\NAT@sort=1\relax
86  \let\hyper@back@hold\relax
87  \def\hyper@compress@cite#1#2{%
88  \advance\@tempcnta\@ne%
89  \ifnum #1=\@tempcnta%
90  \ifx\@h@ld\relax%

 91  \edef\@h@ld{%
 92  \@citea%
 93  \noexpand%
 94  \hyper@natlinkstart{#2}{#1}%
 95  \noexpand%
 96  \hyper@natlinkend%
 97  }%
 98  \def\hyper@back@hold{\hyper@back@to@aux{#2}}%
 99  \else%
100  \hyper@back@hold%
101  \def\@h@ld{%
102  \hbox{--}%
103  \hyper@natlinkstart{#2}{#1}\hyper@natlinkend%

104 }%

105  \def\hyper@back@hold{\hyper@back@to@aux{#2}}%
106  \fi%
107  \else%
108  \@h@ld\@citea%
109  \hyper@natlinkstart{#2}{#1}\hyper@natlinkend%
110  \let\@h@ld\relax%
111  \fi%
112  \@tempcnta#1\def\@citea{\NAT@sep\penalty\@m\NAT@space}%

113 }

114 \fi
115 \NAT@set@cites
116 \fi%

However, that does not help much. So far we did not write the informations down into the resulting dvi–file. To overcome this we modify the \bibitem–command such that the respectively informations will be added after each entry.

117 \let\hyper@lbibitem\@lbibitem
118 \def\@lbibitem[#1]#2#3\par{%
119 \hyper@lbibitem[#1]{#2}#3%
120 \expandafter\hyper@backcite\csname hyper@aux@br@#2\endcsname%
121 \par%

122 }

123 \let\hyper@bibitem\@bibitem
124 \def\hyper@bibitem#1#2\par{%
125 \hyper@bibitem{#1}#2%
126 \expandafter\hyper@backcite\csname hyper@aux@br@#1\endcsname%
127 \par%

128 }

129 \ifx\harvarditem\@undefined\else
130 \let\hyper@harvarditem\harvarditem
131 \def\harvarditem{%
132  \@ifnextchar[{\hyper@harvard@oitem}{\hyper@harvard@item}%

133 }

134 \def\hyper@harvard@item#1#2#3#4\par{%
135  \hyper@harvarditem{#1}{#2}{#3}#4%
136  \expandafter\hyper@backcite\csname hyper@aux@br@#3\endcsname%
137 \par%

138 }

139 \def\hyper@harvard@oitem[#1]#2#3#4#5\par{%
140  \hyper@harvarditem[#1]{#2}{#3}{#4}#5%

141  \expandafter\hyper@backcite\csname hyper@aux@br@#4\endcsname%
142 \par%

143 }

144 \fi

As we do not want an entry several times^{1} but want to insert a hint about the type of backcites, we have to count then number of informations for each citation. Afterwards we can print out this hint and loop through all informations to print them out.

145 \def\hyperbackcitepage{Cited on page~}
146 \def\hyperbackcitepages{Cited on pages~}
147 \def\hyperbackcitesection{Cited in~}
148 \def\hyperbackcitesections{Cited in~}
149 \def\hyperbackcitenormalseparator{, }
150 \def\hyperbackcitefinalseparatorpair{ and~}
151 \def\hyperbackcitefinalseparatorlist{, and~}
152 \def\hyper@backcite#1{%
153 \bgroup%
154  \let\hyper@last@cite\relax%
155  \count11=0\relax%
156  \expandafter\hyper@back@cnt#1\relax%
157  \let\hyper@last@cite\relax%
158  \expandafter\ifnum\count11>0\relax%
159  \if@hyper@back@pages@%
160  \expandafter\ifnum\count11>1\relax%
161  \hyperbackcitepages%
162  \else%
163  \hyperbackcitepage%
164  \fi%
165  \else%
166  \expandafter\ifnum\count11>1\relax%
167  \hyperbackcitesection%
168  \else%
169  \hyperbackcitesections%
170  \fi%
171  \fi%
172  \ifnum\count11>2\relax%
173  \let\hyper@back@final@connection%
174  \hyperbackcitefinalseparatorlist%
175  \else%
176  \let\hyper@back@final@connection%
177  \hyperbackcitefinalseparatorpair%
178  \fi%
179  \expandafter\hyper@@backcite#1\relax.%
180  \fi%
181 \egroup%

182 }

183 \def\hyper@back@cnt{\@ifnextchar({\hyper@@back@cnt}{\@gobble}}
184 \def\hyper@@back@cnt(#1,#2,#3){%
185 \if@hyper@back@pages@%
186  \edef\hyper@tempa{#3}%
187  \ifx\hyper@last@cite\hyper@tempa\relax\else%

1Note, that currently we do not sort the list of informations. Thus, we may get several identical entries for the sectioning informations if, e.g. we cite something within a theorem.

188  \advance\count11by1\relax%
189  \edef\hyper@last@cite{#3}%
190  \fi%
191 \else%
192  \edef\hyper@tempa{#2}%
193  \ifx\hyper@tempa\@empty%
194  \else\ifx\hyper@last@cite\hyper@tempa\relax\else%
195  \advance\count11by1\relax%
196  \edef\hyper@last@cite{#2}%
197  \fi\fi%
198 \fi%
199 \hyper@back@cnt%

200 }

201 \def\hyper@@backcite{\@ifnextchar({\hyper@@@backcite}{}}
202 \def\hyper@@@backcite(#1,#2,#3){%
203 \if@hyper@back@pages@%
204  \edef\hyper@tempa{#3}%
205  \ifx\hyper@tempa\@empty\relax%
206  \else\ifx\hyper@last@cite\hyper@tempa\relax\else%
207  \advance\count11by-1\relax%
208  \ifx\hyper@last@cite\relax\else%
209  \ifnum\count11=0\relax%
210  \hyper@back@final@connection%
211  \else%
212  \hyperbackcitenormalseparator%
213  \fi%
214  \fi%
215  \hyperpagereference{#3}{#3}%
216  \edef\hyper@last@cite{#3}%
217  \fi\fi%
218 \else%
219  \edef\hyper@tempa{#2}%
220  \ifx\hyper@tempa\@empty\relax%
221  \else\ifx\hyper@last@cite\hyper@tempa\relax\else%
222  \advance\count11by-1\relax%
223  \ifx\hyper@last@cite\relax\else%
224  \ifnum\count11=0\relax%
225  \hyper@back@final@connection%
226  \else%
227  \hyperbackcitenormalseparator%
228  \fi%
229  \fi%
230  \hyperreference{#1}{#2}%
231  \edef\hyper@last@cite{#2}%
232  \fi\fi%
233 \fi%
234 \hyper@@backcite%

235 }

At the end of the latex run we want to check whether the backcites may have changed to warn the user about this problem. Thus, we reread the auxiliary file just generated and collect all the informations about the new citations. Afterwards we just check their equivalence roughly such that everything is correct at least when no warning message is printed.

236 \def\hyperbackcite@check#1#2#3#4{\hyper@aux{brc}{#1}{#2,#3,#4}}
237 \let\hyper@back@cite@enddocument\enddocument
238 \def\enddocument{%
239 \let\hyperbackcite\hyperbackcite@check%
240 \let\hyper@@backcite@end\@@end%
241 \def\@@end{\hyper@check@backcites\hyper@@backcite@end}%
242 \hyper@back@cite@enddocument%

243 }

244 \def\hyper@check@backcites{%
245 \expandafter\ifx\csname hyper@aux@br\endcsname\relax%
246  \expandafter\ifx\csname hyper@aux@brc\endcsname\relax%
247  \else%
248  \PackageWarningNoLine{backcite}{%
249  Backcite(s) may have changed.\MessageBreak
250  Rerun to get back references right%

251 }%

252  \fi%
253 \else\expandafter\ifx\csname hyper@aux@brc\endcsname\relax%
254  \PackageWarningNoLine{backcite}{%
255  Backcite(s) may have changed.\MessageBreak
256  Rerun to get back references right%

257 }%

258 \else%
259  \edef\hyper@tempa{\the\hyper@aux@br}
260  \edef\hyper@tempb{\the\hyper@aux@brc}
261  \edef\hyper@tempa{\hyper@tempa}
262  \edef\hyper@tempb{\hyper@tempb}
263  \ifx\hyper@tempa\hyper@tempb\else%
264  \PackageWarningNoLine{backcite}{%
265  Backcite(s) may have changed.\MessageBreak
266  Rerun to get back references right%

267 }%

268  \fi%
269 \fi\fi%

270 }

Now let’s just introduce the options for this package, i.e. decide whether we want to introduce backreferences for the citations using the pages or the section/theorem numbers.

271 \newif\if@hyper@back@pages@
272 \@hyper@back@pages@true
273 \DeclareOption{pages}{\@hyper@back@pages@true}
274 \DeclareOption{sections}{\@hyper@back@pages@false}
275 \ProcessOptions

276 ⟨/backcite⟩