8

I am using a class file that uses \AtEndDocument to include a table of contents at the end of the document. However, I would like to override the original \AtEndDocument and force the document not to have a TOC at all without having to change the document class. How can I achieve that?

The .cls file without the :

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{docclass}[2009/07/02 Whitepaper Style]
\DeclareOption{a5paper}{\OptionNotUsed}
\DeclareOption{b5paper}{\OptionNotUsed}
\DeclareOption{letterpaper}{\OptionNotUsed}
\DeclareOption{legalpaper}{\OptionNotUsed}
\DeclareOption{executivepaper}{\OptionNotUsed}
\DeclareOption{landscape}{\OptionNotUsed}
\DeclareOption{twoside}{\OptionNotUsed}
\DeclareOption{draft}{\OptionNotUsed}
\DeclareOption{notitlepage}{\OptionNotUsed}
\DeclareOption{openright}{\OptionNotUsed}
\DeclareOption{leqno}{\OptionNotUsed}
\DeclareOption{fleqn}{\OptionNotUsed}
\DeclareOption{openbib}{\OptionNotUsed}
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{report}}
\ProcessOptions
%%
\LoadClass[a4paper,11pt,oneside,onecolumn,final,openany,chapterprefix=false]{scrreprt}
\RequirePackage[T1]{fontenc}
\RequirePackage[english]{babel}
\RequirePackage[english]{varioref}
\RequirePackage[ansinew]{inputenc}
\RequirePackage[pdftex]{graphicx}
\RequirePackage{wrapfig}
\RequirePackage{color}
\RequirePackage{float}
\RequirePackage{datetime}
\RequirePackage{fancyvrb}
\RequirePackage{fancyhdr}
\RequirePackage{ae}
\RequirePackage{bbding}
\RequirePackage{amsmath}
\RequirePackage[hang,flushmargin]{footmisc}
\RequirePackage[
    pdftex,
    colorlinks=true,
    linkcolor=black,
    citecolor=black,
    urlcolor=black,
    menucolor=black,
    filecolor=black,
    breaklinks=false,
    bookmarksnumbered=false,
    pdfpagelayout=OneColumn,
    pdfstartview=FitH
    ]{hyperref}

%% more commands

\fontfamily{cmss}

\AtBeginDocument{%
  \hypersetup{%
    pdftitle={\HREFpdftitle},
    pdfauthor={\HREFpdfauthor},
    pdfsubject={\HREFpdfsubject},
    pdfkeywords={\HREFpdfkeywords},
    pdfcreator={\HREFpdfcreator}
  }%
}

\AtEndDocument{%
    \newpage\pdfbookmark[0]{Contents}{TOC}\tableofcontents\thispagestyle{fancy}
}

The document:

\documentclass{docclass}
\begin{document}
\section*{Section 1}
foo bar baz
\section*{Section 2}
lorem ipsum ...
\end{document}

Note: I have tried simply including \AtEndDocument{} in the document, but this doesn't yield the expected result.

  • 1
    You can use loops to avoid copious use of estate by similar calls to the same command. See the documentation of catoptions package. – Ahmed Musa Mar 28 '12 at 22:30
13
\makeatletter
\global\let\@enddocumenthook\@empty
\makeatother

will clear the macro that saves the tokens added by \AtEndDocument

\AtEndDocument{} 

doesn't work as you can have many calls to this command each adds the declarations to the existing hook (so that adds nothing but leaves the existing declarations in place)

  • Wow, thanks a lot for this swift response. Works like a charm. I'm going to accept as soon as I can. – 0xC0000022L Mar 26 '12 at 21:03
  • 2
    David, @STATUS_ACCESS_DENIED: Note that this will clear all code added to the hook previously, which might break the functionality of packages will add their own code there. – Martin Scharrer Mar 26 '12 at 21:22
  • 2
    @MartinScharrer yes that was the requested behaviour:-) If you know exactly what tokens are in the hook it is of course possible to do rather more delicate surgery to remove the tokens or redefine them – David Carlisle Mar 26 '12 at 21:26
5

Here is a general solution. Since there might be unscannable tokens in \@enddocumenthook, I first check for scannability before attempting to filter test tokens from the token list \@enddocumenthook. The solution is not trivial.

You can release \@enddocumenthook at (1) and do \show\y to see that the example at the end behaves as required.

If the test token isn't unique in \@enddocumenthook, a wrong match can occur. For this reason, I have introduced a new command \NewAtEndDocument, which is to be used in place of \AtEndDocument if tokens will be filtered from \@enddocumenthook.

Tokens have to be filtered out in the same lot that they have been included in \@enddocumenthook.

\documentclass[a4paper]{article}
\usepackage{catoptions}
\newletcs\ltsrelax\relax
\robust@def\NewAtEndDocument#1{%
  \g@addto@macro\@enddocumenthook{\ltsrelax#1\ltsrelax}%
}
\robust@def\FilterAtEndDocumentHook{%
  \begingroup
  \endlinechar\m@ne
  \edef\reserved@a##1{%
    \def##1\detokenize{macro}:->####1\ltsrelax{%
      \def\string\reserved@a{####1}%
    }%
    \edef##1{##1\meaning\@enddocumenthook\ltsrelax}%
  }%
  \reserved@a\reserved@a
  \makeatletter\everyeof{\noexpand}%
  \scantokens\expandafter{\reserved@a}\relax
  \ifx\@enddocumenthook\reserved@a\else
    \endgroup
    \@latex@error{\noexpand\@enddocumenthook is no longer scannable}\@ehd
  \fi
  \cpt@testst\Filt@rAtEndDocumentHook
}
\robust@def\Filt@rAtEndDocumentHook#1{%
  \def\filter@remove##1{%
    \xifinsetFT{##1}{\cptoxdetok\@enddocumenthook}{}{%
      \def\reserved@a####1##1####2\filter@nil{%
        \def\@enddocumenthook{####1####2}%
        \ifboolFT{cpt@st}{}{\filter@remove{##1}}%
      }%
      \expandafter\reserved@a\detokenize\expandafter
        {\@enddocumenthook}\filter@nil
    }%
  }%
  \expandafter\filter@remove\expandafter{\detokenize{\ltsrelax#1\ltsrelax}}%
  \cptscantokens\@enddocumenthook
  \postgroupdef\@enddocumenthook\endgroup
}

% Examples:
\NewAtEndDocument{\def\x#1{#1}}
\NewAtEndDocument{\def\y#1{#1}}
\NewAtEndDocument{\def\x#1{#1}}
% The starred variant of \FilterAtEndDocumentHook will remove all occurrences of
% the test token ('\def\x#1{#1}' in the following example). The non-starred form
% will remove only one occurrence.
\FilterAtEndDocumentHook*{\def\x#1{#1}}
% \@enddocumenthook % (1)

\makeatother
\begin{document}

\end{document}

Here is a solution that doesn't require rescanning of \@enddocumenthook. This is to be preferred.

\documentclass[a4paper]{article}
\usepackage{catoptions}
\makeatletter

\let\do@enddoc\@firstofone
\def\added@enddocumenthook{}
\grightaddtocs\@enddocumenthook{\added@enddocumenthook}
\robust@def\NewAtEndDocument#1{%
  \cptexpandarg{\grightaddtocs\added@enddocumenthook}%
    {\noexpand\do@enddoc{\cpttrimspace{#1}}}%
}
\robust@def*\FilterAtEndDocumentHook{%
  \begingroup
  \cpt@testopt\Filt@rAtEndDocumentHook{1}%
}
\robust@def\Filt@rAtEndDocumentHook[#1]#2{%
  \edef\reserved@b{\cpttrimspace{#2}}%
  \@tempcnta\z@
  \def\do@enddoc##1{%
    \toks@{\edef\added@enddocumenthook
      {\expandcsonce\added@enddocumenthook\unexpanded{\do@enddoc{##1}}}}%
    \edef\reserved@a{\unexpanded{##1}}%
    \ifx\reserved@a\reserved@b
      \advance\@tempcnta\@ne
      \ifnum\@tempcnta>\@iden{#1}\relax
        \the\toks@
      \fi
    \else
      \the\toks@
    \fi
  }%
  \expandafter\def\expandafter\added@enddocumenthook\expandafter
    {\expandafter}\added@enddocumenthook
  \postgroupdef\added@enddocumenthook\endgroup
}

% Examples:
\NewAtEndDocument{\def\x#1{#1}}
\NewAtEndDocument{\def\y#1{#1}}
\NewAtEndDocument{\def\x#1{#1}}
% Use the optional argument of \FilterAtEndDocumentHook to specify the number of
% occurrences of the test token to be removed (2 in the following example).
\FilterAtEndDocumentHook[2]{\def\x#1{#1}}
% \@enddocumenthook % (1)
% \show\y

\makeatother
\begin{document}

\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.