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.

Suppose, I have the following code:

\documentclass{article}
\begin{document}
We have totally 7 columns, describing the user:
\begin{enumerate}
\item ID --- users.name
\item Forename --- users\_profiles.first\_name
\item Surname --- users\_profiles.last\_name
\item Email --- users.mail
\item Primary Service --- services.name
\item Start date --- FROM\_UNIXTIME(users.created)
\item Employment Status --- users\_profiles.employment\_status
\end{enumerate}
\end{document}

Producing this document:

enter image description here

Is it possible to set the value 7 automatically, depending upon number of elements in the list? The problem is, that it resides before the list.

share|improve this question
    
Related: How to make enumerate items align at left margin? - it uses a similar technique to Alan's answer to adjust the width of the label. –  Werner Dec 17 '12 at 21:56
add comment

2 Answers

up vote 11 down vote accepted

Just put a label after the last item and refer to that in the text:

\documentclass{article}
\begin{document}
We have \ref{last} columns, describing the user:
\begin{enumerate}
\item ID --- users.name
\item Forename --- users\_profiles.first\_name
\item Surname --- users\_profiles.last\_name
\item Email --- users.mail
\item Primary Service --- services.name
\item Start date --- FROM\_UNIXTIME(users.created)
\item Employment Status --- users\_profiles.employment\_status \label{last}
\end{enumerate}
\end{document}
share|improve this answer
    
this does require a second run of the file, but it's vanishingly rare that there's no second (or further) run. –  barbara beeton Dec 17 '12 at 14:30
    
@barbarabeeton yeah, second run is pretty annoying. Does anybody know, how to get rid of it? –  user4035 Dec 17 '12 at 16:16
1  
There's no way to avoid this, but it's likely that your document has other references that need to be reconciled anyway. If you're worried about forgetting to run latex the required number of times, there are Tools for automating document compilation. For TeXLive installations, latexmk is good; MikTeX also has texify and there is also the relatively new, but very powerful arara. –  Alan Munn Dec 17 '12 at 18:32
    
@AlanMunn your variant works perfectly, when there is only 1 list. But what to do, when we have several lists? When I tried your code, it gives the number of elements in the last list everywhere. –  user4035 Jan 22 '13 at 6:12
1  
@user4035 Since the system uses labels, you need a unique label for each list you want to do this with. So if you have n lists, you need n distinct "last" labels, which you could label last1, last2 etc. or alternatively use more descriptive labels that identify the lists themselves (UserList-last, FunctionAList-last etc). –  Alan Munn Jan 22 '13 at 13:25
add comment

The \label-\ref mechanism is the way to go for this kind of applications; in this case some tweaking is necessary for ensuring that we get a plain number.

I'll present two possibilities. In both I use \numberstringnum from fmtcount to produce the number in words, which is better style.

Recommended form

We use a refenumerate environment that has a label (an arbitrary string) as argument, to be used as argument of \getenumcount, which produces the number.

\documentclass{article}

\usepackage{xparse,fmtcount,refcount}

\makeatletter
\NewDocumentEnvironment{refenumerate}{m}
 {\begin{enumerate}}
 {\edef\@currentlabel{\arabic{\@enumctr}}\label{#1}\end{enumerate}}
\makeatother
\newcommand{\getenumcount}[1]{\numberstringnum{\getrefnumber{#1}}}

\begin{document}

\section*{Recommended form}

We have \getenumcount{profile} columns, describing the user:
\begin{refenumerate}{profile}
\item ID --- users.name
\item Forename --- users\_profiles.first\_name
\item Surname --- users\_profiles.last\_name
\item Email --- users.mail
\item Primary Service --- services.name
\item Start date --- FROM\_UNIXTIME(users.created)
\item Employment Status --- users\_profiles.employment\_status
\end{refenumerate}

Pros

The refenumerate environment can be used at any nesting level

Cons

It requires two runs of LaTeX. This is actually not a big deal, because it's quite rare that one run suffice (think to the table of contents, or any cross reference).

enter image description here

Not recommended form

We use a getreference environment that encloses all code from the start of the paragraph with the reference up to the enumerate environment we want to count the items of.

\documentclass{article}

\usepackage{fmtcount,environ}
\makeatletter
\NewEnviron{getreference}
 {\let\latex@label\label\let\label\@gobble\global\let\printnumber\relax
  \setbox0=\vbox{\@tempswafalse\if@nobreak\@tempswatrue\fi
    \BODY\xdef\printnumber{\noexpand\numberstringnum{\number\value{enumi}}}
    \if@tempswa\aftergroup\@afterheading\fi
  }%
  \let\label\latex@label
  \BODY}
\makeatother

\begin{document}

\section*{Not recommended form}

\begin{getreference}
We have \printnumber{} columns, describing the user:
\begin{enumerate}
\item ID --- users.name
\item Forename --- users\_profiles.first\_name
\item Surname --- users\_profiles.last\_name
\item Email --- users.mail
\item Primary Service --- services.name
\item Start date --- FROM\_UNIXTIME(users.created)
\item Employment Status --- users\_profiles.employment\_status
\end{enumerate}
\end{getreference}
\end{document}

Pros

One LaTeX run is required.

Cons

Only one level can be counted, precisely the outermost enumerate environment.

enter image description here

share|improve this answer
add comment

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.