我对宏的语法感到困惑。基本上我想检查是否应该根据参数使用\section
或带星号的部分。\section*
\documentclass{article}
\newcommand\mySection[2]{
\ifnum #2=1
\expandafter\expandafter\expandafter\section
\else\section*
\fi
{#1}
}
\begin{document}
test
\mySection{title}{1}
\mySection{title}{0}
\end{document}
第二个命令收到错误! Extra \else.
如何让 MWE 工作?
答案1
你没算清楚\expandafter
。你的测试文件应该是:
\documentclass{article}
\newcommand\mySection[2]{
\ifnum #2=1
\expandafter\section
\else\expandafter\section\expandafter*%
\fi
{#1}
}
\begin{document}
test
\mySection{title}{1}
\mySection{title}{0}
\end{document}
一般规则:\expandafter
s 链必须接触\else
条件第一部分中的和\fi
第二部分中的。
答案2
让我们看一下\if..\else..\fi
条件语句:
\if...
当条件满足\if..\else..\fi
时,扩展\if..
的会产生评估并删除需要找出\if..
条件是否满足的标记。
\ifnum
例如,扩大
\ifnum1=1 equal\else different\fi
产量: equal \else different\fi
。
进行进一步加工equal
。之后\else
进行/扩展。
执行/扩展的结果\else
是删除包括匹配的后续标记\fi
。
换句话说,上面的句子重新表述为:在条件得到满足时,
扩展的将导致删除形成“假”分支的标记并删除匹配的。\else
\if..\else..\fi
\if..
\fi
例如,(点击图片放大)
产量: (点击图片放大)
产量: (点击图片放大)
扩展当条件不满足时产生的对需要确定条件是否满足的标记的评估和删除,\if..
以及删除形成“真”分支的所有标记,包括标记“真”分支结束的标记。\if..\else..\fi
\if..
\if..
\else
(\else
当条件不满足时,不会扩展:正如刚才所说:在这种情况下,标记\if..\else..\fi
被删除作为“真”分支结束的标记。由于它已被删除,因此无法扩展。)\if..
\else
\ifnum
例如,扩大
\ifnum1=2 equal\else different\fi
产量:different\fi
。
different
执行完毕。之后\fi
执行=扩展=删除。
请注意,短语“求值并删除用于确定 -条件是否\if..
满足所需的标记”中的术语“求值”对于某些\if..
-条件包含可扩展标记的扩展 - 例如,和\if
-\ifcat
并且对于某些\if..
-条件不包含可扩展标记的扩展 - 例如,\ifx
。对于某些-条件-\if..
例如\ifhmode
,,,,-根本不需要标记来找出-条件是否满足。\ifvmode
\ifmmode
\ifinner
\if..
让我们看看您的定义\mySection
:
\newcommand\mySection[2]{ \ifnum #2=1 \expandafter\expandafter\expandafter\section \else\section* \fi {#1} }
在您的代码中,如果是,则#2
丢弃构成's0
的“真”分支的标记,从而 丢弃表示“真”分支结束的标记。构成“假”分支的 后面的标记不会被丢弃,而是会被执行。在执行 之前,不会从输入堆栈中删除属于's的标记。因此 的参数 将是标记,而不是序列。扩展-macro/扩展-macro 下的宏意味着在插入参数的参数时,用其定义文本替换有问题的控制序列标记。因此,作为的参数出现错误地匹配了来自 -command下某个宏的定义文本的某些- - -表达式。因此,后面的被认为是额外的。 (后面被认为是额外的,并不被认为是额外的,而是“帮助”匹配事物,而不是属于's的,后者被用作 的参数。)\mySection
\ifnum..\else..\fi
\else
\else
\fi
\mySection
\ifnum..\else..\fi
\section*
\section*
\fi
{#1}
\section
\section
\fi
\section*
\if..
⟨some parameter #1/#2/whatever⟩
\else
\fi
\section
\else
⟨some parameter #1/#2/whatever⟩
\else
\fi
\else
\fi
\fi
\mySection
\ifnum..\else..\fi
\section*
在您的代码中,如果#2
是1
第一个\expandafter
链(由第一个和第三个组成\expandafter
),则“命中”了\else
。因此\else
会展开(并因此被删除),从而丢弃整个“假”分支,包括\fi
标志着“假”分支结束的。然后,第二个\expandafter
链(由第二个组成\expandafter
)会“命中”其中的,但由于不可展开,{
因此{#1}
没有任何效果。{
如果#2=1
TeX通过以下方式删除*
序列:\section*
\@firstoftwo
\documentclass{aricle}
\makeatletter
\newcommand\mySection[2]{%
\ifnum#2=1 \expandafter\@firstoftwo\fi\section*{#1}%
}%
\makeatother
\begin{document}
test
\mySection{title}{1}
\mySection{title}{0}
\end{document}
如果你不喜欢\expandafter
你\exchange
\@firstoftwo
可以\fi
:
\documentclass{article}
\makeatletter
\newcommand\exchange[2]{#2#1}%
\newcommand\mySection[2]{%
\ifnum #2=1 \exchange\@firstoftwo\fi\section*{#1}%
}%
\makeatother
\begin{document}
test
\mySection{title}{1}
\mySection{title}{0}
\end{document}
答案3
完成这项工作的标准方法是
\documentclass{article}
\makeatletter
\newcommand\mySection[2]{%
\ifnum #2=1
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\section}{\section*}{#1}%
}
\makeatother
\begin{document}
test
\mySection{title}{1}
\mySection{title}{0}
\end{document}
因此在选择所需路径之前,条件已被完全删除。
还有许多其他方法,甚至有些不需要\expandafter
。
\documentclass{article}
\usepackage{etoolbox}
\newcommand\mySection[2]{%
\ifnumcomp{#2}{=}{1}{\section}{\section*}{#1}%
}
\begin{document}
test
\mySection{title}{1}
\mySection{title}{0}
\end{document}
没有软件包(但有一个相当新的 LaTeX 内核)
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand\mySection{mm}
{
\int_compare:nTF {#2=1}{\section}{\section*}{#1}
}
\ExplSyntaxOff
\begin{document}
test
\mySection{title}{1}
\mySection{title}{0}
\end{document}
最后一个可以扩展以支持可选参数。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand\mySection{O{#2}mm}
{
\int_compare:nTF {#3=1}{\section[#1]}{\section*}{#2}
}
\ExplSyntaxOff
\begin{document}
\tableofcontents
\mySection[short title for toc]{title}{1}
\mySection{title}{0}
\end{document}