将可选参数放在最后

将可选参数放在最后

我一直在尝试修改解决方案这里进入一个 LaTeX3 命令,该命令采用可变长度的逗号分隔的数字列表和一个可选参数(单位),并打印每个数字的平方和的平方根(如果给定,则连同单位)。

\sumofsquares{2,3,-4}[m/s]应该给予

enter image description here

\sumofsquares{3,-4}[m/s]应该给予

enter image description here

我使用 Google 搜索过 LaTeX3 示例,但找到的示例(和的文档xparseexpl3都不包含任何示例。列表和序列之间的差异让我感到困惑。

答案1

这是一个使用序列的选项,它可能会变得更紧凑一些,因为两个辅助宏的代码几乎相同。

我不是专家,所以对我的建议持保留态度,但我会坚持使用sequences。它们需要一行行额外的代码,但它们提供的额外选项非常值得。

\documentclass{article}
\usepackage{xparse}
\usepackage{siunitx}
\ExplSyntaxOn
\NewDocumentCommand{\sumofsquares}{ m o }
    {
        \IfNoValueTF {#2}
            % if optional is missing call this
            {\sum_of_squares:n {#1}}
            % if not, then call this
            {\sum_of_squares:nn {#1}{#2}}
    }

\cs_new_protected:Npn \sum_of_squares:n #1
    {
        % does what the name suggests, set a sequence from the clist
        \seq_set_from_clist:Nn \l_tmpa_seq {#1}
        % applies final arg to each element of second seq and stores result in first seq
        \seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq {(##1)^2}
        % \seq_use puts the items from the seq back in the input with "+" as a separator
        \sqrt{\seq_use:Nnnn \l_tmpb_seq {+}{+}{+}}
    }
\cs_new_protected:Npn \sum_of_squares:nn #1 #2
    {
        % same as above, but with the addition of units
        \seq_set_from_clist:Nn \l_tmpa_seq {#1}
        \seq_set_map:NNn \l_tmpb_seq \l_tmpa_seq {(\SI{##1}{#2})^2}
        \sqrt{\seq_use:Nnnn \l_tmpb_seq {+}{+}{+}}
    }


\ExplSyntaxOff
\begin{document}

$\sumofsquares{2,3,-4}$\par\medskip
$\sumofsquares{2,3,-4}[m/s]$

\end{document}

下面是一个使用 s 的略短(且不太清晰)的示例clist。可以使用相同的方法来缩短上述代码。

\documentclass{article}
\usepackage{xparse}
\usepackage{siunitx}
\ExplSyntaxOn

\NewDocumentCommand{\sumofsquares}{ m O{} }
    {
        \sum_of_squares:nn {#1}{#2}
    }

\cs_new_protected:Npn \sum_of_squares:nn #1 #2
    {
        \tl_if_empty:nTF {#2}
            {
                \clist_set:Nn \l_tmpa_clist {#1}
                \sqrt{(\clist_use:Nnnn \l_tmpa_clist {)^2+(} {)^2+(} {)^2+(} )^2 }
            }
            {
                \clist_set:Nn \l_tmpa_clist {#1}
                \sqrt{(\clist_use:Nnnn \l_tmpa_clist {\,\si{#2})^2+(} {\,\si{#2})^2+(} {\,\si{#2})^2+(} \,\si{#2})^2}
            }
    }

\ExplSyntaxOff
\begin{document}

$\sumofsquares{2,3,-4}$\par\medskip
$\sumofsquares{2,3,-4}[m/s]$

\end{document}

答案2

嗯,你可以这样做xparse,所以

$\sumofsquares{2,3,-4}[m/s]$
$\sumofsquares{2,3,-4,4,7}$

产量:

enter image description here

参考:

代码:

\documentclass{article}
\usepackage{siunitx}
\usepackage{xparse}
\usepackage{pgffor}

\newcommand{\SequenceOfSquares}{}
\newcommand*{\TermSeparator}{}%
\NewDocumentCommand{\sumofsquares}{m O{}}{%
    \gdef\TermSeparator{}% clear up from last use (if any)
    \def\Sequence{#1}
    \foreach \x in  \Sequence {%
        \xdef\SequenceOfSquares{\SequenceOfSquares \TermSeparator (\SI{\x}{#2})^2}%
        \gdef\TermSeparator{+}%
    }
    \sqrt{\SequenceOfSquares}%
    \gdef\SequenceOfSquares{}%
}

\begin{document}
$\sumofsquares{2,3,-4}[m/s]$

\medskip
$\sumofsquares{2,3,-4,4,7}$
\end{document}

答案3

这是另一个解决方案。不需要解析在这个解决方案中:

\documentclass{article}
\usepackage{siunitx}
\makeatletter
\newcommand\sumofsquares[2][]{%
  \def\tempa{}%
  \@for\reserved:=#2\do{%
    \edef\tempa{\tempa\ifx\tempa\empty\else+\fi(\SI{\reserved}{#1})^2}%
  }
  \sqrt{\tempa}%
}
\makeatother
\begin{document}
$\sumofsquares[m/s]{2,3,-4}$
\par\medskip
$\sumofsquares{2,3,-4,4,7}$
\end{document}

将可选参数放在最后

这是 OP 的选择;我不推荐它。

\documentclass{article}
\usepackage{siunitx}
\makeatletter
\newcommand*\sumofsquares[1]{\@testopt{\@sumofsquares{#1}}{}}
\def\@sumofsquares#1[#2]{%
  \begingroup
  \def\tempa{}%
  \@for\reserved:=#1\do{%
    \edef\tempa{\tempa\ifx\tempa\empty\else+\fi(\SI{\reserved}{#2})^2}%
  }
  \expandafter\endgroup\expandafter\sqrt\expandafter{\tempa}%
}
\makeatother
\begin{document}
$\sumofsquares{2,3,-4}[m/s]$
\par\medskip
$\sumofsquares{2,3,-4,4,7}$
\end{document}

相关内容