具有嵌套序列和带宏的参数的自定义命令

具有嵌套序列和带宏的参数的自定义命令

我正在尝试创建一个使用嵌套序列的命令,例如 [[1,2,3],[4,5,6],...] 其中括号代表一个序列

我现在遇到的问题是无法将宏作为参数传递。希望得到帮助!

日志:

> ! Argument of \@sect has an extra }.
> <inserted text> 
>                 \par 
> l.42     \add{7}{8}{\textbf{9}}
>                             
> I've run across a `}' that doesn't seem to match anything.
> For example, `\def\a#1{...}' and `\a}' would produce
> this error. If you simply proceed now, the `\par' that
> I've just inserted will cause me to report a runaway
> argument that might be the root of the problem. But if
> your `}' was spurious, just type `2' and it will go away.
> 
> Runaway argument?
> {\normalfont \Large \bfseries }{9}\ifx \reserved@a \@empty \let \check@icl \ETC
> .
> ! Paragraph ended before \@sect was complete.
> <to be read again> 
>                    \par 
> l.42     \add{7}{8}{\textbf{9}}
>                             
> I suspect you've forgotten a `}', causing me to apply this
> control sequence to too much text. How can we recover?
> My plan is to forget the whole thing and hope for the best.
> 
> [1

梅威瑟:

\documentclass{article}

\usepackage{expl3}
\usepackage{tikz}

\usetikzlibrary{positioning}

\ExplSyntaxOn
\cs_generate_variant:Nn \seq_put_right:Nn {Ne}
\cs_generate_variant:Nn \seq_put_right:Nn {NV}

\seq_new:N \l__outer_seq
\seq_new:N \l__inner_seq
\int_new:N \l__last_node_int

\NewDocumentCommand\add{m m m}
{
    \seq_clear:N \l__inner_seq
    \seq_put_right:Ne \l__inner_seq {#1}
    \seq_put_right:Ne \l__inner_seq {#2}
    \seq_put_right:Ne \l__inner_seq {#3}
    \seq_put_right:NV \l__outer_seq \l__inner_seq
}

\NewDocumentCommand\draw{o}
{
    \int_set:Nn \l_tmpa_int {1}
    \int_set:Nn \l_tmpb_int {\int_eval:n {\seq_count:N \l__outer_seq + 1}}
    \int_zero:N \l__last_node_int
    
    \begin{tikzpicture}[every~node/.style={
            draw,
            line~width=1pt,
            minimum~height=30pt,
            node~distance=-1pt,
            transform~shape,
            shape=rectangle,
        }]
         \int_do_while:nNnn {\l_tmpa_int} < {\l_tmpb_int}
        {
            \seq_pop:NN \l__outer_seq \l_tmpa_seq
            
            \int_compare:nNnTF \l__last_node_int = 0
            {
                \int_incr:N {\l__last_node_int}
                \node (a\int_use:N \l__last_node_int) {\seq_item:Nn \l_tmpa_seq {1}};
                \node[right=of~{a\int_use:N \l__last_node_int}] (b\int_use:N \l__last_node_int) {\seq_item:Nn \l_tmpa_seq {2}};
                \node[right=of~{b\int_use:N \l__last_node_int}] (c\int_use:N \l__last_node_int) {\seq_item:Nn \l_tmpa_seq {3}};
            }
            {
                \int_incr:N {\l__last_node_int}
                \node[below=of~{a\int_eval:n {\l__last_node_int - 1}}]  (a\int_use:N \l__last_node_int) {\seq_item:Nn \l_tmpa_seq {1}};
                \node[below=of~{b\int_eval:n {\l__last_node_int - 1}}] (b\int_use:N \l__last_node_int) {\seq_item:Nn \l_tmpa_seq {2}};
                \node[below=of~{c\int_eval:n {\l__last_node_int - 1}}] (c\int_use:N \l__last_node_int) {\seq_item:Nn \l_tmpa_seq {3}};
            }
            \int_incr:N {\l_tmpa_int}
        }
    \end{tikzpicture}
    \tl_clear:N \l__last_node_tl
}

\ExplSyntaxOff


\begin{document}
    \section{MWE}
    \add{1}{2}{3}
    \add{4}{5}{6}
    
% Error
%   \add{7}{8}{\textbf{9}}
    \draw
\end{document}

答案1

您不能将序列存储在序列中:向您提出的代码仅存储一个变量,该变量将始终指向其当前值。

但是,您可以使用合适的分隔符存储序列项,然后在需要时重新构建它。

\int_step_inline:nn我使用比 while 循环更简单的代码来简化代码。我还根据推荐的指导方针重命名了变量。

另一个问题是使用\seq_put_right:Neon \textbf{9},这是错误的。我将其替换为\seq_put_right:Nn

\documentclass{article}

\usepackage{expl3}
\usepackage{tikz}

\usetikzlibrary{positioning}

\ExplSyntaxOn
\quark_new:N \q_nyannyan_sep
\cs_generate_variant:Nn \seq_put_right:Nn {Ne}

\seq_new:N \l__nyannyan_outer_seq
\seq_new:N \l__nyannyan_inner_seq
\int_new:N \l__nyannyan_last_node_int

\NewDocumentCommand\add{m m m}
 {
  \seq_clear:N \l__nyannyan_inner_seq
  \seq_put_right:Nn \l__nyannyan_inner_seq {#1}
  \seq_put_right:Nn \l__nyannyan_inner_seq {#2}
  \seq_put_right:Nn \l__nyannyan_inner_seq {#3}
  \seq_put_right:Ne \l__nyannyan_outer_seq
   {
    \seq_use:Nn \l__nyannyan_inner_seq { \q_nyannyan_sep }
   }
 }

\NewDocumentCommand\drawpicture {}
 {
  \int_zero:N \l__nyannyan_last_node_int
    
  \begin{tikzpicture}[
    every~node/.style={
      draw,
      line~width=1pt,
      minimum~height=30pt,
      node~distance=-1pt,
      transform~shape,
      shape=rectangle,
    }
  ]
  \int_step_inline:nn { \seq_count:N \l__nyannyan_outer_seq }
   {
    % reconstitute the stored sequences
    \seq_pop_left:NN \l__nyannyan_outer_seq \l_tmpa_tl
    \seq_set_split:NnV \l__nyannyan_inner_seq { \q_nyannyan_sep } \l_tmpa_tl

    \int_compare:nNnTF { \l__nyannyan_last_node_int } = { 0 }
     {
      \int_incr:N \l__nyannyan_last_node_int
      \node (a\int_use:N \l__nyannyan_last_node_int) {\seq_item:Nn \l__nyannyan_inner_seq {1}};
      \node[right=of~{a\int_use:N \l__nyannyan_last_node_int}]
        (b\int_use:N \l__nyannyan_last_node_int) {\seq_item:Nn \l__nyannyan_inner_seq {2}};
      \node[right=of~{b\int_use:N \l__nyannyan_last_node_int}]
        (c\int_use:N \l__nyannyan_last_node_int) {\seq_item:Nn \l__nyannyan_inner_seq {3}};
     }
     {
      \int_incr:N \l__nyannyan_last_node_int
      \node[below=of~{a\int_eval:n {\l__nyannyan_last_node_int - 1}}]
        (a\int_use:N \l__nyannyan_last_node_int) {\seq_item:Nn \l__nyannyan_inner_seq {1}};
      \node[below=of~{b\int_eval:n {\l__nyannyan_last_node_int - 1}}]
        (b\int_use:N \l__nyannyan_last_node_int) {\seq_item:Nn \l__nyannyan_inner_seq {2}};
      \node[below=of~{c\int_eval:n {\l__nyannyan_last_node_int - 1}}]
        (c\int_use:N \l__nyannyan_last_node_int) {\seq_item:Nn \l__nyannyan_inner_seq {3}};
     }
   }
  \end{tikzpicture}
}

\ExplSyntaxOff


\begin{document}

\section{MWE}

\add{1}{2}{3}
\add{4}{5}{6}
\add{7}{8}{\textbf{9}}

\drawpicture

\end{document}

在此处输入图片描述

相关内容