答案1
我不建议这样做,因为这会让阅读您文档的其他人感到困惑。它也不适用于所有宏,尤其是那些在读取其参数之前处理类别代码的宏。尽管如此,这是可能的。
这里有一些 LaTeX 代码,它定义了一个宏\flip
,该宏将翻转定义为只有一个必需参数和一个可选参数的宏的必需参数和可选参数。
\usepackage{etoolbox}
\makeatletter
\newcommand*\flip[1]{%
\cslet{flip@\string#1}#1%
\long\def#1##1{%
\@ifnextchar[{\@flip{#1}{##1}}{\csuse{flip@\string#1}{##1}}%
}%
}
\long\def\@flip#1#2[#3]{%
\csuse{flip@\string#1}[#3]{#2}%
}
\makeatother
例如,给定宏
\newcommand\foo[2][none]{%
\par
Required argument: #2\\
Optional argument: #1%
}
你可以写\flip\foo
一次,然后它会重新定义\foo
为接受一个必需参数,后面跟着一个可选参数。这里有一个完整的文档来说明这一点。
\documentclass{article}
\usepackage{parskip}
\usepackage{etoolbox}
\makeatletter
\newcommand*\flip[1]{%
\cslet{flip@\string#1}#1%
\long\def#1##1{%
\@ifnextchar[{\@flip{#1}{##1}}{\csuse{flip@\string#1}{##1}}%
}%
}
\long\def\@flip#1#2[#3]{%
\csuse{flip@\string#1}[#3]{#2}%
}
\makeatother
\newcommand\foo[2][none]{%
\par
Required argument: #2\\
Optional argument: #1%
}
\begin{document}
Normal use:
\foo{blah}
\foo[option]{asdf}
Now we can flip the arguments:
\flip\foo
\foo{blah}
\foo{asdf}[option]
\end{document}
我以前从未使用过 LyX,但我能够将我的代码插入序言中并实现相同的效果。
请注意,\flip
不考虑\long
宏上缺少的情况(即,通过\def
没有\long
或通过定义的系列定义的宏\newcommand*
)。在某些情况下,这可能会导致令人困惑的错误。可以像etoolbox
修补宏一样处理这个问题,但对于这个答案来说,这样做似乎不值得。
也可以\flip
这样定义,它不重新定义其参数,而是将其\flip\foo{required}[optional]
扩展为\foo[optional]{required}
。类似于(未经测试)
\long\def\flip#1#2[#3]{#1[#3]{#2}}
这会将可选参数变成必需参数,但如果您没有可选参数,则没有理由使用\flip
。
总之,这是可能的,但你可能不应该这样做。