생성된 선택적 인수로 명령 호출

생성된 선택적 인수로 명령 호출

저는 앞으로 많은 시간을 절약할 수 있는 매크로를 작업 중입니다. 현재 원하는 명령 중 하나가 작동하고 있지만 두 번째 부분을 작동시키는 데 문제가 있습니다. 첫 번째 명령은 다음과 같이 정의됩니다.

\NewDocumentCommand\x
{
    s
    >{\SplitList{,}}o
    >{\SplitList{,}}o
    >{\SplitList{,}}o
    >{\SplitList{,}}o
    >{\SplitList{,}}o
    >{\SplitList{,}}o
    >{\SplitList{,}}o
    >{\SplitList{,}}o
}{
  % Full definition of the command
}

이 명령은 8개의 선택적 인수를 사용하며 각 인수는 쉼표로 구분된 목록이며 일반적으로 숫자이지만 필수는 아닙니다. 나는 그것을 \x[-3,0][0,-2]또는 와 같이 부를 수 있습니다 \x[1,2,3,0][4,5,6,0][7,8,9,0]. 각 목록의 길이는 항상 동일합니다.

저는 전치와 비슷한 역할을 하는 두 번째 명령을 만들려고 합니다. 따라서 최대 8개의 목록도 필요하지만 이러한 목록은 별표로 구분되어 있으며 요소는 명령의 목록입니다 \x. 작동 방식을 예시로 보여주는 것이 가장 쉽습니다.

\mxm
   [ [3,2]*[-3, 0]*[ 1,-2] ]
   [ [1,1]*[ 0,-2]*[-1, 3] ]

다음과 같습니다:

\x[3,2][1,1]
\x[-3,0][0,-2]
\x[1,-2][-1,3]

이러한 별 목록 각각에는 동일한 수의 요소가 있습니다. 요소의 수가 다르거나 명령의 인수가 아닌 요소가 있는 경우 \x오류, 일종의 null 요소 삽입, 가장 짧은 목록으로 잘림 등의 문제가 발생할 수 있습니다. 그런 식으로 호출되지 않으므로 그렇게 하지 않습니다. 상관없어.

이 목록의 길이는 \x통화 횟수입니다. 이 예에서는 길이가 3이므로 3번의 호출이 있지만 \x길이가 더 길거나 짧으면 다른 숫자가 발생합니다. 목록의 수는 각 호출에 대한 인수 수입니다 \x. 이 예에서는 2개가 있지만 최대 8개까지 있을 수 있습니다.

\mxm*가능하다면 별표를 에서 으로 전달할 수 있기를 원 \x*하지만 그것이 너무 어렵다면 별표가 자주 나오지 않아야 하기 때문에 대체 솔루션이 있습니다. 그 모습은 다음과 같습니다.

\mxm[[1,3,1]*[-1, 0,3]]
    [[2,2,1]*[ 0,-2,2]]
    [[3,1,2]*[ 1,-2,1]]

다음과 같습니다:

\x*[1,3,1]
   [2,2,1]
   [3,1,2]
\x*[-1, 0,3]
   [ 0,-2,2]
   [ 1,-2,1]

여기 MWE가 있습니다예를 들어 보겠습니다 \x(자리 표시자일 뿐이며 호출할 수 없음 \x). 또한 내가 얼마나 멀리까지 왔는지도 포함되어 있지만 그것이 큰 도움이 될 것이라고는 상상할 수 없습니다.

답변1

꼬리 재귀, 즉 자신을 다시 호출하는 매크로와 사전에 인수를 많이 교환하는 것이 트릭을 수행할 수 있습니다. ;-)

내가 올바르게 이해한다면 \mxm각 선택적 인수 자체가 분리된 선택적 인수 목록을 보유하는 선택적 인수 목록을 처리하는 것입니다 *.

*모든 분리된 선택적 인수 목록에 동일한 양의 요소가 포함되어 있지 않은 경우 수행할 작업을 지정하지 않았습니다 .

따라서 목록의 길이가 다르거나 인수가 비어 있도록 지정되어 있기 때문에 구분된 요소가 누락된 [NULL]곳마다 제공 되도록 자유롭게 구현했습니다 .**

\documentclass{article}
\usepackage{xparse}

\makeatletter
%%=============================================================================
%% Little helpers:
%%.............................................................................
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@Exchange[2]{#2#1}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral\expandafter\@secondoftwo\string{\expandafter
  \@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
  \@secondoftwo\string}\expandafter\z@\@secondoftwo}%
  {\expandafter\z@\@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Extract first inner undelimited argument:
%%.............................................................................
%%   \romannumeral\UD@ExtractFirstArgLoop{<argument>\UD@SelDOm}%
%%   yields <argument>'s 1st undelimited argument.
%%   <argument> must not be blank, i.e., must neither be empty nor consist
%%   only of explicit character tokens of catcode 10 and charcode 32.
%%
%%   \UD@SelDOm must not be defined in terms of \outer !
%%.............................................................................
\@ifdefinable\UD@RemoveTillUD@SelDOm{%
  \long\def\UD@RemoveTillUD@SelDOm#1#2\UD@SelDOm{{#1}}%
}%
\newcommand\UD@ExtractFirstArgLoop[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo{}#1}%
  {\expandafter\z@\@secondoftwo{}#1}%
  {\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillUD@SelDOm#1}}%
}%


%%=============================================================================
%% \mxm starts a loop for collecting an arbitrary amount of optional arguments.
%%.............................................................................
\NewDocumentCommand\mxm{}{\innermxm{}}%
%%-----------------------------------------------------------------------------
%% \innermxm checks if another optional argument is present.
%% If so it will be collected and \innermxm is called again.
%% Otherwise the loop for forming the calls to \x is started.
%%.............................................................................
\NewDocumentCommand\innermxm{m >{\SplitList{*}}o}{%
  % #1 - list of brace-nested optional arguments collected so far.
  % #2 - either the no-value-marker or the next optional argument:
  \IfNoValueTF{#2}{%
    % Start the loop for forming the calls to \x/for re-arranging things:
    %   \romannumeral is not really needed here, but while writing
    %   this I wanted the missing-number-error in case of messing up
    %   the tail-recursive \mxmloop's  flipping-around/exchanging
    %   of arguments. ;-)
    \romannumeral\mxmloop{\x}{}{}{#1}{}%
  }{%
    % Add the current optional argument to the list #1 and check if
    % another optional argument is present...
    \innermxm{#1{#2}}%
  }%
}%

\newcommand\mxmloop[5]{%
  %#1 - token-list produced so far forming current new call to \x
  %#2 - new list of lists
  %#3 - indicator if all elements of current list of lists were empty. 
  %#4 - current list of lists
  %#5 - list of calls to \x
  \UD@CheckWhetherNull{#4}{%
    \UD@CheckWhetherNull{#3}{%
      \z@#5% <- this \z@ terminates the (actually not needed)
           %   \romannumeral-expansion started by \innermxm. 
           %   It denotes a non-positive number and therefore
           %   gets removed silently.
    }{%
      \mxmloop{\x}{}{}{#2}{#5#1}%
    }%
  }{%
    \UD@PassFirstToSecond{#5}{%
      \expandafter\UD@PassFirstToSecond\expandafter{\@firstoftwo{}#4}{%
        \expandafter\UD@CheckWhetherNull\expandafter{\romannumeral\UD@ExtractFirstArgLoop{#4\UD@SelDOm}}{%
          \UD@PassFirstToSecond{#3}{%
            \UD@PassFirstToSecond{#2{}}{%
              \UD@PassFirstToSecond{#1[NULL]}{\mxmloop}%
            }%
          }%
        }{%
          \UD@PassFirstToSecond{m}{%
            \expandafter\UD@PassFirstToSecond\expandafter{%
              \romannumeral
              \expandafter\expandafter\expandafter\UD@PassFirstToSecond
              \expandafter\expandafter\expandafter{%
              \expandafter\@firstoftwo\expandafter{\expandafter}%
              \romannumeral\UD@ExtractFirstArgLoop{#4\UD@SelDOm}}{\z@#2}%
            }{%
              \expandafter\UD@CheckWhetherNull\expandafter{%
                \romannumeral\expandafter
                \UD@ExtractFirstArgLoop\expandafter{%
                  \romannumeral\UD@ExtractFirstArgLoop{#4\UD@SelDOm}%
                \UD@SelDOm}%
              }{%
                \UD@PassFirstToSecond{#1[NULL]}{\mxmloop}%
              }{%
                \expandafter\UD@PassFirstToSecond\expandafter{%
                  \romannumeral
                  \expandafter\UD@Exchange\expandafter{%
                    \romannumeral\expandafter
                    \UD@ExtractFirstArgLoop\expandafter{%
                      \romannumeral\UD@ExtractFirstArgLoop{#4\UD@SelDOm}%
                    \UD@SelDOm}%
                  }{\z@#1}%
                }{\mxmloop}%
              }%
            }%
          }%
        }%
      }%
    }%
  }%
}%

%%=============================================================================
% Let's define \x to collect an arbitrary amount of optional arguments and to display them:
\NewDocumentCommand\x{}{\innerx{}}%
\NewDocumentCommand\innerx{mo}{%
  \IfNoValueTF{#2}{\par\noindent\texttt{\detokenize\expandafter{\string\x#1}}}{\innerx{#1[#2]}}%
}%
\makeatother

\begin{document}

\footnotesize

\noindent Test 1:

\mxm
   [ [3,2]*[-3, 0]*[ 1,-2] ]
   [ [1,1]*[ 0,-2]*[-1, 3] ]
   [ [3,5]*[ 6,-7]*[-8, 9] ]

\bigskip\hrule\bigskip

\noindent Test 2:

\mxm
   [ [3,2]*[-3, 0] ]
   [ [1,1]*[ 0,-2]*[-1, 3] ]
   [ [3,5]*[ 6,-7]*[-8, 9] ]

\bigskip\hrule\bigskip

\noindent Test 3:

\mxm
   [ [3,2]*[-3, 0]*[ 1,-2]*[2,8] ]
   [ [1,1]*[ 0,-2]* * ]
   [ [3,5]*[ 6,-7]*[-8, 9]* ]

\bigskip\hrule\bigskip

\noindent Test 4:

\mxm
   [ [1,1]*[ 0,-2]]
   [ [3,2]*[-3, 0]*[ 1,-2]*[2,8]*[17,4] ]
   [ [3,5]*[ 6,-7]*[-8, 9]* ]

\bigskip\hrule\bigskip

\noindent Test 5:

\mxm
   [ [3,2]*[-3, 0]*[ 1,-2]*[2,8] ]
   [ ]
   [ [3,5]*[ 6,-7]*[-8, 9]* ]

\bigskip\hrule\bigskip

\noindent Test 6:

\mxm
   [ [3,2]*[-3, 0] ]
   [ [1,1]*[ 0,-2] ]
   [ [3,5]*[ 6,-7] ]
   [ [2,7]*[ 7,-0] ]
   [ [8,4]*[ 6,-0] ]

\bigskip\hrule\bigskip

\noindent Test 7:

\mxm
   [ [3,2]*[-3, 0]*[1,1]*[ 0,-2]*[3,5]*[ 6,-7] ]

\bigskip\hrule\bigskip

\noindent Test 8:

\mxm
   [ [3,2] ]

\bigskip\hrule\bigskip

\noindent Test 9:

\mxm
   [  ]

\bigskip\hrule\bigskip

\noindent Test 10:

\mxm

\noindent bla

\end{document}

여기에 이미지 설명을 입력하세요



이것의 변형을 사용하여 행렬을 만들 수 있습니다.

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

\makeatletter
%%=============================================================================
%% Little helpers:
%%.............................................................................
\newcommand\UD@PassFirstToSecond[2]{#2{#1}}%
\newcommand\UD@Exchange[2]{#2#1}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is empty>}%
%%                     {<Tokens to be delivered in case that argument
%%                       which is to be checked is not empty>}%
\newcommand\UD@CheckWhetherNull[1]{%
  \romannumeral\expandafter\@secondoftwo\string{\expandafter
  \@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
  \@secondoftwo\string}\expandafter\@firstoftwo\expandafter{\expandafter
  \@secondoftwo\string}\expandafter\z@\@secondoftwo}%
  {\expandafter\z@\@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Extract first inner undelimited argument:
%%.............................................................................
%%   \romannumeral\UD@ExtractFirstArgLoop{<argument>\UD@SelDOm}%
%%   yields <argument>'s 1st undlimited argument.
%%   <argument> must not be blank, i.e., must neither be empty nor consist
%%   only of explicit character tokens of catcode 10 and charcode 32.
%%
%%   \UD@SelDOm must not be defined in terms of \outer !
%%.............................................................................
\@ifdefinable\UD@RemoveTillUD@SelDOm{%
  \long\def\UD@RemoveTillUD@SelDOm#1#2\UD@SelDOm{{#1}}%
}%
\newcommand\UD@ExtractFirstArgLoop[1]{%
  \expandafter\UD@CheckWhetherNull\expandafter{\@firstoftwo{}#1}%
  {\expandafter\z@\@secondoftwo{}#1}%
  {\expandafter\UD@ExtractFirstArgLoop\expandafter{\UD@RemoveTillUD@SelDOm#1}}%
}%


%%=============================================================================
%% \mxm starts a loop for collecting an arbitrary amount of optional arguments.
%%.............................................................................
\NewDocumentCommand\mxm{s}{%
  \IfBooleanTF{#1}{\innermxm{\x*}{}}{\innermxm{\x}{}}%
}%
%%-----------------------------------------------------------------------------
%% \innermxm checks if another optional argument is present.
%% If so it will be collected and \innermxm is called again.
%% Otherwise the loop for forming the calls to \x is started.
%%.............................................................................
\NewDocumentCommand\innermxm{mm >{\SplitList{*}}o}{%
  % #1 - command for creating matrices
  % #2 - list of brace-nested optional arguments collected so far.
  % #3 - either the no-value-marker or the next optional argument:
  \IfNoValueTF{#3}{%
    % Start the loop for forming the calls to \x/for re-arranging things:
    %   \romannumeral is not really needed here, but while writing
    %   this I wanted the missing-number-error in case of messing up
    %   the tail-recursive \mxmloop's  flipping-around/exchanging
    %   of arguments. ;-)
    \romannumeral\mxmloop{#1}{}{}{}{#2}{}%
  }{%
    % Add the current optional argument to the list #2 and check if
    % another optional argument is present...
    \innermxm{#1}{#2{#3}}%
  }%
}%

\newcommand\mxmloop[6]{%
  %#1 - command for creating matrices
  %#2 - token-list produced so far forming current command for creating matrices
  %#3 - new list of lists
  %#4 - indicator if all elements of current list of lists were empty. 
  %#5 - current list of lists
  %#6 - list of calls for creating matrices
  \UD@CheckWhetherNull{#5}{%
    \UD@CheckWhetherNull{#4}{%
      \z@#6% <- this \z@ terminates the (actually not needed)
           %   \romannumeral-expansion started by \innermxm. 
           %   It denotes a non-positive number and therefore
           %   gets removed silently.
    }{%
      \mxmloop{#1}{}{}{}{#3}{#6#1#2}%
    }%
  }{%
    \UD@PassFirstToSecond{#6}{%
      \expandafter\UD@PassFirstToSecond\expandafter{\@firstoftwo{}#5}{%
        \expandafter\UD@CheckWhetherNull\expandafter{\romannumeral\UD@ExtractFirstArgLoop{#5\UD@SelDOm}}{%
          \UD@PassFirstToSecond{#4}{%
            \UD@PassFirstToSecond{#3{}}{%
              \UD@PassFirstToSecond{#2%[NULL]
                                      }{\mxmloop{#1}}%
            }%
          }%
        }{%
          \UD@PassFirstToSecond{m}{%
            \expandafter\UD@PassFirstToSecond\expandafter{%
              \romannumeral
              \expandafter\expandafter\expandafter\UD@PassFirstToSecond
              \expandafter\expandafter\expandafter{%
              \expandafter\@firstoftwo\expandafter{\expandafter}%
              \romannumeral\UD@ExtractFirstArgLoop{#5\UD@SelDOm}}{\z@#3}%
            }{%
              \expandafter\UD@CheckWhetherNull\expandafter{%
                \romannumeral\expandafter
                \UD@ExtractFirstArgLoop\expandafter{%
                  \romannumeral\UD@ExtractFirstArgLoop{#5\UD@SelDOm}%
                \UD@SelDOm}%
              }{%
                \UD@PassFirstToSecond{#2%[NULL]
                                        }{\mxmloop{#1}}%
              }{%
                \expandafter\UD@PassFirstToSecond\expandafter{%
                  \romannumeral
                  \expandafter\UD@Exchange\expandafter{%
                    \romannumeral\expandafter
                    \UD@ExtractFirstArgLoop\expandafter{%
                      \romannumeral\UD@ExtractFirstArgLoop{#5\UD@SelDOm}%
                    \UD@SelDOm}%
                  }{\z@#2}%
                }{\mxmloop{#1}}%
              }%
            }%
          }%
        }%
      }%
    }%
  }%
}%

%%=============================================================================
% Let's define \x to collect an arbitrary amount of optional arguments and to create a matrix of them:
\NewDocumentCommand\x{s}{%
  \IfBooleanTF{#1}{\innerx{}{}{pmatrix}}{\innerx{}{}{bmatrix}}%
}%
\NewDocumentCommand\innerx{mmm >{\SplitList{,}}o}{%
  % #1 - matrix-content created so far
  % #2 - things to prepend to matrix-row to create (empty with 1st row, \\ otherwise)
  % #3 - name of matrix-environment
  % #4 - optional argument from which next matrix-row is to be created
  \IfNoValueTF{#4}%
  {\UD@CheckWhetherNull{#1}{}{\begin{#3}#1\end{#3}}}%
  {%
    \expandafter\innerx
    \expandafter{\romannumeral\expandafter\UD@Exchange\expandafter{\romannumeral\intersperseloop{#4}{}{}}{\z@#1#2}}%
    {\\}%
    {#3}%
  }%
}%
\newcommand\intersperseloop[3]{%
  %#1 - argument list
  %#2 - interspersed list
  %#3 - token to prepend (empty with 1st element, & otherwise)
  \UD@CheckWhetherNull{#1}{\z@#2}{%
    \UD@PassFirstToSecond{&}{%
      \expandafter\UD@PassFirstToSecond\expandafter{%
        \romannumeral\expandafter\UD@Exchange\expandafter{\romannumeral\UD@ExtractFirstArgLoop{#1\UD@SelDOm}}{\z@#2#3}%
      }{%
        \expandafter\UD@PassFirstToSecond\expandafter{\@firstoftwo{}#1}{%
          \intersperseloop
        }%
      }%
    }%
  }%
}%

\makeatother

\begin{document}

\footnotesize

\noindent Test 1:

$$\mxm
     [ [3,2]*[-3, 0]*[ 1,-2] ]
     [ [1,1]*[ 0,-2]*[-1, 3] ]
     [ [3,5]*[ 6,-7]*[-8, 9] ]$$

\bigskip\hrule\bigskip

\noindent Test 2:

$$\mxm*
     [ [3,2]*[-3, 0]         ]
     [ [1,1]*[ 0,-2]*[-1, 3] ]
     [ [3,5]*[ 6,-7]*[-8, 9] ]$$

\bigskip\hrule\bigskip

\noindent Test 2a:

$$\mxm
     [ [3,2]*       *[-3, 0] ]
     [ [1,1]*[ 0,-2]*[-1, 3] ]
     [ [3,5]*[ 6,-7]*[-8, 9] ]$$



\bigskip\hrule\bigskip

\noindent Test 3:

$$\mxm
     [ [3,2] * [-3, 0] * [ 1,-2] * [2,8] ]
     [ [1,1] * [ 0,-2] *         *       ]
     [ [3,5] * [ 6,-7] * [-8, 9] *       ]$$

\bigskip\hrule\bigskip

\noindent Test 4:

$$\mxm
     [ [1,1]*[ 0,-2]]
     [ [3,2]*[-3, 0]*[ 1,-2]*[2,8]*[17,4] ]
     [ [3,5]*[ 6,-7]*[-8, 9]* ]$$

\bigskip\hrule\bigskip

\noindent Test 5:

$$\mxm
     [ [3,2]*[-3, 0]*[ 1,-2]*[2,8] ]
     [ ]
     [ [3,5]*[ 6,-7]*[-8, 9]* ]$$

\bigskip\hrule\bigskip

\noindent Test 6:

$$\mxm*
     [ [3,2]*[-3, 0] ]
     [ [1,1]*[ 0,-2] ]
     [ [3,5]*[ 6,-7] ]
     [ [2,7]*[ 7,-0] ]
     [ [8,4]*[ 6,-0] ]
     [ [3,2]*[-3, 0] ]
     [ [1,1]*[ 0,-2] ]
     [ [3,5]*[ 6,-7] ]
     [ [2,7]*[ 7,-0] ]
     [ [8,4]*[ 6,-0] ]
     [ [3,2]*[-3, 0] ]
     [ [1,1]*[ 0,-2] ]
     [ [3,5]*[ 6,-7] ]
     [ [2,7]*[ 7,-0] ]
     [ [8,4]*[ 6,-0] ]$$

\bigskip\hrule\bigskip

\noindent Test 6b:

$$\mxm
     [ [3,2] * [-3, 0]   *         ]
     [ [1,1] *           * [ 0,-2] ]
     [ [3,5] *           * [ 6,-7] ]
     [ [2,7] *           * [ 7,-0] ]
     [ [8,4] *           * [ 6,-0] ]
     [       *           * [ 6,-0] ]$$


\bigskip\hrule\bigskip

\noindent Test 7:

$$\mxm
     [ [3,2]*[-3, 0]*[1,1]*[ 0,-2]*[3,5]*[ 6,-7] ]$$

\bigskip\hrule\bigskip

\noindent Test 8:

$$\mxm
     [ [3,2] ]$$

\bigskip\hrule\bigskip

\noindent Test 9:

$$\mxm
     [  ]$$

\bigskip\hrule\bigskip

\noindent Test 10:

$$\mxm$$

\noindent bla

\end{document}

여기에 이미지 설명을 입력하세요 여기에 이미지 설명을 입력하세요

답변2

다음을 생성하려는 경우 \mxm:

\mxm
   [ [3,2]*[-3, 0]*[ 1,-2] ]
   [ [1,1]*[ 0,-2]*[-1, 3] ]

할 것

\x[3,2][1,1]
\x[-3,0][0,-2]
\x[1,-2][-1,3]

그런 다음 정의할 수 있습니다

\def\mxm [ [#1]*[#2]*[#3] ] [ [#4]*[#5]*[#6] ]{%
   \x[#1][#4]
   \x[#2][#5]
   \x[#3][#6]
}

편집하다:귀하의 요구를 이해했다면 매개변수를 바꿔야 합니다. 임의의 행과 열이 주어지면 \mxm다음을 변환해야 합니다.

\mxm
   [ [A1]*[A2]*[A3]*[A4] ]
   [ [B1]*[B2]*[B3]*[B4] ]
   [ [C1]*[C2]*[C3]*[C4] ]

일련의 호출로:

\x[A1][B1][C1]
\x[A2][B2][C2]
\x[A3][B3][C3]
\x[A4][B4][C4]

다음 코드를 테스트할 수 있습니다.

\newcount\numrows \newcount\tmpnum
\def\mxm {\numrows=0 \mxmA}
\def\mxmA [ #1 ] {\advance\numrows by1 \sdef{r:\the\numrows}{#1}%
   \futurelet\next\mxmB}
\def\mxmB {\ifx\next[\expandafter\mxmA \else \expandafter \mxmC\fi}
\def\mxmC {\expandafter\ifx \csname r:1\endcsname \empty \else
   \tmpnum=0 \def\xparams{}%
   \loop
      \advance\tmpnum by1
      \expandafter \expandafter \expandafter \mxmD
           \csname r:\the\tmpnum\endcsname \end
      \ifnum\tmpnum<\numrows \repeat
   \expandafter \x \xparams \relax
   \expandafter \mxmC \fi
}
\def\mxmD #1[#2]#3\end{\sdef{r:\the\tmpnum}{#3}\addto\xparams{[#2]}}

\long\def\addto#1#2{\expandafter\def\expandafter#1\expandafter{#1#2}}
\def\sdef#1{\expandafter\def\csname#1\endcsname}

% Just for testing:
\def\x #1\relax{\message{running \string\x #1}}

\mxm
     [ [A1]*[A2]*[A3]*[A4] ]
     [ [B1]*[B2]*[B3]*[B4] ]
     [ [C1]*[C2]*[C3]*[C4] ]

\bye

\pdftex testfile이 코드(뒤 ) 의 메시지 결과 는 다음과 같습니다.

running \x[A1][B1][C1] running \x[A2][B2][C2]
running \x[A3][B3][C3] running \x[A4][B4][C4]

답변3

나는 이것이 특히 8개의 선택적 인수에 있어서 좋은 접근 방식이라고 생각하지 않습니다. 하지만 고객의 말은 언제나 옳습니다.

\documentclass{article}
\usepackage{amsmath}

\ExplSyntaxOn

\NewDocumentCommand\makematrix{ s o o o o o o o o }
 {
  \begin{ \IfBooleanTF { #1 } { p } { b } matrix }
  \bryce_make_matrix:nnnnnnnn { #2 } { #3 } { #4 } { #5 } { #6 } { #7 } { #8 } { #9 }
  \end{ \IfBooleanTF { #1 } { p } { b } matrix }
 }
\NewDocumentCommand{\mxm} { s o o o o o o o o }
 {
  \group_begin: % localize the setting of the sequences
  \IfValueT{#2}
   {
    \seq_set_split:Nnn \l__bryce_mxm_i_seq { * } { #2 }
   }
  \IfValueT{#3}
   {
    \seq_set_split:Nnn \l__bryce_mxm_ii_seq { * } { #3 }
   }
  \IfValueT{#4}
   {
    \seq_set_split:Nnn \l__bryce_mxm_iii_seq { * } { #4 }
   }
  \IfValueT{#5}
   {
    \seq_set_split:Nnn \l__bryce_mxm_iv_seq { * } { #5 }
   }
  \IfValueT{#6}
   {
    \seq_set_split:Nnn \l__bryce_mxm_v_seq { * } { #6 }
   }
  \IfValueT{#7}
   {
    \seq_set_split:Nnn \l__bryce_mxm_vi_seq { * } { #7 }
   }
  \IfValueT{#8}
   {
    \seq_set_split:Nnn \l__bryce_mxm_vii_seq { * } { #8 }
   }
  \IfValueT{#9}
   {
    \seq_set_split:Nnn \l__bryce_mxm_viii_seq { * } { #9 }
   }
  \cs_set_protected:Nx \__bryce_mxm:
   {
    \makematrix \IfBooleanT { #1 } { * }
   }
  \__bryce_mxm_do:
  \group_end:
 }

\cs_new_protected:Nn \bryce_make_matrix:nnnnnnnn
 {
  \tl_if_novalue:nF { #1 } { \__bryce_make_row:n { #1 } }
  \tl_if_novalue:nF { #2 } { \__bryce_make_row:n { #2 } }
  \tl_if_novalue:nF { #3 } { \__bryce_make_row:n { #3 } }
  \tl_if_novalue:nF { #4 } { \__bryce_make_row:n { #4 } }
  \tl_if_novalue:nF { #5 } { \__bryce_make_row:n { #5 } }
  \tl_if_novalue:nF { #6 } { \__bryce_make_row:n { #6 } }
  \tl_if_novalue:nF { #7 } { \__bryce_make_row:n { #7 } }
  \tl_if_novalue:nF { #8 } { \__bryce_make_row:n { #8 } }
 }

\cs_new_protected:Nn \__bryce_make_row:n
 {
  \clist_set:Nn \l__bryce_row_clist { #1 }
  \clist_use:Nn \l__bryce_row_clist { & }
  \\
 }


\seq_new:N \l__bryce_mxm_i_seq
\seq_new:N \l__bryce_mxm_ii_seq
\seq_new:N \l__bryce_mxm_iii_seq
\seq_new:N \l__bryce_mxm_iv_seq
\seq_new:N \l__bryce_mxm_v_seq
\seq_new:N \l__bryce_mxm_vi_seq
\seq_new:N \l__bryce_mxm_vii_seq
\seq_new:N \l__bryce_mxm_viii_seq
\int_new:N \l__bryce_mxm_int

\cs_new_protected:Nn \__bryce_mxm_do:
 {
  \int_step_inline:nn { \seq_count:N \l__bryce_mxm_i_seq }
   {
    \int_set:Nn \l__bryce_mxm_int { ##1 }
    \exp_last_unbraced:Ne \__bryce_mxm: \__bryce_mxm_args:
   }
 }
\cs_new:Nn \__bryce_mxm_args:
 {
  \int_step_function:nN { 8 } \__bryce_mxm_args_aux:n
 }
\cs_new:Nn \__bryce_mxm_args_aux:n
 {
  \seq_item:cn { l__bryce_mxm_\int_to_roman:n { #1 }_seq } { \l__bryce_mxm_int }
 }

\ExplSyntaxOff

\begin{document}

\[
\makematrix[3,2][1,1]
\makematrix[-3, 0][ 0,-2]
\makematrix[ 1,-2][-1, 3]
\]

\[
\mxm
   [ [3,2]*[-3, 0]*[ 1,-2] ]
   [ [1,1]*[ 0,-2]*[-1, 3] ]
\]

\[
\makematrix*[3,2][1,1]
\makematrix*[-3, 0][ 0,-2]
\makematrix*[ 1,-2][-1, 3]
\]

\[
\mxm*
   [ [3,2]*[-3, 0]*[ 1,-2] ]
   [ [1,1]*[ 0,-2]*[-1, 3] ]
\]

\end{document}

여기에 이미지 설명을 입력하세요

답변4

일부 교정기를 사용해도 괜찮다면 상황이 훨씬 더 쉬울 것입니다.

여기에 이미지 설명을 입력하세요

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{expl3}
\usepackage{xparse}
\usepackage{amsmath}

\ExplSyntaxOn

\tl_new:N \l_doc_tmpa_tl
\tl_new:N \l_doc_tmpb_tl
\tl_new:N \l_doc_tmpc_tl

\int_new:N \l_doc_tmpa_int
\int_new:N \l_doc_tmpb_int
\int_new:N \l_doc_tmpc_int
\clist_new:N \l_doc_tmpa_clist

\seq_new:N \l_doc_tmpa_seq
\seq_new:N \l_doc_tmpb_seq
\seq_new:N \l_doc_tmpc_seq
\seq_new:N \l_doc_tmpd_seq
\seq_new:N \l_doc_tmpe_seq

\cs_set:Npn \doc_extract_square_bracket:nN #1#2 {
  \tl_set:Nn \l_doc_tmpa_tl {#1}
  \seq_clear:N #2
  \int_set:Nn \l_doc_tmpa_int {0}
  \tl_clear:N \l_doc_tmpc_tl
  
  \bool_do_until:nn {\tl_if_empty_p:N \l_doc_tmpa_tl} {
    \tl_set:Nx \l_doc_tmpb_tl {\tl_head:N \l_doc_tmpa_tl}
    \tl_set:Nx \l_doc_tmpa_tl {\tl_tail:N \l_doc_tmpa_tl}
    
    \exp_args:NV \str_case:nnF \l_doc_tmpb_tl {
      {[} {
        \int_compare:nNnT {\l_doc_tmpa_int} > {0} {
          \tl_put_right:NV \l_doc_tmpc_tl \l_doc_tmpb_tl
        }
        \int_incr:N \l_doc_tmpa_int
      }
      {]} {
        \int_decr:N \l_doc_tmpa_int
        \int_compare:nNnTF {\l_doc_tmpa_int} > {0} {
          \tl_put_right:NV \l_doc_tmpc_tl \l_doc_tmpb_tl
        }{
          \seq_put_right:NV #2 \l_doc_tmpc_tl
          \tl_clear:N \l_doc_tmpc_tl
        }
      }
    } {
      \int_compare:nNnT {\l_doc_tmpa_int} > {0} {
        \tl_put_right:NV \l_doc_tmpc_tl \l_doc_tmpb_tl
      }
    }
  }
}

\newcommand{\x}[1]{
  \seq_clear:N \l_doc_tmpc_seq
  \doc_extract_square_bracket:nN {#1} \l_doc_tmpb_seq
  \seq_map_variable:NNn \l_doc_tmpb_seq \l_doc_tmpa_tl {
    \clist_set:NV \l_doc_tmpa_clist \l_doc_tmpa_tl
    \seq_put_right:Nx \l_doc_tmpc_seq {\clist_use:Nn \l_doc_tmpa_clist {\c_alignment_token}}
  }
  \begin{bmatrix}
    \seq_use:Nn \l_doc_tmpc_seq {\\}
  \end{bmatrix}
}

\cs_set:Npn \doc_temp_seq_name:n #1 {
  l__doc_mat_\int_to_alph:n {#1}_seq
}

\newcommand{\mxm}[1]{
  \doc_extract_square_bracket:nN {#1} \l_doc_tmpd_seq
  
  \seq_get_left:NN \l_doc_tmpd_seq \l_doc_tmpa_tl
  \exp_args:NV \doc_extract_square_bracket:nN \l_doc_tmpa_tl \l_doc_tmpe_seq
  \int_set:Nn \l_doc_tmpb_int {\seq_count:N \l_doc_tmpe_seq}
  \seq_show:N \l_doc_tmpd_seq
  \int_step_inline:nn {\l_doc_tmpb_int} {
    \seq_clear:c {\doc_temp_seq_name:n {##1}}
  }
  
  \seq_map_variable:NNn \l_doc_tmpd_seq \l_doc_tmpa_tl {
    \exp_args:NV \doc_extract_square_bracket:nN \l_doc_tmpa_tl \l_doc_tmpe_seq
    \int_set:Nn \l_doc_tmpc_int {1}
    \seq_map_variable:NNn \l_doc_tmpe_seq \l_doc_tmpb_tl {
      \tl_clear:N \l_doc_tmpc_tl
      \tl_put_right:Nn \l_doc_tmpc_tl {[}
      \tl_put_right:NV \l_doc_tmpc_tl \l_doc_tmpb_tl
      \tl_put_right:Nn \l_doc_tmpc_tl {]}
      \seq_put_right:cV {\doc_temp_seq_name:n {\l_doc_tmpc_int}} \l_doc_tmpc_tl
      \int_incr:N \l_doc_tmpc_int
    }
  }
  
  \int_step_inline:nn {\l_doc_tmpb_int} {
    \tl_set:Nx \l_doc_tmpa_tl {\exp_not:N\x{\seq_use:cn {\doc_temp_seq_name:n {##1}} {}}}
    \tl_use:N \l_doc_tmpa_tl
  }
}

\ExplSyntaxOff

\begin{document}
$$\x{[1,2,3][4,5,6][7,8,9]}$$
$$\x{[1,2,3,4,5,6][a,b,c,d,e,f][6,5,4,3,2,1]}$$
$$\x{[1,2][3,4][5,6][7,8][9,10][11,12]}$$
$$
\mxm{
   [ [3,2]*[-3, 0]*[ 1,-2] ]
   [ [1,1]*[ 0,-2]*[-1, 3] ]
}
$$
$$
\mxm{
   [ [3,2]+[-3, 0]+[ 1,-2] ]
   [ [1,1]+[ 0,-2]+[-1, 3] ]
}
$$
$$
\mxm{
   [ [3,2][-3, \alpha][ 1,-2][5,6] ]
   [ [1,1][ 0,-2][-1, 3][5,6] ]
   [ [1,1][ 0,-2][-1, 3][5,6] ]
   [ [1,1][ 0,-2][-1, 3][5,6] ]
   [ [1,1][ 0,-2][-1, 3][5,6] ]
   [ [1,1][ 0,-2][\frac{3}{2}, 3][5,6] ]
}
$$
\end{document}

관련 정보