Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I'm formatting a long document with many chapters. Most chapters contain some generic sections (e.g. "Introduction," "Results," ...) and most of them are already labeled accordingly (e.g. \label{sec:intro}, \label{sec:results}). This is fine on a chapter-by-chapter basis, but when I put them all together, it means some labels will be used more than once (e.g. there might be five sec:intro labels from five different chapters.)

Can I use these labels without re-naming them? Is LaTeX smart enough to know that within the .tex file for chapter 2, \ref{sec:intro} refers to the "Introduction" section in the current chapter.

If not, what's the preferred solution? Renaming all the labels seems clunky and brittle.

share|improve this question
5  
rename all the labels:-) –  David Carlisle Nov 9 '12 at 16:21
    
yuck. Oh, well. –  Abe Nov 9 '12 at 16:26
    
It is possible to do nasty stuff to localize labels to their own included file. But it is fragile and should be done by users who know what they are doing. The rename might be as easy as sec: into sec:<num>: within each file, then it is also easy to spot what each one relates to. –  daleif Nov 9 '12 at 16:43
3  
beware putting section/chapter numbers into labels, it works but the idea of using symbolic keys is that re-numbering is painless. If you insert a new chapter and so all the labels in your (new) chapter 4 are of the form chap3:sec:intro then LaTeX will work without problems but it will confuse any humans looking at the source file. –  David Carlisle Nov 9 '12 at 16:52
    
Your latex editor may be able to prompt you for a label each time you enter a sectioning command, and number it if needed. Plus it can provide you with easy ways of selecting crossreference, so that the name of the label is mostly irrelevant to you. Emacs + RefTeX can definitely do that, for example. –  T. Verron Nov 9 '12 at 17:54
add comment

2 Answers 2

up vote 8 down vote accepted

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 expression Here's a reference to \ref{sec:intro} and \ref{sec:results} it would match

    sec: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.
share|improve this answer
add comment

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. As hypherref, 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. If amsmath 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}.
share|improve this answer
    
I would disadvise this solution, because it basically makes it impossible (or really hard) to reference anything across local label groups. While it is fine for generic section names such as intro, it may come to be a problem if one wants to refer to tables, figures, theorems... –  T. Verron Nov 9 '12 at 21:56
    
On the other hand, surprisingly, this hack doesn't break commands like \tableofcontents. –  T. Verron Nov 9 '12 at 21:57
    
@T.Verron that's not true, really. Why should it break commands such as \tableofcontents? And if you really want to crossref between areas that use \locallabels all you have to do is to use \origref etc with the prefix of the area you reference into. In short what the "hack" does is automating what you could or would do when applying the prefixes manually all over the place. –  Frank Mittelbach Nov 9 '12 at 22:27
    
Yes, that's why I corrected the "impossible" into "really hard". Also, imagine you need to change one of those label prefixes, because of a duplicate name or whatever. All of a sudden, you'll break dozens of labels. If you'd apply the prefixes yourself, you'd do it only for the few sections that have the same name, and which you probably won't want to refer in other chapters. Of course, a workaround is to leave \label as it is, and create a \duplabel for these few sections. –  T. Verron Nov 9 '12 at 22:43
1  
About \tableofcontents, as I understand it, the only reason it isn't broken is that this command does the referencing itself, and doesn't use \ref. I have been trying stuff around to see if I could get to a serious clash... It seems no document will compile with this hack and hyperref loaded, but I have no idea if it is a deep problem or an easily-fixable one. –  T. Verron Nov 9 '12 at 22:46
show 4 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.