Can I re-use section labels across chapters?
Localizing the labels and references by hand would be done using some sort of prefix, e.g., sec:labelA
as suggested in the comments. But that means one has to update all accurrences of \label
, \ref
and \pageref
to use those prefixes.
On the other hand using TeX to automate that is not that difficult:
\documentclass{article}
\AtBeginDocument{%
\let\origref\ref
\let\origpageref\pageref
\let\origlabel\label
\newcommand\locallabels[1]{%
\renewcommand\label[1]{\origlabel{#1##1}}%
\renewcommand\ref[1]{\origref{#1##1}}%
\renewcommand\pageref[1]{\origpageref{#1##1}}%
}}
\begin{document}
\section{A}\label{foo}
test \ref{foo} on \pageref{foo}
\locallabels{sec1:}
\newpage
\section{B}\label{foo}
test \ref{foo} on \pageref{foo}
\locallabels{}
\newpage
test \ref{foo} on \pageref{foo}
\end{document}
Basically that saves away the current definitions of those commands and then redefines them when \locallabels
is called to add the prefix that is given as the argument to \locallabels
.
Notes
- The definitions should come at the very end of
\begin{document}
to pick up the latest definitions of the commands in case some package modifies them. Ashypherref
, for example, does its redefinition using\AtBeginDocument
we have to do the same. - If extensions like
varioref
are used the commands of such a package would need the same treatement. Ifamsmath
is used then the command to adjust additionally is called\label@in@display
, see Using custom \locallabels command with custom \eqref command - Of course each use of
\locallabels
should use a different prefix unless one wants two regions to share the labels, e.g.,\locallabels{}
in the example went back to using no prefix so the references from section A got picked up. - If there is a need to reference a label within the scope of
\locallabels
from the outside one could do this using\origref{<prefix><label}
.
As David Carlisle says, rename your labels. This can easily be done using the Stream Editor, sed
for example.
Let's say that you have one chapter file about Lions, and one about Zebras; in both chapter files you have used the labelling convention you described, something like the following:
lions.tex
\chapter{Lions}
\section{Intro}\label{sec:intro}
\section{Results}\label{sec:results}
Here's a reference to \ref{sec:intro} and \ref{sec:results}.
zerbras.tex
\chapter{Zebras}
\section{Intro}\label{sec:intro}
\section{Intro}\label{sec:intro}
\section{Results}\label{sec:results}
Here's a reference to \ref{sec:intro} and \ref{sec:results}.
You can use sed
to search and replace each \label
and \ref
in each of the files so that all of your labels and references change appropriately
sed -i 's/\\\(label\|ref\){\([^}]*\)/\\\1{lions:\2/g' lions.tex
sed -i 's/\\\(label\|ref\){\([^}]*\)/\\\1{zebras:\2/g' zebras.tex
Now your files look like the following
lions.tex (new)
\chapter{Lions}
\section{Intro}\label{lions:sec:intro}
\section{Results}\label{lions:sec:results}
Here's a reference to \ref{lions:sec:intro} and \ref{lions:sec:results}.
zebras.tex (new)
\chapter{Zebras}
\section{Intro}\label{zebras:sec:intro}
\section{Intro}\label{zebras:sec:intro}
\section{Results}\label{zebras:sec:results}
Here's a reference to \ref{zebras:sec:intro} and \ref{zebras:sec:results}.
Understanding \(label\|ref){([^}]*)/\\1{lions:\2/g
The basic syntax I have used is s/old/new/g
to substitute 'old' with 'new'. The g
flag says to do it globally. Let's break the above expression down into parts:
\\\(label\|ref\)
matches\label
or\ref
and stores the result into memory, to be used later as\1
. Note that we need to use a\
to escape special characters{\([^}]*\)
matches the stuff inside{...}
, but does so in a non-greedy way. It is very important for this regexp not to be greedy; if were greedy, then when operating upon the expressionHere's a reference to \ref{sec:intro} and \ref{sec:results}
it would matchsec:intro} and \ref{sec:results}
which is not what we intend!
\\\1{lions:\2
is the replacement text, using\1
and\2
as the match that has been stored into memory.