How to determine whether a list of figures is empty, then not show it at all?
The idea behind this attempt is to use standard LaTeX references in order to detect whether a figure
was used in the document. Here are the steps involved (with some modifications by @egreg):
- Conjure up a label name that you won't use in your document, ever. Something like
fig:was:used:in:doc
. Patch the
figure
environment to define an empty command (say)\there@is@a@figure
at the end of every figure. This is possible using theetoolbox
package which provides\AtEndEnvironment
. More specifically, the command\AtEndEnvironment{figure}{\gdef\there@is@a@figure{}}
will be perpetually redefined until the last
figure
in the document.At the end of the document, we check whether
\there@is@a@figure
exists (is defined), and define a label\label{fig:was:used:in:doc}
. It doesn't really matter what this label contains (it could be the last used figure, section, table, or whatever):\AtEndDocument{\ifdefined\there@is@a@figure\label{fig:was:used:in:doc}\fi}
Write your own "conditional LoF" command using
\newcommand{\conditionalLoF}{\@ifundefined{r@fig:was:used:in:doc}{}{\listoffigures}}%
The command
\conditionalLoF
checks whether the macro\r@fig:was:used:in:doc
is defined or not. This is the standard LaTeX referencing mechanism at work, since each label<lab>
has an associated macro\r@<lab>
defined.\@ifundefined{<cs>}{<undef code>}{<def code>}
allows execution of<undef code>
if<cs>
is undefined, otherwise execute<def code>
.- Use
\conditionalLoF
instead of\listoffigures
. - Compile your document at least 3 times.
The main idea behind (1) is to have the label fig:was:used:in:doc
only exist when using a figure
, and not having to worry about what it is called. (2) provides the hook to the figure
environment and allows a global (re)definition of \there@is@a@figure
. (3) delays the definition of the fig:was:used:in:doc
label until the end of the document in order to avoid causing "Multiply defined label" warnings. (4) and (5) provides a clean interface to the conditional LoF. (6) may be the only drawback. However, this comes standard with label referencing, requiring at least two compiles to work in general.
Here's a minimal working example (MWE). It uses graphicx
(with the demo
package option) and lipsum
merely for show and is therefore actually not necessary. Compiling this MWE
\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\usepackage[demo]{graphicx}% http://ctan.org/pkg/graphicx
\usepackage{lipsum}% http://ctan.org/pkg/lipsum
\makeatletter
\AtEndEnvironment{figure}{\gdef\there@is@a@figure{}}
\AtEndDocument{\ifdefined\there@is@a@figure\label{fig:was:used:in:doc}\fi}
\newcommand{\conditionalLoF}{\@ifundefined{r@fig:was:used:in:doc}{}{\listoffigures}}%
\makeatother
\begin{document}
\conditionalLoF% Conditionally insert List of Figures
\section{First section}
\lipsum[1]
%\begin{figure}
% \centering\includegraphics{figure}
% \caption{This is a caption}
%\end{figure}
\end{document}
as-is produces
Uncommenting the figure
environment and compiling a couple of times produces
A different approach is using the totalcount
package:
\documentclass{article}
\usepackage[demo]{graphicx}% http://ctan.org/pkg/graphicx
\usepackage{lipsum}% http://ctan.org/pkg/lipsum
\usepackage[figure]{totalcount}
\begin{document}
% Conditionally insert List of Figures
\iftotalfigures
\listoffigures
\fi
\section{First section}
\lipsum[1]
%\begin{figure}
% \centering\includegraphics{figure}
% \caption{This is a caption}
%\end{figure}
\end{document}
Here's a combination of totcount
and assoccnt
(it's combined in xassoccnt
now, at least some features of totcount
)
xassoccnt
defines counters that step with a master counter, say figure
but are not reset if figure
is set to zero, i.e. the totalfigures
counter holds the total number of figures (unless manipulated directly).
Using the \NewTotalDocumentFeature
, the value of a total counter is written to the .aux
file at the end of the compilation run and read in in the next run, i.e. the number of figures is known at the start of the document.
Werner used the refcount
approach together with assoccnt
(which is the predecessor of xassoccnt
, which is much more developed than assoccnt
(I know about the states -- I am the author of (x)assoccnt
;-))
I redefined the \listof...
commands slightly.
\documentclass{book}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{xassoccnt}
\usepackage{graphicx}
\usepackage{tabularx}
\NewTotalDocumentCounter{totalfigures}
\NewTotalDocumentCounter{totaltables}
\DeclareAssociatedCounters{figure}{totalfigures}
\DeclareAssociatedCounters{table}{totaltables}
\makeatletter
\renewcommand{\TotalValue}[1]{% A small bug fix
\value{xassoccnt@total@#1}%
}
\let\@@latex@@listoffigures\listoffigures
\let\@@latex@@listoftables\listoftables
\renewcommand{\listoffigures}{%
\ifnum\TotalValue{totalfigures} > 0
\@@latex@@listoffigures%
\fi
}
\renewcommand{\listoftables}{%
\ifnum\TotalValue{totaltables} > 0
\@@latex@@listoftables%
\fi
}
\makeatother
\begin{document}
\tableofcontents
\clearpage
\listoftables
\listoffigures
A figure:
\begin{figure}[htbp]
\centering
\includegraphics[width=0.25\linewidth]{example-image-a}
\caption{A picture}
\label{fig:label}
\end{figure}
A table:
\begin{table}[htbp]
\centering
%\caption{A table}
\label{tab:label}
\begin{tabularx}{\linewidth}{lX}
test & test test test test test test test test test test test test test test test test test test test test
\end{tabularx}
\end{table}
\end{document}