例如,我创建了多个命令,如下所示
\newcommand{\A}{\mathcal A}
\newcommand{\B}{\mathcal B}
\newcommand{\C}{\mathcal C}
是否可以将所有这些命令组合为一个命令,如下所示?
\newcommand{\*}{\mathcal *}
答案1
并非 OP 提供的期望语法(但非常不精确),但可能对您有用。请注意,这不会检查\A
、\B
或\C
是否已经存在,而是会覆盖任何现有的定义。
\documentclass{article}
\usepackage{listofitems}
\newcommand\makemathcal[1]{
\readlist\mylist{#1}%
\foreachitem\z\in\mylist[]{%
\expandafter\gdef\csname\z\expandafter\endcsname
\expandafter{\expandafter\mathcal\expandafter{\z}}%
}%
}
\begin{document}
\makemathcal{A,B,C}
$\A \ne \B > \C$
\end{document}
也许稍微改进一下(但显然更危险)的语法是利用pgffor
列表规范:
\documentclass{article}
\usepackage{pgffor}
\newcommand\makemathcal[1]{
\foreach\z in{#1}{%
\expandafter\gdef\csname\z\expandafter\endcsname
\expandafter{\expandafter\mathcal\expandafter{\z}}%
}%
}
\begin{document}
\makemathcal{A,...,Z}
$\A \ne \B > \Z$
\end{document}
答案2
答案3
没有“通配符”功能,但可以模拟它。
\documentclass{article}
\usepackage{amssymb}
%\usepackage{xparse} % uncomment if running LaTeX prior to 2020-10-01
\ExplSyntaxOn
\NewDocumentCommand{\makelettercommands}{mmm}
{% #1 = template
% #2 = wrapper (for instance \mathcal)
% #3 = list of ranges
\whatsname_mlc:nnn { #1 } { #2 } { #3 }
}
\seq_new:N \l__whatsname_mlc_range_seq
\seq_new:N \l__whatsname_mlc_list_seq
\cs_generate_variant:Nn \int_step_inline:nnn { ee }
\cs_new_protected:Nn \whatsname_mlc:nnn
{
% set a scratch function to the template
\cs_set:Nn \__whatsname_mlc_name:n { #1 }
% map the list of ranges (or single letters)
\clist_map_inline:nn { #3 }
{
\__whatsname_mlc_do:nnn { ##1 } { #1 } { #2 }
}
}
\cs_new_protected:Nn \__whatsname_mlc_do:nnn
{% split at a possible -
\seq_clear:N \l__whatsname_mlc_list_seq
\seq_set_split:Nnn \l__whatsname_mlc_range_seq { - } { #1 }
\int_compare:nTF { \seq_count:N \l__whatsname_mlc_range_seq = 1 }
{% no range
\seq_put_right:Nn \l__whatsname_mlc_list_seq { #1 }
}
{% range
\int_step_inline:een
{ `\seq_item:Nn \l__whatsname_mlc_range_seq { 1 } } % first item is start of range
{ `\seq_item:Nn \l__whatsname_mlc_range_seq { 2 } } % second item is end of range
{ \seq_put_right:Nx \l__whatsname_mlc_list_seq { \char_generate:nn { ##1 } { 11 } } }
}
\cs_set_protected:Nn \__whatsname_mlc_def:n
{
\cs_new_protected:cpn { \__whatsname_mlc_name:n { ##1 } } { #3 { ##1 } }
}
\seq_map_function:NN \l__whatsname_mlc_list_seq \__whatsname_mlc_def:n
}
% just for a check, show the commands
\NewDocumentCommand{\showcs}{m}
{
\texttt{ \token_to_str:N #1 ~->~ \cs_replacement_spec:N #1 }
}
\ExplSyntaxOff
\makelettercommands{c#1}{\mathcal}{A-C,E}
\makelettercommands{#1}{\mathcal}{D}
\makelettercommands{#1#1}{\mathbb}{C,H,N,Q,R,X-Z}
\makelettercommands{#1frak}{\mathfrak}{a-z}
\begin{document}
$\cA+\cC+\cE+\D+\ZZ+\YY-\afrak$
\showcs\cA
\showcs\ZZ
\showcs\zfrak
\end{document}
我不建议将其定义\A
为\mathcal{A}
,最好使用更复杂一些且带有语义的东西。例如\cA
等。
在示例中,我\NN
对最常见的数字集执行了 等操作;但请注意,\AA
已经定义了。在\mathbb
示例中,我使用Y-Z
来显示混合规范(单个字母和范围)的用法。
如您所见,在第一个参数中,\makelettercommands
我们将#1
它作为第三个参数中指定的字母的通配符。