# format numbers in reference so they sort correctly

This is a followup to question list of occurences of references. In the MWE below the index lists the Goals in alphabetic order where numeric is needed for the second token:

The solution I found (on SE - sorry I lost the link) for the chapter and section numbers for the subsidiary indexing doesn't seem to work for the main headings. I tried a few others, to no avail.

Edit: the solution to convert outcome of reference to regular number looks as if it ought to work but I tried something like that and it failed.

\documentclass[12pt]{book}

\usepackage{amsthm}
\usepackage{environ}
\usepackage{imakeidx}
\usepackage{refcount}
\usepackage{hyperref}

\makeindex[intoc]
\makeindex[name=goals,title=Goal References,columns=1,intoc]

\newcommand{\gref}[1]{%
[Goal~\ref{goal:#1}]
\index[goals]{Goal~\getrefnumber{goal:#1}!Section
\ifnum\value{chapter}<10 0\fi\arabic{chapter}.%
\ifnum\value{section}<10 0\fi\arabic{section}}
}

\makeatletter
\newcommand\l@goal[1]{%
\vskip \z@ \@plus \p@
\begingroup
\parindent\z@
\rightskip\@pnumwidth
\parfillskip-\@pnumwidth
\leavevmode #1\nobreak\hfil\nobreak\null\par
\penalty\@highpenalty
\endgroup}

% arrange goal numbering by chapter
\newtheorem{Goal}{Goal}[chapter]

% define a shorthand to be able to get at \BODY with \expandafter
\newcommand\indexgoal[1]{\goalindex[goals]{Goal~\theGoal! #1}}

% save a copy of \index
\let\goalindex\index
\NewEnviron{goal}[1]{%
\begin{Goal}
\label{goal:#1}%
% here we neutralize \index so that it won't do damages
\begingroup
\renewcommand\index[2][]{}%
% but the main command uses \goalindex, so it's safe
\expandafter\indexgoal\expandafter{\BODY}%
\endgroup
%{\em label:} #1 %comment in/out to restore/suppress printing label
\normalfont{}\noindent
\BODY
}
[\end{Goal}]
\makeatother

\newenvironment{goals}
{%
{\textbf Chapter goals:}
}
{}

\begin{document}

\tableofcontents{}

\setcounter{chapter}{1}
\chapter{TWO}

\tracingmacros=1

\begin{goals}

\begin{goal}{twofirst}
\end{goal}

\end{goals}

\tracingmacros=0

\begin{goal}{twosecond}
spend time on content, not \LaTeX
\end{goal}

\section{two-one}
stuff\index{stuff}
Reference to a chapter 11 goal: \gref{elevenfirst}

\setcounter{chapter}{10}
\chapter{ELEVEN}

\begin{goal}{elevenfirst}
have fun in any case\index{fun}
\end{goal}

Chapter contents here, referring to some goals:

\setcounter{section}{1}

\section{whatever}

Reference to a chapter 2 goal: \gref{twosecond}

Reference to a chapter 11 goal: \gref{elevenfirst}

\setcounter{section}{10}
\section{another}

Second reference to a chapter 2 goal: \gref{twofirst}

\printindex[goals]
\printindex

\end{document}

-
Would you please explain better the problem? –  egreg Jul 17 '12 at 20:33
@egreg The goals from chapter 11 (11.1, 11.2 etc.) come before those from chapter 2 (2.1, 2.2 etc.) since 11 precedes 2 in alphabetic (but not numerical) order. If there were more than 9 goals in any single chapter I would predict similar misbehavior (but haven't tested in the MWE). –  Ethan Bolker Jul 17 '12 at 23:33

You have to format the entries in such a way that the alphabetization is correct. So I use a trick:

\documentclass[12pt]{book}

\usepackage{amsthm}
\usepackage{environ}
\usepackage{imakeidx}
\usepackage{refcount}
\usepackage{hyperref}

\makeindex[intoc]
\makeindex[name=goals,title=Goal References,columns=1,intoc]

\makeatletter
\newcommand{\gref}[1]{%
[Goal~\ref{goal:#1}]
\edef\@goal@number{\getrefnumber{goal:#1}}%
\edef\@the@section{\thesection}%
\index[goals]{Goal~\expandafter\sortgref\@goal@number.0\sortgref!%
\expandafter\sortgref\@the@section.0\sortgref @%
Section~\thesection}%
}
\def\sortgref#1.#2#3\sortgref{%
\ignoresort{\ifnum#1<10 0\fi#1.\ifnum#2<10 0\fi#2}#1.#2%
}
\protected\def\ignoresort#1{}

\newcommand\l@goal[1]{%
\vskip \z@ \@plus \p@
\begingroup
\parindent\z@
\rightskip\@pnumwidth
\parfillskip-\@pnumwidth
\leavevmode #1\nobreak\hfil\nobreak\null\par
\penalty\@highpenalty
\endgroup}

% arrange goal numbering by chapter
\newtheorem{Goal}{Goal}[chapter]

% define a shorthand to be able to get at \BODY with \expandafter
\newcommand\indexgoal[1]{\edef\@goal@number{\theGoal}%
\goalindex[goals]{Goal~\expandafter\sortgref\@goal@number.0\sortgref! #1}}

% save a copy of \index
\let\goalindex\index
\NewEnviron{goal}[1]{%
\begin{Goal}
\label{goal:#1}%
% here we neutralize \index so that it won't do damages
\begingroup
\renewcommand\index[2][]{}%
% but the main command uses \goalindex, so it's safe
\expandafter\indexgoal\expandafter{\BODY}%
\endgroup
%{\em label:} #1 %comment in/out to restore/suppress printing label
\normalfont{}\noindent
\BODY
}
[\end{Goal}]
\makeatother

\newenvironment{goals}
{%
{\textbf Chapter goals:}
}
{}

\begin{document}

\tableofcontents{}

\setcounter{chapter}{1}
\chapter{TWO}

\tracingmacros=1

\begin{goals}

\begin{goal}{twofirst}
\end{goal}

\end{goals}

\tracingmacros=0

\begin{goal}{twosecond}
spend time on content, not \LaTeX
\end{goal}

\section{two-one}
stuff\index{stuff}
Reference to a chapter 11 goal: \gref{elevenfirst}

\setcounter{chapter}{10}
\chapter{ELEVEN}

\begin{goal}{elevenfirst}
have fun in any case\index{fun}
\end{goal}

Chapter contents here, referring to some goals:

\setcounter{section}{1}

\section{whatever}

Reference to a chapter 2 goal: \gref{twosecond}

Reference to a chapter 11 goal: \gref{elevenfirst}

\setcounter{section}{10}
\section{another}

Second reference to a chapter 2 goal: \gref{twofirst}

\printindex[goals]
\printindex

\end{document}


The in goals.idx you'll find

\indexentry{Goal\nobreakspace  {}\ignoresort {02.01}2.1! learn more \LaTeX  |hyperpage}{3}
\indexentry{Goal\nobreakspace  {}\ignoresort {02.02}2.2! spend time on content, not \LaTeX  |hyperpage}{3}
\indexentry{Goal\nobreakspace  {}\ignoresort {11.01}11.1!\ignoresort {02.01}2.1@Section\nobreakspace  {}2.1|hyperpage}{3}
\indexentry{Goal\nobreakspace  {}\ignoresort {11.01}11.1! have fun in any case\index {fun}|hyperpage}{5}
\indexentry{Goal\nobreakspace  {}\ignoresort {02.02}2.2!\ignoresort {11.02}11.2@Section\nobreakspace  {}11.2|hyperpage}{5}
\indexentry{Goal\nobreakspace  {}\ignoresort {11.01}11.1!\ignoresort {11.02}11.2@Section\nobreakspace  {}11.2|hyperpage}{5}
\indexentry{Goal\nobreakspace  {}\ignoresort {02.01}2.1!\ignoresort {11.01}11.1@Section\nobreakspace  {}11.11|hyperpage}{5}


so that the sorting will be done correctly: here is goals.ind

\begin{theindex}

\item Goal\nobreakspace  {}\ignoresort {02.01}2.1
\subitem Section\nobreakspace  {}11.11, \hyperpage{5}
\item Goal\nobreakspace  {}\ignoresort {02.02}2.2
\subitem Section\nobreakspace  {}11.2, \hyperpage{5}
\subitem  spend time on content, not \LaTeX  , \hyperpage{3}
\item Goal\nobreakspace  {}\ignoresort {11.01}11.1
\subitem Section\nobreakspace  {}2.1, \hyperpage{3}
\subitem Section\nobreakspace  {}11.2, \hyperpage{5}
\subitem  have fun in any case\index {fun}, \hyperpage{5}

\end{theindex}


The \ignoresort macro does nothing with its argument, so the entries will be printed without padding zeros.

-