% \iffalse
%% File: backcite.dtx Copyright (C) 1995 Michael Mehlich
%
%<*driver>
\documentclass{ltxdoc}
\IfFileExists{hyper.sty}{%
  \message{*** Generating hypertext documentation ***}
  \usepackage{hyper}%
}{}
%</driver>
\def\fileversion{V1.0}
\def\filedate{1995/05/11}
\def\docdate{1995/05/11}
%<*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{345}
%%
%% \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 enties 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}[1994/12/01]
\ProvidesPackage{hxt-bc}%
  [\filedate\space Backcite extension for HyperLaTeX2e]
%    \end{macrocode}
% Then check whether the |\hyper|--package already has been loaded.
% Otherwise, print a warning message and load it.
%    \begin{macrocode}
\@ifpackageloaded{hyper}{}{%
\@latex@warning{%
  Backcite extension hxt-bc loaded without the hyper package%
}%
\usepackage{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 remind the citations between two run or realize a bibliography in
% front of a document we have to write the neccessary informations about
% the occurrencies of the citations to the axiliary file and get the
% informations back when reading this file during startup.
%    \begin{macrocode}
\def\hyperbackcite#1#2#3#4{\hyper@aux{br}{#1}{#2,#3,#4}}
\let\hyper@citex\@citex
\def\@citex[#1]#2{%
  \hyper@citex[#1]{#2}%
  \let\@citea\@empty%
  \@for\@citeb:=#2\do%
    {\edef\@citeb{\expandafter\@iden\@citeb}%
     \@bsphack%
       \protected@write%
         \@auxout%
         {}%
         {\string\hyperbackcite%
           {\@citeb}%
           {\@currenthyper}%
           {\@currentlabel}%
           {\thepage}%
         }%
     \@esphack%
    }%
}
%    \end{macrocode}
% However, that does not help much. Yet we did not write the informations
% down into the resulting |dvi|--file. To overcome this we modify 
% the |\bibitem|--comand 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%
  \newblock%
  \expandafter\hyper@backcite\csname hyper@aux@br@#2\endcsname%
  \par%
}
\let\hyper@bibitem\@bibitem
\def\hyper@bibitem#1#2\par{%
  \hyper@bibitem{#1}#2%
  \newblock%
  \expandafter\hyper@backcite\csname hyper@aux@br@#2\endcsname%
  \par%
}
%    \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.\footnote{We just would need to count them up to 2 
% entries, but currently I do not see a really more efficient solution that
% works.}
% 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\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\space%
        \else%
          \hyperbackcitepage\space%
        \fi%
      \else%
        \expandafter\ifnum\count11>1\relax%
          \hyperbackcitesection\space%
        \else%
          \hyperbackcitesections\space%
        \fi%
      \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}{\@gobble}}
\def\hyper@@@backcite(#1,#2,#3){%
  \if@hyper@back@pages@%
    \edef\hyper@tempa{#3}%
    \ifx\hyper@last@cite\hyper@tempa\relax\else%
      \ifx\hyper@last@cite\relax\else, \fi\hyperpagereference{#3}{#3}%
      \edef\hyper@last@cite{#3}%
    \fi%
  \else%
    \edef\hyper@tempa{#2}%
    \ifx\hyper@tempa\@empty%
    \else\ifx\hyper@last@cite\hyper@tempa\relax\else%
      \ifx\hyper@last@cite\relax\else, \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 there 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%
      \@latex@warning@no@line{%
        Backcite(s) may have changed. Rerun to back references right%
      }%
    \fi%
  \else\expandafter\ifx\csname hyper@aux@brc\endcsname\relax%
    \@latex@warning@no@line{%
        Backcite(s) may have changed. Rerun to 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%
      \@latex@warning@no@line{%
        Backcite(s) may have changed. Rerun to 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
