# Creating lists of figures based on groups

Friends, consider the following code:

\documentclass{article}

\usepackage{graphicx}
\usepackage{lipsum}

\begin{document}

\listoffigures

\newpage

\lipsum[2]

\begin{figure}[h]
\centering
\includegraphics{imgs/shark.png}
\caption{A shark.}
\label{fig:shark}
\end{figure}

\lipsum[2]

\begin{figure}[h]
\centering
\includegraphics{imgs/duck.png}
\caption{A duck.}
\label{fig:duck}
\end{figure}

\lipsum[2]

\begin{figure}[h]
\centering
\includegraphics{imgs/elephant.png}
\caption{An elephant.}
\label{fig:elephant}
\end{figure}

\lipsum[2]

\end{document}


Basically, I have some text and three figures, as seen in the output:

I also have a \listoffigures:

I was wondering if it's possible to create lists of figures based on groups. For instance, group those animals by their habitat:

First list of figures

Animals that live in water

1 . A shark. ................. 2

Second list of figures

Animals that live in land

2 . A duck. ................. 2

3 . An elephant. ........ 2

I'm also wondering if it's possible to have intersections, e.g., the duck could be in both lists. I was thinking if there is some magical command like this:

...
\magicalcommandhere{water}
\includegraphics{imgs/shark.png}
...
\magicalcommandhere{water,land}
\includegraphics{imgs/duck.png}
...
\magicalcommandhere{land}
\includegraphics{imgs/elephant.png}
...
\magicallist{water}
\magicallist{land}
...


I was thinking on the float package for my first attempt, but I'm not sure if it's the right choice.

Any ideas?

-
Would this help tex.stackexchange.com/questions/19828/… – Yiannis Lazarides Jun 17 '11 at 17:13
Thanks @Yiannis, it seems promising. =) – Paulo Cereda Jun 17 '11 at 17:29

\documentclass[a4paper]{book}

\makeatletter
\newcommand\newkind[2]{%
\protected\def\div@water{}
\protected\def\div@land{}
\def\divcaption#1#2{\caption{#2}% generate the caption and the number
\def\div@list{#1}%
\@for\next:=\div@list\do
{\edef\div@write{\write\tf@divided{\csname div@\next\endcsname{%
\unexpanded{\noexpand\contentsline{figure}}
{\unexpanded{\noexpand\numberline}{\thefigure}{\ignorespaces
\unexpanded{#2}}}{\unexpanded{\thepage}}}}}\div@write}
}
\newcommand{\categorize}[1]{\def\div@list{#1}%
\@for\next:=\div@list\do{\global\@namedef{div@kind@\next}{}}
\chapter{\listfigurename}
\@input{\jobname.div}
\@for\next:=\div@list\do{\expandafter\div@print\expandafter{\next}}
\if@filesw
\newwrite\tf@divided
\immediate\openout\tf@divided=\jobname.div\relax
\fi
}
\makeatletter

\newkind{water}{Animals living in water}
\newkind{land}{Animals living on land}

\begin{document}
\frontmatter
\categorize{water,land}

\mainmatter
\chapter{Pippo}
\begin{figure}
\divcaption{water}{Whale}
\end{figure}
\begin{figure}
\divcaption{water,land}{Duck}
\end{figure}
\end{document}


Of course this needs some refinement.

It works by defining a new output stream into which we write an entry similar to that of the .lof file, but given as argument to a suitable macro; for instance, \divcaption{land}{Tiger} would write

\div@land{\contentsline{figure}{\numberline{1}{\ignorespaces Tiger}{2}}


assuming it's figure 1 on page 2. For \divcaption{water,land}{Frog} we'd get two lines:

\div@water{\contentsline{figure}{\numberline{2}{\ignorespaces Frog}{4}}
\div@land{\contentsline{figure}{\numberline{1}{\ignorespaces Frog}{4}}


The file is read by the \categorize command in the same way that's read the list of figures. This command takes as argument the comma separated list of "kinds", in the order in which we want them listed. The commands \div@water and \div@land add their argument to a container for each kind and, when the file is completely read in, the containers are expanded, which cause the printing of a header, followed by the entries. The kind is defined beforehand with \newkind{name}{header}.

-
egreg, this code is very impressive. You managed to write it without the use of additional packages. For me, it's a great chance to learn more about commands / macros. I managed to (partially) solve it by using tocloft based on Yiannis' suggestion and caption from Gonzalo's answer, and your answer seems to complete them. Thanks! – Paulo Cereda Jun 18 '11 at 0:15

With the help of the caption package you can achieve what you desire. The idea is to declare a new caption type for each category, and then to use \captionof and \addcontentsline to decide in which list(s) should the corresponding entry go. A little example:

\documentclass{article}
\usepackage{caption}

\DeclareCaptionType[fileext=wat]{water}[Figure][Animals that live in water]
\DeclareCaptionType[fileext=lan]{aland}[Figure][Animals that live in land]

\begin{document}
\listoffigures
\listofwaters
\listofalands

\begin{figure}[!ht]
\centering
A shark
\captionof{water}{A shark}
\label{fig:shark}
\stepcounter{aland}
\stepcounter{figure}
\end{figure}

\begin{figure}[!ht]
\centering
A duck
\captionof{aland}{A duck}
\label{fig:duck}
\stepcounter{water}
\stepcounter{figure}
\end{figure}

\begin{figure}[!ht]
\centering
An elephant
\captionof{aland}{An elephant}

Thanks a lot, Gonzalo, it works perfectly. I made some progress with the tocloft package based on the related question Yiannis suggested, but your approach is surely more consistent than mine. =) – Paulo Cereda Jun 17 '11 at 20:46