Have command's output dependent on where (body or section title) it is called

I am using

\newcommand{\PRODUCT}{\textsf{PRODUCT}}


to format a product name consistently throughout my document. However, I realized that this should not happen in (((sub-)sub-)sub-)section titles, but there really should just the text be printed without formatting, as in

\newcommand{\PRODUCT}{PRODUCT}


How can I have a command result in different outputs depending on where it is used in the document?

• I don't see why: you're going against consistency. – egreg Nov 6 '13 at 13:03
• I know, but it was not my idea... – navige Nov 6 '13 at 13:05
• Unfortunately there's no standard way to tell whether LaTeX is typesetting a title or normal text. The simplest workaround would be to provide a *-variant to be used in titles. – egreg Nov 6 '13 at 13:22
• @masu I don't answer all questions. – egreg Nov 6 '13 at 23:05

As egreg told you, "there's no standard way to tell whether LaTeX is typesetting a title or normal text". However you can do some "hacking":

\documentclass{article}

\let\titleFLAG=0

\newcommand\emphif[1]{%
\ifx1\titleFLAG#1\else\textsf{#1}\fi
}

\makeatletter
\let\latex@section\section
\def\section{\secdef\my@section{\latex@section}}
\def\my@section[#1]#2{\let\titleFLAG=1\latex@section[#1]{#2}\let\titleFLAG=0}
\let\latex@subsection\subsection
\def\subsection{\secdef\my@subsection{\latex@subsection}}
\def\my@subsection[#1]#2{\let\titleFLAG=1\latex@subsection[#1]{#2}\let\titleFLAG=0}
\let\latex@subsubsection\subsubsection
\def\subsubsection{\secdef\my@subsubsection{\latex@subsubsection}}
\def\my@subsubsection[#1]#2{\let\titleFLAG=1\latex@subsubsection[#1]{#2}\let\titleFLAG=0}
\makeatother

\begin{document}

\noindent
ABCD \emphif{TEST} ABCD

\section{ABCD \emphif{TEST} ABCD}

ABCD \emphif{TEST} ABCD

\subsection{ABCD \emphif{TEST} ABCD}

ABCD \emphif{TEST} ABCD

\subsubsection{ABCD \emphif{TEST} ABCD}

ABCD \emphif{TEST} ABCD

\noindent
{\bfseries ABCD \emphif{TEST} ABCD}

\end{document}


Hopefully @egreg will tell us what can backfire here and why is this a really bad idea to do. Until that, this seems to work and you only have to add code to your preamble. :)

• I'd do it slightly differently, but not in an essential way. You need no braces in \secdef\my@section\latex@section. – egreg Nov 6 '13 at 23:12
• looks truly like hacking :) but if it works its fine :) – navige Nov 7 '13 at 8:55

This is essentially the same as masu's answer; what's added is an abstraction layer that allows to say only

\redef\section
\redef\subsection


and so on, ensuring that all sectional commands we need are redefined in the same way; code duplication is thus avoided. I added also a \productdef command with three arguments: the first is a control sequence name, the second is what we want to be done in titles and the third is what we want in normal text.

It remains a problem to be solved: what should be the behavior of \PRODUCT in the table of contents? With the following macros it will use the “normal text” version. It would be easy to change \tableofcontents so that it sets the conditional too.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\redef}{m}
{
\navige_redef:N #1
}

\cs_new_protected:Npn \navige_redef:N #1
{
% get a copy of the command to modify
\cs_set_eq:cN { latex_original_ \cs_to_str:N #1 :w } #1
% redefine it with the common “som” strategy, but setting the
% conditional to true before calling the old command
\RenewDocumentCommand{ #1 } { s o m }
{
\bool_gset_true:N \g_navige_intitle_bool
\IfBooleanTF{##1}
{
\use:c { latex_original_ \cs_to_str:N #1 :w } * { ##3 }
}
{
\IfNoValueTF{##2}
{
\use:c { latex_original_ \cs_to_str:N #1 :w } { ##3 }
}
{
\use:c { latex_original_ \cs_to_str:N #1 :w } [ ##2 ] { ##3 }
}
}
% end by setting the conditional to false
\bool_gset_false:N \g_navige_intitle_bool
}
}

\NewDocumentCommand{\productdef}{mmm}
{
\cs_new_protected:Npn #1
{
\bool_if:NTF \g_navige_intitle_bool { #2 } { #3 }
}
}
\ExplSyntaxOff

\redef\section
\redef\subsection
\redef\subsubsection

\productdef{\PRODUCT}{PRODUCT}{\textsf{PRODUCT}}

\begin{document}

\tableofcontents
\show\section

Abcd \PRODUCT{} abcd

\section{Abcd \PRODUCT{} abcd}

Abcd \PRODUCT{} abcd

\subsection{Abcd \PRODUCT{} abcd}

Abcd \PRODUCT{} abcd

\subsubsection{Abcd \PRODUCT{} abcd}

Abcd \PRODUCT{} abcd

{\bfseries Abcd \PRODUCT{} abcd}

\end{document}