3

From this answer, I tweaked it a little bit to redefine \section as follows:

\let\oldsection\section
\renewcommand{\section}[1]%
{
\begin{tcolorbox}
             [
              colback=gray!50!white,% background
              colframe=gray!50!white,% frame colour
              coltext=black, % text color
              width=\linewidth,%
              height=0.7cm,
              halign=left,
              valign=center,
              fontupper=\large\bfseries,
              arc=0mm, auto outer arc,
             ]
    {\stepcounter{section}\arabic{section}$\,|\quad$ #1}
\end{tcolorbox}
}

However, the moment I use \tableofcontents, it does not work as expected (I am using an article class, by the way.)

Then, by scanning article.cls, the definition of \tableofcontents is as follows:

\newcommand\tableofcontents{%
    \section*{\contentsname
        \@mkboth{%
           \MakeUppercase\contentsname}{\MakeUppercase\contentsname}}%
    \@starttoc{toc}%
    }

I tried replacing \section with \oldsection, but it does not work. Can someone help, please?


Edit: MWE

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{sample}

\RequirePackage{letltxmacro, tcolorbox}
\LetLtxMacro{\oldsection}{\section}
\renewcommand{\section}[1]%
{
\begin{tcolorbox}
             [
              colback=gray!50!white,% background
              colframe=gray!50!white,% frame colour
              coltext=black, % text color
              width=\linewidth,%
              height=0.7cm,
              halign=left,
              valign=center,
              fontupper=\large\bfseries,
              arc=0mm, auto outer arc,
             ]
    {\stepcounter{section}\arabic{section}$\,|\quad$ #1}
\end{tcolorbox}
}

\renewcommand\tableofcontents{%
    \oldsection*{\contentsname
        \@mkboth{%
           \MakeUppercase\contentsname}{\MakeUppercase\contentsname}}%
    \@starttoc{toc}%
    }
\endinput
\documentclass[letterpaper, 10pt]{article}
\usepackage{sample}

\begin{document}
     \tableofcontents
     
     \section{I}
          \subsection{1}
          \subsection{2}
     \section{II}
          \subsection{1}
          \subsection{2}
\end{document}

Edit: Used \LetLtxMacro instead of \let

6
  • Instead of these sniple4s, 9lease post a full but minimal example such that others can 5est your code. Additionally, exactly what do you mean by "it doesn't work"
    – daleif
    Mar 29 '21 at 6:33
  • Even though you typed some words wrong, I understand that they are "snippets, please, test". Thank you for insisting.
    – soupless
    Mar 29 '21 at 6:37
  • The original \section command takes an optional argument, which determines what's written to the aux file (and eventually to the toc file, which is where the contents of the Table of Contents are assembled). If left blank, the optional argument of \section defaults to the command's mandatory argument. Your redefinition of \section, however, guarantees that nothing is written to the aux file. Was that deliberate?
    – Mico
    Mar 29 '21 at 7:10
  • @Mico Are you referring to this? \newcommand\section{\@startsection {section}{1}{\z@}{-3.5ex \@plus -1ex\@minus -.2ex}{2.3ex \@plus.2ex}{\normalfont\Large\bfseries}}
    – soupless
    Mar 29 '21 at 7:12
  • Yes, but somewhat indirectly. If you examine the code for \@startsection (contained in the file latex.ltx, the LaTeX "kernel"), you'll find (for unstarred section-like commands), the instruction \@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}, where \@sect, finally, contains the instruction \addcontentsline{toc}{#1}{...}. Unfortunately, this setup was not designed to be easy to adjust. I recommend you look into the capabilities of the titlesec and sectsty for solutions that are feasible in finite time.
    – Mico
    Mar 29 '21 at 7:21
1

The challenge here is that \section does not actually take a single argument. Instead, it can take three forms:

\section{...}
\section[...]{...}
\section*{...}

You've only accounted for one of those three and, as you've discovered, \tableofcontents uses the last form.

One approach to what you want would be to use the xparse package to redefine \section:

\RequirePackage{xparse}

\RenewDocumentCommand{\section}{s o m}{%
   \IfBooleanTF {#1}
     {\@ssect{\z@}{-3.5ex \@plus -1ex \@minus -.2ex}{2.3ex \@plus.2ex}{\normalfont\Large\bfseries}{#3}}
     {%
   \IfNoValueTF{#2}
     {\@mysection{#3}{#3}}
     {\@mysection{#2}{#3}}
}

\NewDocumentCommand{\@mysection}{m m }{
      \begin{tcolorbox}
             [
              colback=gray!50!white,% background
              colframe=gray!50!white,% frame colour
              coltext=black, % text color
              width=\linewidth,%
              height=0.7cm,
              halign=left,
              valign=center,
              fontupper=\large\bfseries,
              arc=0mm, auto outer arc,
             ]
    {\refstepcounter{section}\thesection $\,|\quad$ #2}
  \end{tcolorbox}
  \sectionmark{#1}
  \addcontentsline{toc}{section}{%
    \ifnum 1>\c@secnumdepth\else
      \protect\numberline{\thesection}%
    \fi
    #1}
  }

A couple notes on the above:

  1. This is all untested. Old habit from when I taught a creating LaTeX style classes entirely off the top of my head writing everything longhand on a whiteboard.

  2. I used the internal \@ssect command with the arguments that would be passed to it from the article class for the starred version of \section so you don't need to change \tableofcontents.

  3. I changed \stepcounter to \refstepcounter so references to section numbers will still work.

  4. I changed \arabic{section} to \thesection. You should always prefer \theCOUNTER to \arabic{COUNTER} unless you have some compelling reason to do otherwise.

  5. I added support for page headings and table of contents. You might not be using the former but you're definitely using the latter. The code is adapted from the LaTeX core.

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.