4

In order to further automatize a macro I have written, I would like to know if there is a possibility to determine if this macro is used inside the argument of a sectioning command or inside the text. My aim is to cause different behaviour/output depending on the above described surrounding.

I have already found this question, but as I would prefer not to switch to ConTeXt the accepted answer does not suit my needs.

If my question is too vague please tell me and I will try my best to provide additional details.

EDIT for clarification:

  • With "sectioning command" I refer to all commands form chapter to subsubsection.
  • I am especially interested in a solution that works with the KOMA script classes. (With scrreprt to be precise)
2
  • A sectioning command: is it only \section or includes \subsection and \subsubsection as well?
    – Masroor
    Aug 28, 2017 at 16:35
  • After my answer given below, I like the approach in this answer more than mine.
    – Masroor
    Aug 28, 2017 at 18:00

2 Answers 2

2

Here is your solution where the assumptions are:

  1. You are using article class.
  2. You are not going to change the font of the sections.
  3. By sectioning commands, you mean \section as well as \subsection and \subsubsection. If this is otherwise, please comment out the lines for \subsection and \subsubsection.

\documentclass{article}
\pagenumbering{gobble}


\usepackage{xspace}

\usepackage{etoolbox}

\newtoggle{insidesection}
\togglefalse{insidesection}

\patchcmd{\section}{\bfseries}{\bfseries\toggletrue{insidesection}}{}{}
\patchcmd{\subsection}{\bfseries}{\bfseries\toggletrue{insidesection}}{}{}
\patchcmd{\subsubsection}{\bfseries}{\bfseries\toggletrue{insidesection}}{}{}

\def\insideoroutside{\iftoggle{insidesection}{I AM INSIDE\xspace}{I am outside\xspace}}

\begin{document}

This is before any section: \insideoroutside

\section{\insideoroutside At Start Section}

\insideoroutside

\subsection{A Subsection \insideoroutside}

\insideoroutside

\section{At Mid \insideoroutside Section}

\insideoroutside

\subsection{Another Subsection}

\insideoroutside

\subsubsection{And a Subsubsection \insideoroutside}

\insideoroutside

\section{At End Section \insideoroutside}

\insideoroutside

\section*{What if There is a Star? \insideoroutside}

\end{document}

enter image description here


How It Works?

If we take a look at the definition of the sectioning commands in article.cls, we find that the last (6th actually or #6) argument which is being sent to \@startsection is something in the line of, \normalfont\Large\bfseries.

The above effectively changes the font of the section text. We exploit this by putting a \toggletrue{insidesection} just after \bfseries.

Here, \patchcmd{\section}{\bfseries}{\bfseries\toggletrue{insidesection}}{}{} replaces \bfseries with \bfseries\toggletrue{insidesection}, thus setting the flag to true.

Our sense of logic would tell us to reset the flag to false at the end of the sectioning text, but that does not become necessary. As mentioned above, all the sectioning commands call \@startsection to render the section. And inside the definition of this macro, the scoping around argument #6 makes the flag setting local and hence it returns to its original value of false once the section name text has been rendered.

To learn more about \patchcmd, read this excellent answer.

3
  • Thanks for your answer and the explanations of your code. I was able to successfully use this in combination wih my macro but saldy this solution only works for the article document class while I would prefer the KOMA classes.
    – leandriis
    Aug 28, 2017 at 18:09
  • 2
    @leandriis Then I strongly suggest that you use the approach delineated here. This is much better than mine. And, yes, it works for KOMA classes, I checked.
    – Masroor
    Aug 28, 2017 at 18:19
  • 1
    Whatever the relative merits of this solution compared to others, +1 for explaining how it works. Please continue to do that, and encourage the practice. :-) Aug 28, 2017 at 19:24
1

Here is a Solution using some redefinitions of sectioning commands that I used about a month ago for other question on TeX.SE. I suppose it works with any kind of documentclass since it just redefining the "sections" as exactly was and just gives the opportunity to add commands inside. Exception is that I accept starred section with optional argument and just ignore that (found that useful in other question and used it for fancyhead section or chapter name):

\documentclass{book}

\usepackage{xcolor}

\def\InsideSectioning{0}

\makeatletter
\let\oldchapter=\chapter
\def\chapter{%
\xdef\InsideSectioning{1}%
\@ifstar{\@Starred}{\@nonStarred}%
}
\def\@Starred{%
\@ifnextchar[%
{\@StarredWith}%
{\@StarredWithout}%
}      
\def\@StarredWith[#1]#2{%
\oldchapter*{#2}\xdef\InsideSectioning{0}% You can give an error here because normally latex doesn't accept starred sections with 
%optional arguments. I just ignore that argument!
}
\def\@StarredWithout#1{%
\oldchapter*{#1}\xdef\InsideSectioning{0}%
}
\def\@nonStarred{%
\@ifnextchar[%
{\@nonStarredWith}%
{\@nonStarredWithout}%
}
\def\@nonStarredWith[#1]#2{%
\oldchapter[#1]{#2}\xdef\InsideSectioning{0}%
}
\def\@nonStarredWithout#1{%
\oldchapter{#1}\xdef\InsideSectioning{0}%
}

\let\oldsection=\section
\def\section{%
\xdef\InsideSectioning{1}%
\@ifstar{\@StarredS}{\@nonStarredS}%
}
\def\@StarredS{%
\@ifnextchar[%
{\@StarredWithS}%
{\@StarredWithoutS}%
}      
\def\@StarredWithS[#1]#2{%
\oldsection*{#2}\xdef\InsideSectioning{0}% Again accepted... See coment above
}
\def\@StarredWithoutS#1{%
\oldsection*{#1}\xdef\InsideSectioning{0}%
}
\def\@nonStarredS{%
\@ifnextchar[%
{\@nonStarredWithS}%
{\@nonStarredWithoutS}%
}
\def\@nonStarredWithS[#1]#2{%
\oldsection[#1]{#2}\xdef\InsideSectioning{0}%
}
\def\@nonStarredWithoutS#1{%
\oldsection{#1}\xdef\InsideSectioning{0}%
}

\let\oldsubsection=\subsection
\def\subsection{%
\xdef\InsideSectioning{1}%
\@ifstar{\@StarredSS}{\@nonStarredSS}%
}
\def\@StarredSS{%
\@ifnextchar[%
{\@StarredWithSS}%
{\@StarredWithoutSS}%
}      
\def\@StarredWithSS[#1]#2{%
\oldsubsection*{#2}% Here too
}
\def\@StarredWithoutSS#1{%

\oldsubsection*{#1}\xdef\InsideSectioning{0}%
}
\def\@nonStarredSS{%
\@ifnextchar[%
{\@nonStarredWithSS}%
{\@nonStarredWithoutSS}%
}
\def\@nonStarredWithSS[#1]#2{%
\oldsubsection[#1]{#2}\xdef\InsideSectioning{0}%
}
\def\@nonStarredWithoutSS#1{%
\oldsubsection{#1}\xdef\InsideSectioning{0}%
}

\let\oldsubsubsection=\subsubsection
\def\subsubsection{%
\xdef\InsideSectioning{1}%
\@ifstar{\@StarredSS}{\@nonStarredSS}%
}
\def\@StarredSSS{%
\@ifnextchar[%
{\@StarredWithSSS}%
{\@StarredWithoutSSS}%
}      
\def\@StarredWithSSS[#1]#2{%

\oldsubsubsection*{#2}\xdef\InsideSectioning{0}% Here too
}
\def\@StarredWithoutSSS#1{%
\oldsubsubsection*{#1}\xdef\InsideSectioning{0}%
}
\def\@nonStarredSSS{%
\@ifnextchar[%
{\@nonStarredWithSSS}%
{\@nonStarredWithoutSSS}%
}
\def\@nonStarredWithSSS[#1]#2{%
\oldsubsubsection[#1]{#2}\xdef\InsideSectioning{0}%
}
\def\@nonStarredWithoutSSS#1{%
\oldsubsubsection{#1}\xdef\InsideSectioning{0}%
}
\makeatother

\newcommand{\testIfInside}
{%
\ifnum\InsideSectioning=1%
Inside%
\else%
Outside%
\fi%
}



\begin{document}

\tableofcontents

Outside:\testIfInside

\chapter{Test:\testIfInside}

test outside:\testIfInside

\section{Here is a section\testIfInside}

outside again:\testIfInside AndText to test tokens

\subsection{Inside Subsection\testIfInside}

again Outside:\testIfInside

\subsubsection{Inside SubSubSection\testIfInside}

again Outside:\testIfInside

\chapter{Chapter \testIfInside}

text \testIfInside

\end{document}

I think my approach gives solution to many such problems.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .