3

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)
  • A sectioning command: is it only \section or includes \subsection and \subsubsection as well? – Masroor Aug 28 '17 at 16:35
  • After my answer given below, I like the approach in this answer more than mine. – Masroor Aug 28 '17 at 18:00
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.

  • 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 '17 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 '17 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. :-) – ShreevatsaR Aug 28 '17 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.

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.