[Tex/LaTex] redefining \label and \ref when using hyperref

cross-referencinghyperref

I'm editing a book that includes about 25 papers written in LaTeX by different authors. Since many of them use the same \label, to avoid collisions I redefined the \label command (and \ref and \pageref and \cite and \bibitem) so that if the third paper has
\label{main_theorem}
the aux file actually uses the tag "iii:main_theorem", and \ref{main_theorem}
actually refers to the same tag. I did a similar thing for \cite and \bibitem.

%*************** bib/cite hacks
\let\TheReal@citex=\@citex
\let\TheReal@bibitem=\@bibitem
\let\TheReal@lbibitem=\@lbibitem
\gdef\@lbibitem[#1]#2{\TheReal@lbibitem[{#1}]{#2\roman{chapter}}}
\gdef\@bibitem#1{\TheReal@bibitem{#1\roman{chapter}}}
\gdef\@citex[#1]#2{%
\toks@={}\count@=0%
\@for\@citec:=#2\do{%
\advance\count@ 1
\ifnum\count@=1\edef\0{\the\toks@\expandafter\expandafter\noexpand\@citec\roman{chapter}}%
\else\edef\0{\the\toks@,\expandafter\expandafter\noexpand\@citec\roman{chapter}}
\fi%
\toks@=\expandafter{\0}}%
\TheReal@citex[#1]{\the\toks@}%
}
%************** label/ref/pageref hacks  %%%%%%%%%%%%% must be before ams pkgs
\let\TheRealLabel=\label
\let\TheRealRef=\ref
\let\TheRealPageref=\pageref
\gdef\label#1{\TheRealLabel{\roman{chapter}:#1}}
\gdef\ref#1{\TheRealRef{\roman{chapter}:#1}}
\gdef\pageref#1{\TheRealPageref{\roman{chapter}:#1}}

This all worked fine until I used hyperref, which seems to ignore the redefinition of \label, whether I load it before or after the above code.

Any suggestions? It would be nice if the redefinition would work whether or not hyperref was loaded, so I don't want to just grab the defintion of \label out of the package and tweak it.

I'm also open to alternative methods. Redefining \label and \ref just seemed the most straightforward (to me) solution.

Note that I also want to be able to refer to the inner labels from outside, as well. For example, I might want to say "the main theorem of the third paper is
\ChapRef{iii}{main_theorem} from within the introduction (a different chapter).

Best Answer

Because some redefining of \label/\ref by hyperref/nameref is done via \AtBeginDocument, you have to use it also at a later time after the packages are loaded:

\usepackage{hyperref}
\usepackage{letltxmacro}

\AtBeginDocument{%
  \LetLtxMacro{\TheRealLabel}{\label}%
  \LetLtxMacro{\TheRealRef}{\ref}%
  \LetLtxMacro{\TheRealPageRef}{\pageref}%
  % redefining \label, \ref, \pageref (\renewcommand or \DeclareRobustCommand)
}

Updated with egreg's comment. \LetLtxMacro of package letltxmacro takes care of macros that are defined via \DeclareRobustCommand (or as macros with optional parameters).

Related Question