% \iffalse
%% File: backcite.dtx Copyright (C) 1995--1999 Michael Mehlich
%% This program can be redistributed and/or modified under the terms
%% of the LaTeX Project Public License Distributed from CTAN
%% archives in directory macros/latex/base/lppl.txt; either
%% version 1 of the License, or any later version.
%
%<*driver>
\documentclass{ltxdoc}
\IfFileExists{hyper.sty}{%
  \message{*** Generating hypertext documentation ***}
  \usepackage[color,pagetop]{hyper}%
}{%
  \def\hyperURL##1##2##3##4{##4}
}
%</driver>
\def\fileversion{V2.0}
\def\filedate{1997/03/01}
\def\docdate{1997/03/01}
%<*driver>
\begin{document}
  \title{Backcite Extension for Hyper\LaTeXe\\\fileversion}
  \author{Michael Mehlich}
  \date{\docdate}
  \maketitle
  \tableofcontents
  \DocInput{backcite.dtx}
\end{document}
%</driver>
% \fi
% \CheckSum{513}
%%
%% \CharacterTable
%% {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
%%  Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
%%  Digits        \0\1\2\3\4\5\6\7\8\9
%%  Exclamation   \!     Double quote  \"     Hash (number) \#
%%  Dollar        \$     Percent       \%     Ampersand     \&
%%  Acute accent  \'     Left paren    \(     Right paren   \)
%%  Asterisk      \*     Plus          \+     Comma         \,
%%  Minus         \-     Point         \.     Solidus       \/
%%  Colon         \:     Semicolon     \;     Less than     \<
%%  Equals        \=     Greater than  \>     Question mark \?
%%  Commercial at \@     Left bracket  \[     Backslash     \\
%%  Right bracket \]     Circumflex    \^     Underscore    \_
%%  Grave accent  \`     Left brace    \{     Vertical bar  \|
%%  Right brace   \}     Tilde         \~}
%%
% \MakeShortVerb{|}
%
% \title{Hyper\LaTeXe}
% \maketitle
%
% \section{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.
% 
% \section{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.
%
% \StopEventually{}
%
% \clearpage
% \section{The Realization}
% First of all, introduce the standard header.
%    \begin{macrocode}
%<*backcite>
\NeedsTeXFormat{LaTeX2e}[1995/12/01]
\ProvidesPackage{hxt-bc}%
  [\filedate\space Backcite extension for HyperLaTeX2e]
%    \end{macrocode}
% Now check whether the |\hyper|--package already has been loaded.
% Otherwise, print a warning message and load it.
%    \begin{macrocode}
\@ifpackageloaded{hyper}{}{%
\PackageWarningNoLine{backcite}{%
  Backcite extension of hyper package needs hyper package.\MessageBreak
  Loading hyper package.%
}%
\usepackage[no]{hyper}%
}
%    \end{macrocode}
% 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.)
%    \begin{macrocode}
\def\hyper@aux#1#2#3{%
    \expandafter\ifx\csname hyper@aux@#1@#2\endcsname\relax%
      \expandafter\global%
      \expandafter\edef\csname hyper@aux@#1@#2\endcsname%
        {(#3)}%
    \else%
      \expandafter\global%
      \expandafter\edef\csname hyper@aux@#1@#2\endcsname%
        {\csname hyper@aux@#1@#2\endcsname(#3)}%
    \fi%
    \expandafter\ifx\csname hyper@aux@#1\endcsname\relax%
      \expandafter\global\expandafter%
      \newtoks\csname hyper@aux@#1\endcsname%
    \fi%
    \def\hyper@tempa{\csname hyper@aux@#1\endcsname}%
    \expandafter\expandafter\expandafter\expandafter%
    \expandafter\expandafter\expandafter\global%
    \expandafter\expandafter\expandafter\expandafter%
    \expandafter\expandafter\expandafter\hyper@tempa%
    \expandafter\expandafter\expandafter\expandafter%
    \expandafter\expandafter\expandafter{%
      \expandafter\expandafter\expandafter\the\expandafter\hyper@tempa%
      \csname hyper@aux@#1@#2\endcsname%
    }%
}
%    \end{macrocode}
% 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.\newline
% Damned, why do different packages handle this differently?
%    \begin{macrocode}
\def\hyperbackcite#1#2#3#4{\hyper@aux{br}{#1}{#2,#3,#4}}
\def\hyper@back@to@aux#1{%
   \@bsphack%
     \protected@write%
       \@auxout%
       {}%
       {\string\hyperbackcite%
         {#1}%
         {\@currenthyper}%
         {\@currentlabel}%
         {\thepage}%
       }%
   \@esphack%
}
\def\hyper@back@to@aux@list#1{%
  \@for\@citeb:=#1\do%
    {\edef\@citeb{\expandafter\@firstofone\@citeb}%
     \@bsphack%
       \protected@write%
         \@auxout%
         {}%
         {\string\hyperbackcite%
           {\@citeb}%
           {\@currenthyper}%
           {\@currentlabel}%
           {\thepage}%
         }%
     \@esphack%
    }%
}
\let\hyper@citex\@citex%
\def\@citex[#1]#2{%
   \hyper@back@to@aux@list{#2}%
   \hyper@citex[#1]{#2}%
}%
\ifx\harvarditem\@undefined\else%
  \let\hyper@har@citetoaux\HAR@citetoaux%
  \def\HAR@citetoaux#1{%
       \hyper@back@to@aux{#1}%
       \hyper@har@citetoaux{#1}%
  }%
\fi
\ifx\NAT@set@cites\@undefined\else%
  \let\hyper@hyper@natlinkstart\hyper@natlinkstart%
  \def\hyper@natlinkstart#1#2\hyper@natlinkend{%
     \hyper@back@to@aux{#1}%
     \hyper@hyper@natlinkstart{#1}{#2}\hyper@natlinkend%
  }%
  \ifnum\NAT@sort=1\relax
    \let\hyper@back@hold\relax
    \def\hyper@compress@cite#1#2{%
      \advance\@tempcnta\@ne%
      \ifnum #1=\@tempcnta%
         \ifx\@h@ld\relax%
            \edef\@h@ld{%
               \@citea%
               \noexpand%
                  \hyper@natlinkstart{#2}{#1}%
               \noexpand%
                  \hyper@natlinkend%
            }%
            \def\hyper@back@hold{\hyper@back@to@aux{#2}}%
         \else%
            \hyper@back@hold%
            \def\@h@ld{%
               \hbox{--}%
               \hyper@natlinkstart{#2}{#1}\hyper@natlinkend%
            }%
            \def\hyper@back@hold{\hyper@back@to@aux{#2}}%
         \fi%
      \else%
         \@h@ld\@citea%
         \hyper@natlinkstart{#2}{#1}\hyper@natlinkend%
         \let\@h@ld\relax%
      \fi%
      \@tempcnta#1\def\@citea{\NAT@sep\penalty\@m\NAT@space}%
    }
  \fi
  \NAT@set@cites
\fi%
%    \end{macrocode}
% 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.
%    \begin{macrocode}
\let\hyper@lbibitem\@lbibitem
\def\@lbibitem[#1]#2#3\par{%
  \hyper@lbibitem[#1]{#2}#3%
  \expandafter\hyper@backcite\csname hyper@aux@br@#2\endcsname%
  \par%
}
\let\hyper@bibitem\@bibitem
\def\hyper@bibitem#1#2\par{%
  \hyper@bibitem{#1}#2%
  \expandafter\hyper@backcite\csname hyper@aux@br@#1\endcsname%
  \par%
}
\ifx\harvarditem\@undefined\else
  \let\hyper@harvarditem\harvarditem
  \def\harvarditem{%
     \@ifnextchar[{\hyper@harvard@oitem}{\hyper@harvard@item}%
  }
  \def\hyper@harvard@item#1#2#3#4\par{%
     \hyper@harvarditem{#1}{#2}{#3}#4%
     \expandafter\hyper@backcite\csname hyper@aux@br@#3\endcsname%
  \par%
  }
  \def\hyper@harvard@oitem[#1]#2#3#4#5\par{%
     \hyper@harvarditem[#1]{#2}{#3}{#4}#5%
     \expandafter\hyper@backcite\csname hyper@aux@br@#4\endcsname%
  \par%
  }
\fi
%    \end{macrocode}
% As we do not want an entry several times\footnote{Note, 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.} 
% 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.
%    \begin{macrocode}
\def\hyperbackcitepage{Cited on page~}
\def\hyperbackcitepages{Cited on pages~}
\def\hyperbackcitesection{Cited in~}
\def\hyperbackcitesections{Cited in~}
\def\hyperbackcitenormalseparator{, }
\def\hyperbackcitefinalseparatorpair{ and~}
\def\hyperbackcitefinalseparatorlist{, and~}
\def\hyper@backcite#1{%
  \bgroup%
    \let\hyper@last@cite\relax%
    \count11=0\relax%
    \expandafter\hyper@back@cnt#1\relax%
    \let\hyper@last@cite\relax%
    \expandafter\ifnum\count11>0\relax%
      \if@hyper@back@pages@%
        \expandafter\ifnum\count11>1\relax%
          \hyperbackcitepages%
        \else%
          \hyperbackcitepage%
        \fi%
      \else%
        \expandafter\ifnum\count11>1\relax%
          \hyperbackcitesection%
        \else%
          \hyperbackcitesections%
        \fi%
      \fi%
      \ifnum\count11>2\relax%
         \let\hyper@back@final@connection%
                \hyperbackcitefinalseparatorlist%
      \else%
         \let\hyper@back@final@connection%
                \hyperbackcitefinalseparatorpair%
      \fi%
      \expandafter\hyper@@backcite#1\relax.%
    \fi%
  \egroup%
}
\def\hyper@back@cnt{\@ifnextchar({\hyper@@back@cnt}{\@gobble}}
\def\hyper@@back@cnt(#1,#2,#3){%
  \if@hyper@back@pages@%
    \edef\hyper@tempa{#3}%
    \ifx\hyper@last@cite\hyper@tempa\relax\else%
      \advance\count11by1\relax%
      \edef\hyper@last@cite{#3}%
    \fi%
  \else%
    \edef\hyper@tempa{#2}%
    \ifx\hyper@tempa\@empty%
    \else\ifx\hyper@last@cite\hyper@tempa\relax\else%
      \advance\count11by1\relax%
      \edef\hyper@last@cite{#2}%
    \fi\fi%
  \fi%
  \hyper@back@cnt%
}
\def\hyper@@backcite{\@ifnextchar({\hyper@@@backcite}{}}
\def\hyper@@@backcite(#1,#2,#3){%
  \if@hyper@back@pages@%
    \edef\hyper@tempa{#3}%
    \ifx\hyper@tempa\@empty\relax%
    \else\ifx\hyper@last@cite\hyper@tempa\relax\else%
       \advance\count11by-1\relax%
       \ifx\hyper@last@cite\relax\else%
          \ifnum\count11=0\relax%
             \hyper@back@final@connection%
          \else%
             \hyperbackcitenormalseparator%
          \fi%
      \fi%
      \hyperpagereference{#3}{#3}%
      \edef\hyper@last@cite{#3}%
    \fi\fi%
  \else%
    \edef\hyper@tempa{#2}%
    \ifx\hyper@tempa\@empty\relax%
    \else\ifx\hyper@last@cite\hyper@tempa\relax\else%
       \advance\count11by-1\relax%
       \ifx\hyper@last@cite\relax\else%
          \ifnum\count11=0\relax%
             \hyper@back@final@connection%
          \else%
             \hyperbackcitenormalseparator%
          \fi%
       \fi%
       \hyperreference{#1}{#2}%
       \edef\hyper@last@cite{#2}%
    \fi\fi%
  \fi%
  \hyper@@backcite%
}
%    \end{macrocode}
% 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.
%    \begin{macrocode}
\def\hyperbackcite@check#1#2#3#4{\hyper@aux{brc}{#1}{#2,#3,#4}}
\let\hyper@back@cite@enddocument\enddocument
\def\enddocument{%
  \let\hyperbackcite\hyperbackcite@check%
  \let\hyper@@backcite@end\@@end%
  \def\@@end{\hyper@check@backcites\hyper@@backcite@end}%
  \hyper@back@cite@enddocument%
}
\def\hyper@check@backcites{%
  \expandafter\ifx\csname hyper@aux@br\endcsname\relax%
    \expandafter\ifx\csname hyper@aux@brc\endcsname\relax%
    \else%
      \PackageWarningNoLine{backcite}{%
        Backcite(s) may have changed.\MessageBreak
        Rerun to get back references right%
      }%
    \fi%
  \else\expandafter\ifx\csname hyper@aux@brc\endcsname\relax%
    \PackageWarningNoLine{backcite}{%
        Backcite(s) may have changed.\MessageBreak
        Rerun to get back references right%
      }%
  \else%
    \edef\hyper@tempa{\the\hyper@aux@br}
    \edef\hyper@tempb{\the\hyper@aux@brc}
    \edef\hyper@tempa{\hyper@tempa}
    \edef\hyper@tempb{\hyper@tempb}
    \ifx\hyper@tempa\hyper@tempb\else%
      \PackageWarningNoLine{backcite}{%
        Backcite(s) may have changed.\MessageBreak
        Rerun to get back references right%
      }%
    \fi%
  \fi\fi%
}
%    \end{macrocode}
% 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.
%    \begin{macrocode}
\newif\if@hyper@back@pages@
\@hyper@back@pages@true
\DeclareOption{pages}{\@hyper@back@pages@true}
\DeclareOption{sections}{\@hyper@back@pages@false}
\ProcessOptions
%</backcite>
%    \end{macrocode}
%
% \Finale
