![让命令的输出取决于其调用位置(主体或章节标题)](https://linux22.com/image/278462/%E8%AE%A9%E5%91%BD%E4%BB%A4%E7%9A%84%E8%BE%93%E5%87%BA%E5%8F%96%E5%86%B3%E4%BA%8E%E5%85%B6%E8%B0%83%E7%94%A8%E4%BD%8D%E7%BD%AE%EF%BC%88%E4%B8%BB%E4%BD%93%E6%88%96%E7%AB%A0%E8%8A%82%E6%A0%87%E9%A2%98%EF%BC%89.png)
我在用
\newcommand{\PRODUCT}{\textsf{PRODUCT}}
在我的文档中对产品名称进行一致的格式化。但是,我意识到这不应该发生在(((子)子)子)部分标题中,而应该只打印文本而不进行格式化,就像这样
\newcommand{\PRODUCT}{PRODUCT}
如何让命令根据其在文档中的使用位置产生不同的输出结果?
答案1
正如 egreg 所说,“没有标准方法来判断 LaTeX 是在排版标题还是普通文本”。但是你可以做一些“黑客攻击”:
\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}
希望 @egreg 能告诉我们什么会适得其反,以及为什么这是一个非常糟糕的想法。在此之前,这似乎有效,你只需要在序言中添加代码。:)
基于这个答案。
答案2
这基本上和 masu 的答案相同;添加的是一个抽象层,允许只说
\redef\section
\redef\subsection
等等,确保我们需要的所有部分命令都以相同的方式重新定义;这样就避免了代码重复。我还添加了一个\productdef
带有三个参数的命令:第一个是控制序列名称,第二个是我们想要在标题中执行的操作,第三个是我们想要在普通文本中执行的操作。
还有一个问题需要解决:\PRODUCT
目录中的行为应该是什么?使用以下宏,它将使用“普通文本”版本。更改它很容易,\tableofcontents
以便它也设置条件。
\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
\section*{Introduction about \PRODUCT}
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}