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.

I have created a simple template for someone with the table of content added to the first page as follow

\begin{document}
    % title and date here 
    \maketitle
    \tableofcontents
    \indent \newline
    %  
\end{document} 

But I figure out that someone don't add anything to the table of contents but there will be a word "Contents" shown in the document even the table is empty. Is that anyway I check in advance whether the table of contents is empty or not so to decide what to do next? Thanks.

share|improve this question
    
My intuition tells me that you have to check if the the .toc file is empty or not. I'm not an expert of conditional statements in latex but maybe you can file some information here –  Pouya Jan 23 '13 at 9:03
    
Thanks for your replies. To Pouya, since the latex will be run via php calling on the server side. I am wondering if that's possible for some case the .toc has not been cleaned so leads to a misleading judge? Well, buy the way, I don't know how to check the file remotely on the server too :( –  user1285419 Jan 23 '13 at 9:07

2 Answers 2

up vote 4 down vote accepted

I am updating this answer to provide a more flexible method, which assumes nothing about what the title of the table of contents is supposed to look like. As in my original answer, the point is that testing for existence or emptiness of the .toc file is not enough. With babel for example, there will always be some stuff in this file. Thus, we check if the file contains at least one \contentsline instance. In the new answer, the package etoc is used because it stores the contents of the .toc file in some internal register which we can check and then we set accordingly a toggle. Then \tableofcontents is redefined to first check this toggle. As long as etoc is left like here in compatibility mode, it will not modify the looks of the TOC. If tocloft is used it must be loaded before etoc.

\documentclass{article}
\usepackage[french]{babel} % for testing
\usepackage{hyperref}      % for testing

% Testing if the .toc file exists is not sufficient, (with Babel, there
% will be some info added to it automatically). We need to make
% sure it doesn't contain some \contentsline
\usepackage{etoc}

\newif\ifNonEmptyContents
\makeatletter
\expandafter\in@\expandafter\contentsline\expandafter{\the\Etoc@toctoks}%
\ifin@\expandafter\NonEmptyContentstrue\else
      \expandafter\NonEmptyContentsfalse
\fi
\makeatother

\AtBeginDocument{\let\originaltableofcontents\tableofcontents
  \renewcommand{\tableofcontents}%
     {\ifNonEmptyContents\expandafter\originaltableofcontents\fi}%
}

\begin{document}

\tableofcontents


% \section{A}
% a

% \section{B}

% b

% \subsection{C}

nothing
\end{document}

Initial answer:

Note though that there are some nice packages dealing with TOC's which could well be upset by the following. Besides, I am assuming a standard \tableofcontents command as in the article class.

\documentclass{article}
\usepackage[french]{babel} % for testing
\usepackage{hyperref}      % for testing

\newif\iftoctitledone

\makeatletter

\def\printcontentsnameifnotalreadydone{%
\iftoctitledone\else
\section *{\contentsname \@mkboth {\MakeUppercase \contentsname }
          {\MakeUppercase \contentsname }}\fi
\toctitledonetrue}


\AtBeginDocument{%
  \let\mygoodoldcontentsline\contentsline
  \def\contentsline{\printcontentsnameifnotalreadydone\mygoodoldcontentsline}
  \renewcommand\tableofcontents{\@starttoc {toc}}
}
\makeatother

\begin{document}

    \tableofcontents
    %  \section{test}
nothing
\end{document} 

The same in another style, slightly more elegant.

\documentclass{article}
\usepackage[french]{babel} % for testing
\usepackage{hyperref}      % for testing

\makeatletter

\def\printcontentsnameifnotalreadydone{%
\section *{\contentsname \@mkboth {\MakeUppercase \contentsname }
          {\MakeUppercase \contentsname }}%
\def\printcontentsnameifnotalreadydone{}}

\AtBeginDocument{%
  \let\mygoodoldcontentsline\contentsline
  \def\contentsline{\printcontentsnameifnotalreadydone\mygoodoldcontentsline}
  \renewcommand\tableofcontents{\@starttoc {toc}}
}
\makeatother

\begin{document}

    \tableofcontents
%    \section{A}
% a

% \section{B}

% b

% \subsection{C}

nothing
\end{document}
share|improve this answer
    
It works just pefect. Thanks a lot –  user1285419 Jan 24 '13 at 3:03

Regarding the answer of jfbu:

How does this differ (except for the \@mkboth) from the following:

\documentclass{article}
\usepackage[french]{babel} % for testing
\usepackage{hyperref}      % for testing

\makeatletter

\AtBeginDocument{%
     \let\oldcontentsline\contentsline
     \renewcommand{\contentsline}{
         \section*{\contentsname}
         \let\contentsline\oldcontentsline
         \oldcontentsline
     }
     \renewcommand{\tableofcontents}{\@starttoc{toc}}
}
\makeatother

\begin{document}

\tableofcontents
%    \section{A}
% a

% \section{B}

% b

% \subsection{C}

nothing
\end{document}
share|improve this answer
3  
this is not an answer to the original question but a new question. Anyway, it differs a lot because the code you propose will insert a Contents heading for each and every entry, be it section, subsection etc... ending up in the TOC. Try it out after un-commenting the sections in the code you provide. –  jfbu Apr 4 at 13:55
    
If you have a new question, please ask it by clicking the Ask Question button. Include a link to this question if it helps provide context. –  Andrew Swann Apr 4 at 14:06
    
@AndrewSwann: IMHO it is not a new question, but a simplified version of jfbu's answer. And the "question" is more about, whether this simplification can be done or are there oversights. –  Heiko Oberdiek Apr 4 at 16:18
    
@HeikoOberdiek It is still not an answer, a comment on jfbu's answer, or an edit to the original question would appear to be more approrpiate. –  Andrew Swann Apr 5 at 9:27
    
@AndrewSwann: The code is different from jfbu's answer and provides a solution for the question. Therefore it qualifies for an answer to the question. –  Heiko Oberdiek Apr 5 at 11:57

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.