如何确定分段命令的参数中是否使用了宏?

如何确定分段命令的参数中是否使用了宏?

为了进一步自动化我编写的宏,我想知道是否有可能确定此宏是在分段命令的参数内使用还是在文本内使用。我的目标是根据上述环境引起不同的行为/输出。

我已经找到了这个问题,但由于我不想切换到 ConTeXt,因此接受的答案并不符合我的需要。

如果我的问题太模糊,请告诉我,我会尽力提供更多详细信息。

编辑以澄清:

  • 我使用“分段命令”来引用从章节到小节的所有命令。
  • 我对与 KOMA 脚本类配合使用的解决方案特别感兴趣。(准确地说是使用 scrreprt)

答案1

这是您的解决方案,其假设如下:

  1. 您正在使用article课程。
  2. 您不会更改各部分的字体。
  3. 分段命令的意思是\section以及\subsection\subsubsection。如果不是这样,请注释掉 \subsection和 的行\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}

在此处输入图片描述


怎么运行的?

如果我们看一下中的分段命令的定义article.cls,我们会发现发送给的最后一个(实际上是第 6 个或 #6 个)参数\@startsection 是行中的某个内容\normalfont\Large\bfseries

上述代码有效地改变了部分文本的字体。我们通过\toggletrue{insidesection}在 之后放置 来利用这一点\bfseries

这里,用\patchcmd{\section}{\bfseries}{\bfseries\toggletrue{insidesection}}{}{} 替换,从而将标志设置为 true。\bfseries\bfseries\toggletrue{insidesection}

我们的逻辑感会告诉我们在节文本结束时将标志重置为 false,但这并不是必要的。如上所述,所有节命令都调用\@startsection来呈现节。并且在此宏的定义中,范围参数#6使标志设置为本地设置,因此一旦呈现了节名称文本,它就会返回其原始值 false。

要了解更多信息 \patchcmd,请阅读此内容很好的答案

答案2

这是一个解决方案,使用了一些重新定义的分段命令,我大约一个月前在 TeX.SE 上的其他问题中使用过这些命令。我认为它适用于任何类型的文档类,因为它只是按原样重新定义了“部分”,并提供了在其中添加命令的机会。例外是我接受带有可选参数的带星号部分,并忽略它(发现它在其他问题中很有用,并将其用于 fancyhead 部分或章节名称):

\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}

我认为我的方法解决了许多这样的问题。

相关内容