3

My document contains parts and sections. When I refer, for instance, to the section I.1, I would like \ref to output 1 when it is located in part I, and I.1 otherwise. Thus, I would like my document to look like :

I. First part
1 First section
2 Second section
Reference to the first section of the first part : 1

II. Second part
1 First section
Reference to the first section of the first part : I.1

Following this link, here is what I've tried. First, I use \counterwithin* so that section is reset each time part is incremented. Then, I change \p@section to add the part number to references to sections. Finally, I define \newref, which is supposed to drop the part number when it is not needed. Hence we get :

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{chngcntr}
\usepackage{xstring}
\usepackage{refcount}

\counterwithin*{section}{part}
\makeatletter
\renewcommand\p@section{\thepart.}
\makeatother

\newcommand\newref[1]{%
  \IfRefUndefinedExpandable{#1}{\refused{#1}\textbf{??}}{%
    \edef\temp{\expandafter\detokenize\getrefnumber{#1}}%
    \IfStrEq{\thepart}{\StrBefore\temp.}{%
      \StrBehind\temp.}{%
      \temp}}}

\begin{document}

\part{First part}

\section{First section}

\label{sec:fst}

\section{Second section}

Reference to the first section of the first part : \newref{sec:fst}

\part{Second part}

\section{First section}

Reference to the first section of the first part : \newref{sec:fst}

\end{document}

However, the code above fails with "! Missing { inserted", for a reason I don't understand.

So, to recap, I would greatly appreciate to :
1) Understand why my code doesn't work ;
2) Get a solution to my problem.

Many thanks in advance.

aew
  • 33
  • I think there are expansion problems and \thepart might not contain what you suspect. –  Jun 30 '15 at 18:16

1 Answers1

1

This works, but it calls \getrefnumber three times. I'll try to improve this.

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{chngcntr}
\usepackage{xstring}
\usepackage{refcount}

\counterwithin*{section}{part}
\makeatletter
\renewcommand\p@section{\thepart.}

%\newcommand\newref[1]{%
%  \IfRefUndefinedExpandable{#1}{\refused{#1}\textbf{??}}{%
%    \edef\temp{\expandafter\detokenize\getrefnumber{#1}}%
%    \IfStrEq{\thepart}{\StrBefore\temp.}{%
%      \StrBehind\temp.}{%
%      \temp}}}

\newcommand{\newref}[1]{%
  \IfRefUndefinedExpandable{#1}{\refused{#1}\textbf{??}}{%
    \StrBefore{\getrefnumber{#1}}{.}[\part@number]
    \StrBehind{\getrefnumber{#1}}{.}[\section@number]
    \IfStrEq{\thepart}{\part@number}{%
      \section@number%
    }{%
      \getrefnumber{#1}%
    }%
  }%
}

\makeatother


\begin{document}

\part{First part}

\section{First section}

\label{sec:fst}

\section{Second section}

Reference to the first section of the first part : \newref{sec:fst} and \newref{sec:other}

\part{Second part}

\section{First section}

Reference to the first section of the first part : \newref{sec:fst}

\end{document}

Edit Version without \getrefnumber{#1} called thrice:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{chngcntr}
\usepackage{xstring}
\usepackage{refcount}

\counterwithin*{section}{part}
\makeatletter
\renewcommand\p@section{\thepart.}

\newcommand{\newref}[1]{%
  \IfRefUndefinedExpandable{#1}{\refused{#1}\textbf{??}}{%
    \edef\temp{\getrefnumber{#1}}%
    \StrBefore{\temp}{.}[\part@number]
    \StrBehind{\temp}{.}[\section@number]
    \IfStrEq{\thepart}{\part@number}{%
      \section@number%
    }{%
      \temp%
    }%
  }%
}

\makeatother


\begin{document}

\part{First part}

\section{First section}

\label{sec:fst}

\section{Second section}

Reference to the first section of the first part : \newref{sec:fst} and \newref{sec:other}

\part{Second part}

\section{First section}

Reference to the first section of the first part : \newref{sec:fst}

\part{Third part}

\section{First section} \label{sec:third}

Reference to the first section of the 3rd part : \newref{sec:third}


\end{document}

enter image description here

  • Thank you very much. Looking at the différences between your code and mine, I've understood a part of the problem : it is explicitly mentioned in the xstring documentation (section 3.2) that the macros of this package are not purely expandable, and that nestling them is not possible. – aew Jun 30 '15 at 19:32
  • @aew: Yes, I mentioned that (very shortly) in my comment to your post –  Jun 30 '15 at 19:33
  • As for the \expandafter\detokenize sequence, I had copied it from the page I linked in my question, without being fully aware of its meaning. Apparently, not only is it useless, but it seems to make trouble. However, for some reason, the code posted in that page compiles very fine and yields the expected result. – aew Jun 30 '15 at 19:39
  • @aew: Yes, I do not understand the detokenizing there at all. Please note, that my code my break somewhere. It's only tested for your small document. –  Jun 30 '15 at 20:10
  • I've tested you code in a larger document (about 40 pages and 200 references). I got 2 problems. The first seems to be a well-known, though complicated one : \newcommand\newref must be replaced with \DeclareRobustCommand\newref, otherwise references in the titles of sections may make trouble. The second problem is a very strange and unfortunate one : if we add the line usepackage[french]{babel} at the beginning of the file, your code doesn't work anymore. It seems to come from the reference names containing the character :. Thus, I've changed all my reference names. – aew Jul 01 '15 at 13:08
  • For sure, in a section command, you always need a robust command or use \protect. And : is dangerous due to French typography. Both things were not available to me from your MWE. –  Jul 01 '15 at 14:39
  • Yes, your solution works with my MWE, but it's good to mention the problem for potential other users. I won't open a new question just for that, since there is a trivial solution : avoid using : in reference names. However, it goes against a well-established LaTeX tradition ; thus, if you know how Babel works, feel free to suggest something better. – aew Jul 01 '15 at 14:56
  • Something else which is worth mentioning is that in case a section title contains a reference, patching \ref obviously won't affect the table of contents. Thus, there will be a slight difference between the section title announced in the table of contents, and the actual title. I don't know how to fix that (but personally, it doesn't really bother me). – aew Jul 01 '15 at 15:00