如何在自定义命令中使用 for 循环?

如何在自定义命令中使用 for 循环?

我有一个很好的代码片段来生成一个DI 表分部积分:

\documentclass{article}

\usepackage{xparse}
\usepackage{amsmath}
\usepackage{tikz}
\usepackage{pgffor}
\usepackage{mathtools}
\usepackage{nicematrix}
\usepackage{booktabs}
\usepackage{physics}
\usepackage{listofitems}
\usepackage{derivative}

\begin{document}
\[
\begin{NiceArray}{cc@{\hspace*{1.0cm}}c}[create-medium-nodes, cell-space-limits=5pt]
  \toprule
     & D & I \\
  \cmidrule{2-3}
    + & x^2 & e^x \\
    - & 2x & e^x \\
    + & 2 & e^x \\
    - & 0 & e^x \\
  \bottomrule
\CodeAfter
    \begin{tikzpicture}[->, name suffix = -medium]
        \draw[red] (2-2) -- node [above] {} (3-3);
        \draw[red] (3-2) -- node [above] {} (4-3);
        \draw[red] (4-2) -- node [above] {} (5-3);
    \end{tikzpicture}
\end{NiceArray}
\]
\[ \int x^2 e^x \odif{x} = x^2 e^x - 2x e^x + 2e^x + C \]
\end{document}

我想xparse为这段代码编写一个命令,这样每次进行分部积分时就不必复制粘贴它,也不必在行数发生变化时手动修改代码。问题是我需要使用某种形式的 for 循环来生成行、交替符号和箭头。

我尝试使用该lisofitems包让命令获取表中的行列表并使用pgffor包获取循环,最后得到了以下代码:

\documentclass{article}

\usepackage{xparse}
\usepackage{amsmath}
\usepackage{tikz}
\usepackage{pgffor}
\usepackage{mathtools}
\usepackage{nicematrix}
\usepackage{booktabs}
\usepackage{physics}
\usepackage{listofitems}
\usepackage{derivative}

\NewDocumentCommand{\DI}{ m }{
\setsepchar{;/,}
\readlist\lines{#1}
\begin{NiceArray}{cc@{\hspace*{1.0cm}}c}[create-medium-nodes, cell-space-limits=5pt]
    \toprule
        & D & I \\
    \cmidrule{2-3}
    \foreach \i in {1,...,\lineslen}{
        \ifodd\i+\else-\fi & \lines[\i, 1] & \lines[\i, 2] \\
    }
    \bottomrule
\CodeAfter
    \begin{tikzpicture}[->, name suffix = -medium]
        \foreach \i in {2,...,\lineslen}{
            \pgfmathtruncatemacro{\prev}{\i-1}
            \draw[red] (\prev-2) -- node [above] {} (\i-3);
        }
    \end{tikzpicture}
\end{NiceArray}
}


\begin{document}
\[ \DI{x^2,e^x ; 2x,e^x ; 2,e^x ; 0,e^x} \]
\[ \int x^2 e^x \odif{x} = x^2 e^x - 2x e^x + 2e^x + C \]
\end{document}

但是,这段代码无法编译并产生错误,我不知道哪里出了问题。我无法弄清楚如何使用 for 循环来生成行。

从示例中可以看出,我希望此命令具有以下语法: \DI{D1,I1 ; D2,I2 ; ...} 其中每对都是表格的一行。交替符号和箭头应自动处理。

如果有人能解释我的尝试失败的原因以及如何修复它,我将不胜感激。使用除和之外的软件包的其他解决方案listofitems也是pgffor可以接受的,只要它能产生正确的输出。

答案1

以下使用 L3 编程语言进行工作。

\documentclass{article}

\usepackage{mathtools}
\usepackage{nicematrix}
\usepackage{tikz}
\usepackage{booktabs}
\usepackage{derivative}

\ExplSyntaxOn
\seq_new:N \l_shaiavr_items_seq
\tl_new:N \g_shaiavr_sign_tl
\NewDocumentCommand{\DI}{ m }
  {
    \seq_set_split:Nnn \l_shaiavr_items_seq { ; } {#1}
    \tl_gset:Nn \g_shaiavr_sign_tl { + }
    \begin{NiceArray}{cc@{\hspace*{1.0cm}}c}[create-medium-nodes, cell-space-limits=5pt]
        \toprule
            & D & I \\
        \cmidrule{2-3}
        \seq_map_function:NN \l_shaiavr_items_seq \__shaiavr_line_formatter:n
        \bottomrule
    \CodeAfter
        \begin{tikzpicture}[->, name~ suffix = -medium]
          \int_step_inline:nnn {2} { \seq_count:N \l_shaiavr_items_seq }
            { \draw[red] (##1 - 2) -- (\int_eval:n { ##1 + 1 } -3); }
        \end{tikzpicture}
    \end{NiceArray}
  }
\cs_new_protected:Npn \__shaiavr_line_formatter:n #1
  {
    \g_shaiavr_sign_tl & \clist_item:nn {#1} { 1 } & \clist_item:nn {#1} { 2 }
    \tl_if_eq:NnTF \g_shaiavr_sign_tl { + }
      { \tl_gset:Nn \g_shaiavr_sign_tl { - } }
      { \tl_gset:Nn \g_shaiavr_sign_tl { + } }
    \\
  }
\ExplSyntaxOff


\begin{document}
\[ \DI{x^2,e^x ; 2x,e^x ; 2,e^x ; 0,e^x} \]
\[ \int x^2 e^x \odif{x} = x^2 e^x - 2x e^x + 2e^x + C \]
\end{document}

在此处输入图片描述

相关内容