\@seccntformat only for section
How about
\makeatletter
\def\@seccntformat#1{\@ifundefined{#1@cntformat}%
{\csname the#1\endcsname\quad}% default
{\csname #1@cntformat\endcsname}}% enable indiv. control
\newcommand\section@cntformat{\thesection.\quad}
\makeatother
Feel free to use a different spacing amount than \quad
.
A full MWE:
\documentclass{article}
\makeatletter
\def\@seccntformat#1{\@ifundefined{#1@cntformat}%
{\csname the#1\endcsname\quad}% default
{\csname #1@cntformat\endcsname}}% enable indiv. control
\newcommand\section@cntformat{\thesection.\quad}
\makeatother
\begin{document}
\section{Hello World}
\subsection{Good Morning}
\subsubsection{Yawn}
\section{Goodbye World}
\end{document}
Addendum: The OP has asked me to explain a bit how this code works. It's helpful to begin with the default definition of the \@seccntformat
macro that's provided by the LaTeX kernel (see the file latex.ltx
):
\def\@seccntformat#1{\csname the#1\endcsname\quad}
The macro's argument, #1
, is a string of the form section
, subsection
, subsubsection
, paragraph
, or subparagraph
. Upon expansion, the macro will thus return \thesection\quad
, \thesubsection\quad
, etc. Observe that there is no .
("dot", "full stop") before \quad
.
The proposed modified form of the macro is:
\def\@seccntformat#1{\@ifundefined{#1@cntformat}%
{\csname the#1\endcsname\quad}% default
{\csname #1@cntformat\endcsname}}% enable indiv. control
The first thing the redefined macro does is to check if the macro \#1@cntformat
is "undefined". (As above, #1
is a string of the form section
, subsection
, etc.) If \@ifundefined{#1@cntformat}
is true, the "true" branch is followed. Suppose, for instance, that #1
is set to subsubsection
. Assuming \subsubsection@cntformat
hasn't been defined before \@seccntformat
is executed, the "true" branch is chosen, and thus \@seccntformat
expands to \thesubsubsection\quad
.
If, in contrast, #1
is set to section
, \section@cntformat
will in fact have been defined by the time \@seccntformat
is executed. Specifically, the solution given above provides:
\newcommand\section@cntformat{\thesection.\quad}
Hence, the "false" branch of \@ifundefined{#1@cntformat}
is followed, \@seccntformat#1
evaluates to \section@cntformat
which, in turn, evaluates to \thesection.\quad
.
Comparing this approach with the one in Christian Hupfer's answer is useful. Christian's version of \@seccntformat
begins by setting up two "scratch" macros; the first is set to section
and the other to (the contents of) #1
. Then the \ifx
conditional is applied to compare the two macros. If the condition is 'true', which will only be the case if #1
is equal to the string section
, \thesection.\quad
is executed; otherwise, \csname the#1\endcsname\quad
is executed. If you're only ever going to redefine the look of the formatted section
counter, both approaches are equally good. If, for some reason not revealed so far, you also needed to change the looks of the formatted subsection
, subsubsection
, paragraph
, and subparagraph
counters, the approach above may be a bit more straightforward to implement. Let me state that this statement shouldn't be taken to imply some kind of criticism of Christian's solution!
Using a \ifx\....
comparison
\documentclass{article}
\makeatletter
\DeclareRobustCommand{\@seccntformat}[1]{%
\def\temp@@a{#1}%
\def\temp@@b{section}%
\ifx\temp@@a\temp@@b
\csname the#1\endcsname .\quad%
\else
\csname the#1\endcsname\quad%
\fi
}
\makeatother
\begin{document}
\section{Foo}
\subsection{Foo}
\end{document}
Under regular documents, using \pdfstrcmp
(e-TeX) should work:
\documentclass{article}
\makeatletter
\renewcommand{\@seccntformat}[1]{%
\csname the#1\endcsname% Print sectional counter
\ifnum\pdfstrcmp{#1}{section}=0 .\fi% If \section, print .
\quad% Space between number and title
}
\makeatother
\begin{document}
\section{A section}
\subsection{A subsection}
\subsubsection{A subsubsection}
\end{document}
Since \@seccntformat
receives a single argument for the sectional unit counter, we string-compare the argument against section
. \pdfstrcmp{<strA>}{<strB>}
returns 0 if <strA>
matches <strB>
.