使用 \@ifstar 定义星号变体

使用 \@ifstar 定义星号变体

为什么下面的操作根本不起作用?

\documentclass{article}

\makeatletter
\newcommand{\foo}[1]{\@ifstar{\textbf{#1}}{\textit{#1}}}
\makeatother

\begin{document}

\foo{test}
\foo*{test}

\end{document}

输出似乎是“test”,对于非星号变体正确地以斜体形式书写,而对于星号变体则写为“*test”(“test”正常书写,没有粗体,“*”以斜体形式书写)。

答案1

原因是 with\foo*{test} *是 的参数\foo,而{test}只是组中的单词文本。\foo必须是一个没有参数的宏,它调用另一个有参数的宏

\documentclass{article}

\makeatletter
\newcommand{\foo}{\@ifstar{\@foob}{\@fooi}}
\newcommand{\@foob}[1]{\textbf{#1}}
\newcommand{\@fooi}[1]{\textit{#1}}
\makeatother

\begin{document}

\foo{test}
\foo*{test}

\end{document}

答案2

\foo定义时只有一个参数。如果以 来调用\foo*{test},则星号将成为参数 ( #1);然后 \foo被展开并被\@ifstar调用。但后面的标记{不是星号。然后,参数星号被设置为\textit{*}。的处理\foo已完成,{test}并被解释为包含单词testinside 的组。

该示例可以通过以下方式修复:

\documentclass{article}

\makeatletter
\newcommand*{\foo}{\@ifstar\textbf\textit}
\makeatother

\begin{document}

\foo{test}
\foo*{test}

\end{document}

结果

\foo定义时不带参数,因此\@ifstar可以查找后面的星号。然后代码中的“带星号”和“不带星号”的参数都会\@ifstar读取后面的参数。

如果论证中的代码\@ifstar更复杂,那么更一般的回答迈克的帮助。

答案3

在您的定义中,在 \@ifstar 出现之前,参数已经被读取。因此,您必须将星号放在参数后面(请注意,它会占用一个空格::

\documentclass{article}

\makeatletter
\newcommand{\foo}[1]{\@ifstar{\textbf{#1}}{\textit{#1}}}
\makeatother

\begin{document}

\foo{test}
\foo{test}*

\end{document}

在此处输入图片描述

但你想要的可能是这样的:

\documentclass{article}

\makeatletter
\newcommand{\foo}{\@ifstar\textbf\textit}
\makeatother

\begin{document}

\foo{test}
\foo*{test}

\end{document}

在此处输入图片描述

答案4

其内容如下xparse

\usepackage{xparse}
\NewDocumentCommand\foo{sm}{\IfBooleanTF{#1}{\textbf{#2}}{\textit{#2}}}

相关内容