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):

  1. Conjure up a label name that you won't use in your document, ever. Something like fig:was:used:in:doc.
  2. Patch the figure environment to define an empty command (say) \there@is@a@figure at the end of every figure. This is possible using the etoolbox 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.

  3. 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}
    
  4. 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>.

  5. Use \conditionalLoF instead of \listoffigures.
  6. 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

enter image description here

Uncommenting the figure environment and compiling a couple of times produces

enter image description here


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}