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 need a list like the list of figures for \ref entries in the text to instances of a custom Theorem environment. Here's a MWE with a handbuilt example. The solution should add features to this code I built using the answer to write contents of an environment to document and toc.

\documentclass[12pt]{book}

\usepackage{amsthm}
\usepackage{environ}
\usepackage{hyperref}

\newcommand{\gref}[1]{%
   [Goal~\ref{goal:#1}]
}

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

\newcommand{\egregaddtocontents}[1]{%
  \addtocontents{toc}{\protect\l@goal{#1}}}

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

\NewEnviron{goal}[1]{%
\begin{Goal}
\label{goal:#1}
%{\em label:} #1 %comment in/out to restore/suppress printing label
\normalfont{}\noindent
\BODY
\egregaddtocontents{\BODY}
}
[\end{Goal}]
\makeatother

\begin{document}

\tableofcontents{}

\chapter{First}

\begin{goal}{firstfirst}
learn more \LaTeX
\end{goal}

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

stuff

\chapter{Second}

\begin{goal}{secondfirst}
have fun in any case
\end{goal}

Chapter contents here, referring to some goals:
\section{whatever}

Reference to a chapter 1 goal: \gref{firstsecond}

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

\section{another}

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

\chapter*{List of Goal References}

Built by hand, should be automated. Format not yet specified.

\begin{itemize}
\item \gref{firstfirst} 
learn more \LaTeX

\item \gref{firstsecond} 
spend time on content, not \LaTeX
\begin{itemize}
\item Section 2.1, page 5 [link to that page]
\end{itemize} 

\item \gref{secondfirst} 
have fun in any case
\begin{itemize}
\item Section 2.1, page 5 [link to that page]
\item Section 2.2, page 5 [link to that page]
\end{itemize}

\end{itemize}
\end{document}

Here's the list from the MWE. The format is \itemize but that's just temporary - the solution should allow me to change it easily.

handbuilt list of goals

Perhaps there's already a package that does the job. If not, perhaps build on top of or cannibalize code that creates the index and the list of figures, since I require features from both.

share|improve this question
    
Maybe this could be interesting for you: tex.stackexchange.com/a/49597/10570. I think it is very similar to your problem. –  Holle Jun 23 '12 at 22:10
    
@Holle That's certainly promising. My application seems to call for a list of lists, with back references. I might be able to use tocloft to write that myself and answer my own question - but I hope someone else finds the challenge entrancing before I get around to it. –  Ethan Bolker Jun 23 '12 at 22:17
    
@Holle You could have pointed me at this too: tex.stackexchange.com/questions/32401/…. Now someone (you or me or someone else) can combine this backreference solution with the list solution ... –  Ethan Bolker Jun 23 '12 at 22:34
    
Just use the hyperref-package in the tocloft-example from my first comment. With this package the table entries are hyperlinks back to the text. –  Holle Jun 25 '12 at 7:43

3 Answers 3

up vote 5 down vote accepted

There are some adjustments to be made. Here's something that should work

\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 \arabic{chapter}.\arabic{section}}
}

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

\newcommand{\egregaddtocontents}[1]{%   
  \addtocontents{toc}{\protect\l@goal{#1}}}

% 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}%
   \egregaddtocontents{\BODY}
   \endgroup
   %{\em label:} #1 %comment in/out to restore/suppress printing label
   \normalfont{}\noindent
   \BODY
}
[\end{Goal}]
\makeatother

\begin{document}

\tableofcontents{}

\chapter{First}

\tracingmacros=1

\begin{goal}{firstfirst} 
learn more \LaTeX
\end{goal}

\tracingmacros=0

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

stuff\index{stuff}

\chapter{Second}

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

Chapter contents here, referring to some goals:
\section{whatever}

Reference to a chapter 1 goal: \gref{firstsecond}

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

\section{another}

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

\printindex[goals]
\printindex

\end{document}

I've used refcount and \getrefnumber, otherwise \index would produce different entries.

share|improve this answer

This is so close to a complete solution, built following Holle's index suggestion and using egreg's imakidx package, that I decided to post it as an answer rather than as an edit to the question. Still missing:

  • the ability to expand the \BODY macro from the environ package inside the call to \index,
  • guarantee that the expanded \BODY always appears first under its goal in the Goal References index, Edit: starting the index with a blank space before \BODY fixes this. Incorporate in in egreg's accepted answer.
  • single column output for that index. Edit: deleting idxlayout package fixes this.

Here's the output from the MWE below, which isn't quite "minimal" since I need to make sure that other features still work.

almost right goals index

\documentclass[12pt]{book}

\usepackage{amsthm}
\usepackage{environ}
\usepackage{imakeidx}
\usepackage[totoc]{idxlayout}
\usepackage{hyperref}

\makeindex

%% columns=1 isn't working
\makeindex[name=goals,title=Goal References,columns=1]

\newcommand{\gref}[1]{%
   [Goal~\ref{goal:#1}]
   \index[goals]{Goal~\ref{goal:#1}!Section \arabic{chapter}.\arabic{section}}
}

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

\newcommand{\egregaddtocontents}[1]{%   
  \addtocontents{toc}{\protect\l@goal{#1}}}

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

\NewEnviron{goal}[1]{%
\begin{Goal}
   \label{goal:#1}
   \index[goals]{Goal~\ref{goal:#1}!BODY here}
   %{\em label:} #1 %comment in/out to restore/suppress printing label
   \normalfont{}\noindent
   \BODY
   \egregaddtocontents{\BODY}
}
[\end{Goal}]
\makeatother

\begin{document}

\tableofcontents{}

\chapter{First}

\begin{goal}{firstfirst} 
learn more \LaTeX
\end{goal}

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

stuff\index{stuff}

\chapter{Second}

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

Chapter contents here, referring to some goals:
\section{whatever}

Reference to a chapter 1 goal: \gref{firstsecond}

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

\section{another}

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

\printindex[goals]
\printindex

\end{document}
share|improve this answer
    
@egreg Don't know whether it's appropriate to point particular people at particular questions - but if this isn't easy for you then it's really hard. Feel free to finish my answer and post a new one of your own for me to accept and upvote. –  Ethan Bolker Jun 30 '12 at 1:18
    
Do you really want to index something in the body of a goal environment and index the whole contents? –  egreg Jul 1 '12 at 9:00
    
@egreg Yes. The reader can use the separate index of goal references to see where in the text various goals are addressed. That's easier if the index contains the statement of the goal (the BODY), not just the goal number. The BODY text will always be pretty short. Thanks for the good question and the good answer! –  Ethan Bolker Jul 1 '12 at 13:14

I merged your code with the code of the first given example from the comments. Maybe it's what you want.

\documentclass[12pt]{book}
\usepackage{amsthm}
\usepackage{environ}
\usepackage{tocloft}
\usepackage{hyperref}

% create a new list incl. counter
\newlistof{goalsCounter}{goals}{List of \textbackslash goals}

\AtEndDocument{
\cleardoublepage
\listofgoalsCounter% print the list
}

\newcommand{\gref}[1]{%
   [Goal~\ref{goal:#1}]
}

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

\newcommand{\egregaddtocontents}[1]{%
  \addtocontents{toc}{\protect\l@goal{#1}}}

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

%this is new
\refstepcounter{goalsCounter}% step the counter
\addcontentsline{goals}{goalsCounter}{\thegoalsCounter:\quad#1}% add item to list

\begin{Goal}
\label{goal:#1}
%{\em label:} #1 %comment in/out to restore/suppress printing label
\normalfont{}\noindent
\BODY
\egregaddtocontents{\BODY}
}
[\end{Goal}]
\makeatother

\begin{document}

\tableofcontents{}

\chapter{First}

\begin{goal}{firstfirst}
learn more \LaTeX
\end{goal}

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

stuff

\chapter{Second}
\begin{goal}{secondfirst}
have fun in any case
\end{goal}

Chapter contents here, referring to some goals:
\section{whatever}
Reference to a chapter 1 goal: \gref{firstsecond}
Reference to a chapter 2 goal: \gref{secondfirst}
\section{another}
Second reference to a chapter 2 goal: \gref{secondfirst}    
\end{document}

But I don't know why you use the (complicated) \l@goal. I think the tocloft package do the same job. But maybe you have special reasons for this. In the following example is a solution only with the tocloft package.

\documentclass{book}
\usepackage{tocloft}
\usepackage{hyperref}

% create a new list incl. counter
\newlistof{goalsCounter}{goals}{List of \textbackslash goals}

% a new goal reference command
\newcommand{\goalRef}[1]{ [Goal~\ref{goal:#1}]}

\newenvironment{goal}[1]{%
    \refstepcounter{goalsCounter}% step the counter
    \addcontentsline{goals}{goalsCounter}{\thegoalsCounter:\quad#1}% add item to list
    \addcontentsline{toc}{section}{Goal \thegoalsCounter: #1}% add item to the toc
    \label{goal:#1}\textbf{Goal \thegoalsCounter\ #1:}\quad%
}

\AtEndDocument{\listofgoalsCounter}% print the list

\begin{document}

\tableofcontents

\chapter{First}
\begin{goal}{FirstFirst}
learn more \LaTeX
\end{goal}
\begin{goal}{FirstSecond}
spend time on content, not \LaTeX
\end{goal}
stuff
\chapter{Second}
\begin{goal}{SecondFirst}
have fun in any case
\end{goal}

Chapter contents here, referring to some goals:
\section{whatever}
Reference to a chapter 1 goal: \goalRef{FirstSecond}\\
Reference to a chapter 2 goal: \goalRef{SecondFirst}
\section{another}
Second reference to a chapter 2 goal:\goalRef{SecondFirst}
\end{document}

Solution example with the tocloft package

share|improve this answer
    
This is a start. But what I need (as in the MWE) is a list of goals with their text, each entry followed by a list of references to that goal, with page numbers and links. Your answer also changes the TOC format from my MWE. I think a solution could be built with two indexes, one normal, one for goals - see tex.stackexchange.com/questions/472/…. –  Ethan Bolker Jun 25 '12 at 13:05
    
@EthanBolker: Because you wrote: 'I need a list like the list of figures' I provided this example. I think you don't need a 'List of goals' but you need a 'Index of goals'. I'm right? If so you should use the index or the splitindex package. If you are interested in LuaLaTeX this could be an approach: tex.stackexchange.com/a/55321/10570. Here you can create an 'index' and format the index entries like you want. –  Holle Jun 25 '12 at 13:31
    
Yes, an index of goals is indeed what I want - as I realized last night and indicated in my previous comment. I will work on that solution when I get a chance. Thanks for your help. I don't use LuaLaTeX and will probably try this without its tools. –  Ethan Bolker Jun 25 '12 at 13:54

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.