I want to use markup commands such as \pkg{classicthesis} that not only typeset the entry, but that have side-effects such as adding a margin note or index entry. (See the example below.)

My problem is that I would like to be able to use these in sectioning commands \chapter{The \pkg{classicthesis} Package}, but doing so sends the extra stuff to the .toc file as well, which can cause problems when the table of contents is formatted.

Question: How can I clean everything but the text (and formatting information) from what is sent to the .toc file?

I know that I could do something like \chapter[The \pkg*{classicthesis} Package]{The \pkg{classicthesis} Package} where I define the starred form to omit the extra info, but this means unnecessarily duplicating the contents.

Note: I am doing this for a class and have no problem redefining \chapter etc. to do the cleaning, I just need the internals.

Here is a MWE. In the second case, the index command appears both in the section header and in the ToC: the latter introducing an undesired entry in the index and the marginpar also appears in the ToC. There are usually workarounds for each individual issue (in this case the scrindex package solves the index problem and one could disable \marginpar in the toc), but I would still like a general solution.

\documentclass{scrbook}
\usepackage{makeidx}
%\usepackage{scrindex} % This will fix the index issue.
\usepackage{suffix}
\usepackage{makerobust}
\usepackage{classicthesis}

\newcommand*{\pkg}[1]{\texttt{#1}\marginpar{\texttt{#1}}\index{environments!#1@\texttt{#1}}}
\WithSuffix\newcommand\pkg*[1]{\texttt{#1}}
\MakeRobustCommand\pkg

\makeindex

\begin{document}
\tableofcontents
\chapter{The Problem}
\section[The \pkg*{classicthesi} Package]{The \pkg{classicthesis} Package}
This works, but is error-prone and violates the DRY principle.
\section{The \pkg{classicthesis} Package}
This fails because the indexing commands are sent to the .toc file.
\printindex
\end{document}

-

While you are using a KOMA-Script class you are also using package KOMA-Script package tocbasic. So you can simply use \BeforeStartingTOC to redefine the macros until they are used at the toc file and local to the toc file:

\documentclass{scrbook}
\usepackage{makeidx}
%\usepackage{scrindex} % This will fix the index issue.
\usepackage{suffix}
\usepackage{makerobust}
\usepackage{classicthesis}

\newcommand*{\pkg}[1]{\texttt{#1}\marginpar{\texttt{#1}}\index{environments!#1@\texttt{#1}}}
\WithSuffix\newcommand\pkg*[1]{\texttt{#1}}
\MakeRobustCommand\pkg

\makeindex

\BeforeStartingTOC[toc]{%
\expandafter\let\expandafter\pkg\csname \SuffixName\pkg*\endcsname
}

\begin{document}
\tableofcontents
\chapter{The Problem}
\section{The \pkg{classicthesis} Package}
This works.
\printindex
\end{document}


To completely deactivate a single argument macro use something like

\makeatother
\BeforeStartingTOC{%
\let\pkg\@firstofone
}
\makeatletter


You may find more information about \BeforeStartingTOC at page 238 of the current English KOMA-Script manual. The whole documentation of package tocbasic may be found at chapter 10 of the same manual.

AFAIK their is no possibility to just say deactivate all macros, so the answer to this question is still open. But if I correctly understand your question, deactivation of \pkg is not really what you want. You still want \pkg to be \texttt.

Another solution may be to deactivate \index and \marginpar:

\BeforeStartingTOC[toc]{%
\renewcommand*{\index}[1]{}%
\renewcommand*{\marginpar}[2][]{}%
}


instead of redefining \pkg.

-
That will work, but requires special casing each problematic command. Maybe this is the best answer possible, but what I am looking for is some sort of semi-magic command \getonlythetex{} that discards everything except the text. I.e. is there some way of checking whether a macro expands to nothing (only side-effects) without actually expanding it (and thereby triggering the side-effect), subsequently discarding the macro. The more I think about though, the less likely I think that another solution exists. –  mforbes Nov 13 '11 at 9:53
@mfborbes: I don't think, that such a solution can exists, because sometimes an argument of a macro still should be set (e.g. \pkg) and sometimes it should be removed together with the macro (e.g. \index). And automatism for this needs manual declaration. Declaration is the thing I do at my answer using \let or \renewcommand. –  Schweinebacke Nov 13 '11 at 9:59