LaTeX forum ⇒ General ⇒ Full context variable depth references to list labels?

LaTeX specific issues not fitting into one of the other forums of this category.
kreil
Posts: 11
Joined: Mon Jul 28, 2008 3:38 am

Full context variable depth references to list labels?

Dear Community,

What I try to do is the following: In a document, I will have enumerate lists at varying depths in the section structure, e.g., I will have some enumerate lists that occur within a section, while others occur in a subsection, etc.

I now need to cross-reference them in full context (sometimes called "legal style"), e.g., list item 3 in section 2.1 should be referenced ad "2.1.3", whereas list item 4 in subsection 2.1.1 should be referenced as "2.1.1.4". (Just the in-text reference should be "2.1.1.4". The list item label in the enumerate environment should still read "4", however, and not "2.1.1.4".)
Annoyingly, I can get Microsoft Word to do this but after a full night of google, forum posts, and digging through CTAN, all I can do is either:-
- construct the reference manually after storing the section counters for each label, e.g., through package "smartref"
- extend the label with additional counters, e.g., using the ref= option of package "enumitem"
also, all direct counter redefinitions seem to link one counter directly to a "level" above.
All the above thus do not work to link a list label to the deepest actually used sectioning command in which it is nested.

I'd be most grateful for a pointer.

Many thanks,
David.

kreil
Posts: 11
Joined: Mon Jul 28, 2008 3:38 am
I have read more of the LaTeX source (am I going in the wrong direction there?) and it seems that \@currentlabel holds exactly what I need. I'd now love to save this before starting an enumerate list and prepend it to the item labels.

\def\savecounter{\protected@edef\savedlabel\@currentlabel}

would store the current label in \savecounter but I can tell that this does not work. Clearly, I don't understand what the above code does and "coding by analogy" from the latex source was apparently not a good strategy.

I had hoped to then say something like

\item\copycounter\label{foo}

to add the saved sectioning label back in front of the new item label, with something like

\def\copycounter{\protected@edef\@currentlabel{\savedlabel-\@currentlabel}}

but, again, this does not do what I thought it should.

David.

Ted
Posts: 94
Joined: Sat Jun 23, 2007 4:11 pm
Location: Columbus, OH
Contact:
UPDATE: Make sure you see my response to this message. It's a much cleaner solution

kreil wrote:I'd be most grateful for a pointer.
See the enumitem package:

This works well for me (though I think there are more compact solutions):
\begin{enumerate}         \item First item                 \begin{enumerate}[label={\theenumi.\arabic*.}]                         \item Second item                                  \begin{enumerate}[label={\theenumii\arabic*.}]                                         \item\label{item:last} Last item                                 \end{enumerate}                 \end{enumerate}\end{enumerate} Here is a reference: \ref{item:last}
Of course, make sure
\usepackage{enumitem}
exists in the preamble.
Last edited by Ted on Mon Jul 28, 2008 4:26 pm, edited 1 time in total.
-- Ted [home/blog]

Ted
Posts: 94
Joined: Sat Jun 23, 2007 4:11 pm
Location: Columbus, OH
Contact:
Ted wrote:
kreil wrote:I'd be most grateful for a pointer.
See the enumitem package:

Consulting the documentation, it gives the legal case as an example. Put in your preamble:
\usepackage{enumitem}\newlist{legal}{enumerate}{10}\setlist[legal]{label*=\arabic*.}
That lets you use a "legal" enumeration environment:
\begin{legal}         \item First item                 \begin{legal}                         \item Second item                                  \begin{legal}                                         \item\label{item:last} Last item                                 \end{legal}                 \end{legal}\end{legal} Here is a reference: \ref{item:last}
I hope that helps.
-- Ted [home/blog]

kreil
Posts: 11
Joined: Mon Jul 28, 2008 3:38 am
Dear Ted!

Many thanks for your comments. The problem is that unless I manually construct a combined label, I cannot easily combine section and enumerate labels.

My best bet so far has been the following:

\usepackage{enumitem} \makeatletter\def\sc{\protected@edef\savedlabel{\@currentlabel\relax\relax}}\def\cc{\protected@edef\@currentlabel{\savedlabel-\@currentlabel}}\makeatother

Which allows me to "save counter" (\sc), say, after a new subsection command.
I can then recall this and add it to a particular item label by "copy counter" (\cc).
For example:

\section{foo}\subsection{bar}\sc\begin{enumerate}\item aaa\item\cc\label{mine} bbb\end{enumerate}\section{foo too}It is \ref{mine}.  % will give 1.1-2 to refer to item 2 in subsection 1.1

So this works now after about 8h of fiddling (the "\relax" took me ages to figure out) but it is still very manual.
Attempts to automate further, e.g., by doing a
\def\longlabel#1{\cc\label#1}

or such still fail. Again, that's of course a result of coding by analogy rather than understanding. So if someone knows of a package that solves this better, or actually understands any of the above code then I'd be grateful for a hint!

Many thanks,
David.

Ted
Posts: 94
Joined: Sat Jun 23, 2007 4:11 pm
Location: Columbus, OH
Contact:
UPDATE: Be sure to see my response to this message. It's a much cleaner solution.
kreil wrote:Many thanks for your comments. The problem is that unless I manually construct a combined label, I cannot easily combine section and enumerate labels.

Thanks for your patience. I see that I completely overlooked the real problem. To start on a cleaner solution, have you tried
\begin{legal}[ref=\arabic{section}.\arabic*.]         \item\label{item:first} First item                 \begin{legal}[ref=\thelegali\arabic*.]                         \item \label{item:second} Second item                                  \begin{legal}[ref=\thelegalii\arabic*.]                                         \item\label{item:last} Last item                                 \end{legal}                 \end{legal}\end{legal}
(using the definition of legal given above, of course)?

[ Of course, you could change the initial \arabic{section} so that it includes subsections, etc. ]
Last edited by Ted on Mon Jul 28, 2008 5:37 pm, edited 1 time in total.
-- Ted [home/blog]

Ted
Posts: 94
Joined: Sat Jun 23, 2007 4:11 pm
Location: Columbus, OH
Contact:
UPDATE: The firstlegal environment below is NOT needed if you add a
\newcommand{\thelegal}{\thesubsection.}
in the preamble. See a later message in this thread for details. The modification allows you to use legal without any parameters at every level of your enumerated list (including the first one).
---

Ted wrote:Thanks for your patience. I see that I completely overlooked the real problem. To start on a cleaner solution, have you tried...
Here's a better idea...

First, in the preamble:
\usepackage{enumitem}\newlist{legal}{enumerate}{10}\makeatletter\setlist[legal]{label*=\arabic*.,ref=\csname the\enit@prevlabel\endcsname\arabic*.}\makeatother
Then you can do
\begin{legal}[ref=\thesubsection.\arabic*.]         \item\label{item:first} First item                 \begin{legal}                         \item \label{item:second} Second item                                  \begin{legal}                                         \item\label{item:last} Last item                                 \end{legal}                 \end{legal}\end{legal}
So the only special thing you need to do within the document is add that [ref=...] line to the first legal environment. All nested ones are handled without any special arguments.

You can simplify that first legal environment a little... In your preamble, put
\newenvironment{firstlegal}{\begin{legal}[ref=\thesubsection.\arabic*.]}{\end{legal}}
Then you can use
\begin{firstlegal}         \item\label{item:first} First item                 \begin{legal}                         \item \label{item:second} Second item                                  \begin{legal}                                         \item\label{item:last} Last item                                 \end{legal}                 \end{legal}\end{firstlegal}
How does that work for you?
Last edited by Ted on Mon Jul 28, 2008 7:17 pm, edited 2 times in total.
-- Ted [home/blog]

kreil
Posts: 11
Joined: Mon Jul 28, 2008 3:38 am
Dear Ted,

Yes, that looks nice! I tried your approach ...

Ted wrote:First, in the preamble:
\usepackage{enumitem}\newlist{legal}{enumerate}{10}\makeatletter\setlist[legal]{label*=\arabic*.,ref=\csname the\enit@prevlabel\endcsname\arabic*.}\makeatother
Then you can do
\begin{legal}[ref=\thesubsection.\arabic*.]         \item\label{item:first} First item                 \begin{legal}                         \item \label{item:second} Second item                                  \begin{legal}                                         \item\label{item:last} Last item                                 \end{legal}                 \end{legal}\end{legal}
So the only special thing you need to do within the document is add that [ref=...] line to the first legal environment. All nested ones are handled without any special arguments.

Are the inner loops supposed to inherit the ref from the outer loops? That doesn't seem to work for me. A label/ref to the outer loop works fine but the inner loops just have the "normal" legal style refs.

What works quite nicely is substituting the first line with
   \begin{legal}[ref=\savedlabel-\arabic*.]

Together with the "\sc" save counter macro I posted above, this makes the first loop start from the section nesting level where the save counter macro was last applied.

So if we could get the inner loops to inherit that would be great!

Best wishes,
David.

Ted
Posts: 94
Joined: Sat Jun 23, 2007 4:11 pm
Location: Columbus, OH
Contact:
kreil wrote:Yes, that looks nice! I tried your approach ...
kreil wrote:Are the inner loops supposed to inherit the ref from the outer loops?
Yes, they are. It's in the \setlist. The \csname should cause the previous label to built into the refs.
kreil wrote:That doesn't seem to work for me. A label/ref to the outer loop works fine but the inner loops just have the "normal" legal style refs.
It works for me. Here's a (working) complete example:
\documentclass{article} \usepackage{enumitem}\newlist{legal}{enumerate}{10}\makeatletter\setlist[legal]{label*=\arabic*.,ref=\csname the\enit@prevlabel\endcsname\arabic*.}\makeatother \newenvironment{firstlegal}{\begin{legal}[ref=\thesubsection.\arabic*.]}{\end{legal}} \begin{document} \section{First section} First: \ref{item:first}\\Second: \ref{item:second}\\Third: \ref{item:last} \section{Second section}\subsection{A subsection}\subsection{Another subsection} \begin{firstlegal}         \item An item          \item Another item          \item\label{item:first} First labeled item                 \begin{legal}                         \item \label{item:second} Second item                                  \begin{legal}                                         \item\label{item:last} Last item                                 \end{legal}                 \end{legal}\end{firstlegal} \end{document}
That produces:
First: 2.2.3.
Second: 2.2.3.1.
Third: 2.2.3.1.1.
which is what I THINK you want. Right?
-- Ted [home/blog]

kreil
Posts: 11
Joined: Mon Jul 28, 2008 3:38 am
Perfect!

Many thanks, I don't know what I got wrong when I first tried. The below does exactly what I want (even semi-automatically picks up the section level).

Thanks a lot again for your help!

All the best,
David.

\documentclass{article} \usepackage{enumitem}\newlist{legal}{enumerate}{10}\makeatletter\def\sc{\protected@edef\savedlabel{\@currentlabel\relax\relax}}\setlist[legal]{label*=\arabic*.,ref=\csname the\enit@prevlabel\endcsname\arabic*.}\makeatother\newenvironment{firstlegal}{\begin{legal}[ref=\savedlabel-\arabic*.]}{\end{legal}} \begin{document} \section{First section} First: \ref{item:first}\\Second: \ref{item:second}\\Third: \ref{item:last} \section{Second section}\subsection{A subsection}\subsection{Another subsection}\sc \begin{firstlegal}         \item An item         \item Another item         \item\label{item:first} First labeled item                 \begin{legal}                         \item \label{item:second} Second item                                  \begin{legal}                                         \item\label{item:last} Last item                                 \end{legal}                 \end{legal}\end{firstlegal} \end{document}