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.

  • I think there are expansion problems and \thepart might not contain what you suspect. – user31729 Jun 30 '15 at 18:16
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

| improve this answer | |
  • 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 – user31729 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. – user31729 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 1 '15 at 13:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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