使用 4 个可选参数制作自定义命令的最佳方法

使用 4 个可选参数制作自定义命令的最佳方法

我想创建一个产生以下结果的命令

\myquantity[Q]
\myquantity[Q][i]
\myquantity[Q][][j]
\myquantity[Q][i][j]
\myquantity[Q][i][j][\bar]
\myquantity[Q][][][\bar]
\myquantity[Q][][][\tilde]
\myquantity[Q_c][i][j][\bar]

结果

我当前的解决方案如下

\newcommandx{\myquantity}[4][1=, 2=, 3=, 4=]{
  \des[#4]{#1}{#3}(\lambda_{#2})}  

\des这个补充中的命令在哪里回答

有没有更简单的方法来获得相同的结果?

答案1

我想说的是,有四个可选参数不太符合语义。我会使用带有key=value可选参数的命令。

\myquantity[Q_c][i][j][\bar]

可读性远低于

\myquantity[accent=\bar,subscript={c,j},lambda subscript=i]{Q}

尽管后者可能使用了太长的键,但我希望您同意它更容易理解。

以下 MWE 使用键值参数给出了所需命令的示例。如果您确实认为键太长,您可以随时将其更改为您认为足够描述的内容。

\documentclass{article}

\usepackage{amsmath}
\usepackage{pgf}

\makeatletter
\newif\if@myquantity@subscript
\newif\if@myquantity@lambdasubscript
\pgfkeys{
    my quantity/.cd,
        accent/.code={\let\@myquantity@accent#1},
        accent=\relax,
        subscript/.code={\def\@myquantity@subscript{#1}\@myquantity@subscripttrue},
        lambda subscript/.code={\def\@myquantity@lambdasubscript{#1}\@myquantity@lambdasubscripttrue},
}
\newcommand{\myquantity}[2][]{%
    \@myquantity@subscriptfalse
    \@myquantity@lambdasubscriptfalse
    \pgfkeys{my quantity/.cd,#1}%
    \if@myquantity@subscript%
        \@myquantity@accent{#2}_{\@myquantity@subscript}%
    \else%
        \@myquantity@accent{\mathbf{#2}}%
    \fi%
    (\lambda%
    \if@myquantity@lambdasubscript
        _{\@myquantity@lambdasubscript}%
    \fi)%
}
\makeatother

\begin{document}
    \begin{equation*}
        \begin{array}{lll}
            \myquantity{Q} &
            \myquantity[lambda subscript=i]{Q} &
            \myquantity[subscript=j]{Q}\\
            \myquantity[subscript=j,lambda subscript=i]{Q} &
            \myquantity[accent=\bar,subscript=j,lambda subscript=i]{Q} &
            \myquantity[accent=\bar]{Q} \\
            \myquantity[accent=\tilde]{Q} &
            \myquantity[accent=\bar,subscript={c,j},lambda subscript=i]{Q}
        \end{array}
    \end{equation*}
\end{document}

导致

在此处输入图片描述

答案2

四个可选参数需要非常小心地输入。此外,其中一个是必需的,最后一个指的是必需参数,因此应首先指定。

我的想法是

\myq[<optional decoration>]{<variable>}[<optional coordinate>](<optional subscript)

所以没有必要指定空的可选参数。

_这些宏有什么作用?首先,我在可选参数中查找,因为\mathbf当没有出现坐标时,这不应该是其中的一部分。为此,\regex_split:nnN可以使用:如果未_找到,则序列将只有一个项目,否则将有两个(前面的_和后面的)。

然后需要检查坐标是否指定,以便决定\mathbf是否指定。

应该<decoration>是一个数学重音命令;它默认为\use:n,这意味着“输出参数”(经典的\@firstofone)。

\documentclass{article}
\usepackage[leqno,fleqn]{amsmath} % the options are just to better show the output
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\myq}{
  O{\use:n} % decoration for the main variable
  m         % main variable
  o         % coordinate
  d()       % subscript to \lambda
 }
 {
  % separate off the possible subscript to the variable;
  % item 1 contains the variable, item 2 the subscript
  \regex_split:nnN { \cD_ } { #2 } \l_simone_myq_var_seq
  % make the subscript
  \int_compare:nTF { \seq_count:N \l_simone_myq_var_seq = 1 }
   {% no subscript in #2
    \IfNoValueTF{#3}
     { #1 { \mathbf{#2} } }
     { #1 { #2 } \sb { #3 } }
   }
   {% subscript in #2
    \IfNoValueTF{#3}
     {
      #1 { \mathbf{\seq_item:Nn \l_simone_myq_var_seq { 1 }} } % base
      \sb { \seq_item:Nn \l_simone_myq_var_seq { 2 } }
     }
     {
      #1 { \seq_item:Nn \l_simone_myq_var_seq { 1 } } % base
      \sb { \seq_item:Nn \l_simone_myq_var_seq { 2 } , #3 }
     }
   }
  ( \lambda\IfValueT{#4}{\sb{#4}} )
 }

\seq_new:N \l_simone_myq_var_seq

\ExplSyntaxOff

\begin{document}

\begin{gather}
\myq{Q} \\
\myq[\bar]{Q} \\
\myq{Q}[i] \\
\myq{Q}(j) \\
\myq{Q}[i](j) \\
\myq[\tilde]{Q}(j) \\
\myq[\tilde]{Q}[i](j) \\
\myq{Q_c} \\
\myq[\bar]{Q_c} \\
\myq{Q_c}[i] \\
\myq{Q_c}(j) \\
\myq{Q_c}[i](j) \\
\myq[\tilde]{Q_c}(j) \\
\myq[\tilde]{Q_c}[i](j)
\end{gather}

\end{document}

在此处输入图片描述

相关内容