在可选参数中使用 \Repeat 命令

在可选参数中使用 \Repeat 命令

动机

我想要一个\pythagoras命令,它接受一个表达式列表,以及第二个可选的括号形状列表,并返回一个勾股表达式。

期望结果

例如,

\pythagoras{a,b,c}

应该返回相当于

\sqrt{a^2+b^2+c^2}

尽管

\pythagoras{a,\frac{b}{2},c}[.,r,.]

应该返回相当于

\sqrt{a^2+\left(\frac{b}{2}\right)^2+c^2}

当前代码

\documentclass{article}
\usepackage{xparse,amsmath}

\ExplSyntaxOn

% count list
\NewDocumentCommand{\countlist}{m}{
    \clist_count:n { #1 }
}

% repeat command
\cs_new_eq:NN \Repeat \prg_replicate:nn

% brackets; my notation of r for round, s for square, c for curly
\NewDocumentCommand{\br}{O{r} O{#1} m}{
    \left
    \str_case:nnF { #1 } { {r}{(} {s}{[} {c}{\{} {v}{|} {V}{\|} {.}{.} } {.}
    #3
    \right
    \str_case:nnF { #2 } { {r}{)} {s}{]} {c}{\}} {v}{|} {V}{\|} {.}{.} } {.}
}

% pythagoras
\NewDocumentCommand{\pythagoras}{m O{.\Repeat{\countlist{#1}-1}{,.}}}{
    \seq_set_from_clist:Nn \l_tmpa_seq {#1}
    \seq_set_from_clist:Nn \l_tmpb_seq {#2}
    \cs_set:Npn \__mapper ##1##2 {\__sep \tl_if_empty:nTF { ##2 }{##1}{\br[##2]{##1}}^2}
    \cs_set:Npn \__sep {\cs_set:Npn \__sep {+}}
    \seq_mapthread_function:NNN \l_tmpa_seq \l_tmpb_seq \__mapper
}

\ExplSyntaxOff

问题

\Repeat我当前尝试使用可选参数创建括号形状的默认列表,但\pythagoras似乎不起作用。

\begin{document}
    \begin{align*}
        & \pythagoras{x,y}[.,.] \\           % pass the bracket parameters explicitly; works as desired
        & .\Repeat{\countlist{x,y}-1}{,.} \\ % the expression used in the definition; in the document, it works as desired
        & \pythagoras{x,y}                   % rely on the \Repeat command in the optional argument in the definition; 
                                             % should return x^2+y^2; 
                                             % actually returns x^2
    \end{align*}
\end{document}

我也不确定如何将总和包装在 中\sqrt。包装命令的相关行\pythagoras会返回错误。

致谢

  • \countlist摘自 egreg 对问题
  • \Repeat摘自 Joseph Wright 对问题
  • \br摘自 egreg 对问题
  • \pythagoras改编自 Don Hosek 对问题

答案1

这更简单。;-)作为围栏的说明符,我使用以下amsmath约定:

  • p对于(圆)括号
  • b方括号
  • B用于牙套
  • v表示垂直线(绝对值)
  • V对于双垂直线(标准)

您可以添加到列表或修改它,但我不建议使用可能造成混淆的不同缩写。

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand{\pythagoras}{mo}
 {
  \IfNoValueTF{#2}
   {
    \sqrt { \mjc_pythagoras:n { #1 } }
   }
   {
    \sqrt{ \mjc_pythagoras:nn { #1 } { #2 } }
   }
 }

\bool_new:N \l__mjc_pythagoras_delims_bool
\seq_new:N \l__mjc_pythagoras_items_seq
\seq_new:N \l__mjc_pythagoras_delims_seq
\seq_new:N \l__mjc_pythagoras_output_seq

\cs_new_protected:Nn \mjc_pythagoras:n
 {% no optional argument
  \seq_set_split:Nnn \l__mjc_pythagoras_items_seq { , } { #1 }
  \bool_set_false:N \l__mjc_pythagoras_delims_bool
  \__mjc_pythagoras:
 }
\cs_new_protected:Nn \mjc_pythagoras:nn
 {
  \seq_set_split:Nnn \l__mjc_pythagoras_items_seq { , } { #1 }
  \seq_set_split:Nnn \l__mjc_pythagoras_delims_seq { , } { #2 }
  \bool_set_true:N \l__mjc_pythagoras_delims_bool
  \__mjc_pythagoras:
 }

\cs_new_protected:Nn \__mjc_pythagoras:
 {
  \seq_clear:N \l__mjc_pythagoras_output_seq
  \seq_map_indexed_inline:Nn \l__mjc_pythagoras_items_seq
   {
    \seq_put_right:Nx \l__mjc_pythagoras_output_seq
     {
      \bool_if:NTF \l__mjc_pythagoras_delims_bool
       { \__mjc_pythagoras_left:n { ##1 } ##2 \__mjc_pythagoras_right:n { ##1 } }
       { ##2 }
      ^{2}
     }
   }
  \seq_use:Nn \l__mjc_pythagoras_output_seq { + }
 }

\cs_new:Nn \__mjc_pythagoras_left:n
 {
  \str_case_e:nn { \seq_item:Nn \l__mjc_pythagoras_delims_seq { #1 } }
   {
    {p}{\left(}
    {b}{\left[}
    {B}{\left\{}
    {v}{\left|}
    {V}{\left\|}
   }
 }
\cs_new:Nn \__mjc_pythagoras_right:n
 {
  \str_case_e:nn { \seq_item:Nn \l__mjc_pythagoras_delims_seq { #1 } }
   {
    {p}{\right)}
    {b}{\right]}
    {B}{\right\}}
    {v}{\right|}
    {V}{\right\|}
   }
 }

\ExplSyntaxOff

\begin{document}

\begin{gather*}
\pythagoras{a} \\
\pythagoras{a,b} \\
\pythagoras{a,b,c} \\
\pythagoras{a,\frac{1}{2},c}[.,p,.]
\end{gather*}

\end{document}

在此处输入图片描述

答案2

以下使用两种不同的输出例程,具体取决于是否使用可选参数。在两种情况下,它都使用该\clist_use:Nn函数。

\documentclass[]{article}


\ExplSyntaxOn
\clist_new:N \l_mjc_pythagoras_elements_clist
\clist_new:N \l_mjc_pythagoras_brackets_clist
\tl_new:N \l_mjc_pythagoras_element_tl
\msg_new:nnn { mjc-pythagoras } { unmatched-braces }
  {
    The~ bracket~ specification~ and~ the~ number~ of~ elements~ don't~ match.\\
    Elements:~ #1\\
    Brackets:~ #2
  }
\NewDocumentCommand \pythagoras { m o }
  {
    \sqrt
      {
        \group_begin:
          \clist_set:Nn \l_mjc_pythagoras_elements_clist {#1}
          \IfNoValueTF {#2}
            {
              \clist_use:Nn \l_mjc_pythagoras_elements_clist { \sp{2} + }
              \sp{2}
            }
            {
              \clist_set:Nn \l_mjc_pythagoras_brackets_clist {#2}
              \int_compare:nNnTF
                { \clist_count:N \l_mjc_pythagoras_elements_clist }
                =
                { \clist_count:N \l_mjc_pythagoras_brackets_clist }
                {
                  \__mjc_delimiter_left:
                  \clist_use:Nn \l_mjc_pythagoras_elements_clist
                    {
                      \__mjc_delimiter_right:
                      +
                      \__mjc_delimiter_left:
                    }
                  \__mjc_delimiter_right:
                }
                {
                  \msg_error:nnxx { mjc-pythagoras } { unmatched-braces }
                    { \clist_count:N \l_mjc_pythagoras_elements_clist }
                    { \clist_count:N \l_mjc_pythagoras_brackets_clist }
                }
            }
        \group_end:
      }
  }
\cs_new_protected:Npn \__mjc_delimiter_left:
  {
    \clist_pop:NN \l_mjc_pythagoras_brackets_clist \l_mjc_pythagoras_bracket_tl
    \str_case_e:nn \l_mjc_pythagoras_bracket_tl
      {
        { r } { \left( }
        { s } { \left[ }
        { c } { \left\{ }
        { v } { \left| }
        { V } { \left\| }
      }
  }
\cs_new_protected:Npn \__mjc_delimiter_right:
  {
    \str_case_e:nn \l_mjc_pythagoras_bracket_tl
      {
        { r } { \right) }
        { s } { \right] }
        { c } { \right\} }
        { v } { \right| }
        { V } { \right\| }
      }
    \sp {2}
  }
\ExplSyntaxOff

\begin{document}
$\pythagoras{a,b,c}$

$\pythagoras{a,b,c}[.,r,.]$

$\pythagoras{a,b,c}[.,r]$ % throws an error
\end{document}

相关内容