[Tex/LaTex] Redefine `\section*` so it behaves *exactly* as `\section` except leaves out the number

sectioningstarred-versiontable of contents

There's any number of variations on the question "How do I get my unnumbered sections into the table of contents?" …

and none of the answers are any good to me, because they all involve sticking \addcontentsline, plus maybe other stuff (\mark, \phantomsection, …?), at just the right place in the document. In my case, the \section* commands are being issued by packages, and they don't give me hooks to insert stuff at just the right place; and also it is unclear exactly what set of "other stuff" I need. It would be simpler and more robust if I could just redefine \section* so that it behaves exactly as its non-starred version does, except that it does not print a section number.

How do I do that?

Note: KOMA-Script classes are not an option. I am currently using plain article for drafts and I will eventually need to drop in a journal's class.

Note 2 (from comments on an attempted answer): adjusting \secnumdepth globally will not work for me, because (a) I still want normal section numbering from unstarred \section etc, and (b) the packages that are issuing \section* commands can't be persuaded to use plain \section instead.

Best Answer

You can redefine \section to capture and condition on when the starred-version is used. Upon finding \section*, issue it just like you would \section, but remove the number-printing mechanism through an appropriate setting of the counter secnumdepth.

enter image description here

\documentclass{article}

\usepackage{xparse}

\let\oldsection\section
\makeatletter
\newcounter{@secnumdepth}
\RenewDocumentCommand{\section}{s o m}{%
  \IfBooleanTF{#1}
    {\setcounter{@secnumdepth}{\value{secnumdepth}}% Store secnumdepth
     \setcounter{secnumdepth}{0}% Print only up to \chapter numbers
     \oldsection{#3}% \section*
     \setcounter{secnumdepth}{\value{@secnumdepth}}}% Restore secnumdepth
    {\IfValueTF{#2}% \section
       {\oldsection[#2]{#3}}% \section[.]{..}
       {\oldsection{#3}}}% \section{..}
}
\makeatother

\begin{document}

\tableofcontents

\section{TestA}

\section*{TestB}

\end{document}

xparse provides an easy interface for (re)defining commands that may have a starred version, as well as an optional argument.

Related Question