Estou trabalhando em uma macro que deve me poupar muito tempo no futuro. Atualmente, tenho um dos comandos que queria funcionando, mas estou tendo problemas para fazer a segunda parte funcionar. Esse primeiro comando é definido da seguinte forma:
\NewDocumentCommand\x
{
s
>{\SplitList{,}}o
>{\SplitList{,}}o
>{\SplitList{,}}o
>{\SplitList{,}}o
>{\SplitList{,}}o
>{\SplitList{,}}o
>{\SplitList{,}}o
>{\SplitList{,}}o
}{
% Full definition of the command
}
Este comando leva oito argumentos opcionais, cada um deles é uma lista separada por vírgulas, geralmente números, embora isso não seja obrigatório. Eu poderia chamá-lo de like \x[-3,0][0,-2]
ou \x[1,2,3,0][4,5,6,0][7,8,9,0]
. Cada lista terá sempre o mesmo comprimento.
Estou tentando criar um segundo comando que atue um pouco como uma transposição. Portanto, também são necessárias até oito listas, mas essas listas são separadas por estrelas e os elementos são listas do \x
comando. É mais fácil mostrar com um exemplo como funciona:
\mxm
[ [3,2]*[-3, 0]*[ 1,-2] ]
[ [1,1]*[ 0,-2]*[-1, 3] ]
seria equivalente a:
\x[3,2][1,1]
\x[-3,0][0,-2]
\x[1,-2][-1,3]
Cada uma dessas listas de estrelas teria o mesmo número de elementos. Se eles tivessem números diferentes de elementos ou elementos que não fossem argumentos do \x
comando então qualquer coisa poderia acontecer, um erro, inserir algum tipo de elemento nulo, truncar para a lista mais curta, etc. não importa.
O comprimento dessas listas é quantas \x
chamadas existem. Neste exemplo, o comprimento é três, portanto há três chamadas, \x
mas se o comprimento fosse maior ou menor, haveria um número diferente. O número de listas é quantos argumentos existem para cada chamada de \x
. Neste exemplo, existem dois, mas pode haver até 8.
Se possível, gostaria de poder passar uma estrela de \mxm*
para \x*
, mas se isso for muito difícil, tenho uma solução alternativa, pois ela não deve aparecer com muita frequência. Aqui está como seria:
\mxm[[1,3,1]*[-1, 0,3]]
[[2,2,1]*[ 0,-2,2]]
[[3,1,2]*[ 1,-2,1]]
seria equivalente a:
\x*[1,3,1]
[2,2,1]
[3,1,2]
\x*[-1, 0,3]
[ 0,-2,2]
[ 1,-2,1]
Aqui está um MWEcom um exemplo \x
(apenas um espaço reservado, não pode ser chamado \x
). Também inclui o quão longe cheguei, embora não possa imaginar que seja de muita ajuda.
Responder1
A recursão final, ou seja, macros que se autodenominam novamente e muita troca de argumentos antecipadamente, pode resolver o problema. ;-)
Se entendi direito, \mxm
é processar uma lista de argumentos opcionais em que cada argumento opcional contém uma *
lista separada de argumentos opcionais.
Você não especificou o que fazer caso nem todas *
as listas separadas de argumentos opcionais contenham a mesma quantidade de elementos.
Portanto, tomei a liberdade de implementar coisas de forma que [NULL]
sejam fornecidas sempre que *
elementos separados por -estão faltando devido a listas de comprimentos diferentes ou argumentos entre *
serem especificados como vazios.
\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}
Uma variação disso pode ser usada para criar matrizes:
\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}
Responder2
Se você deseja criar um \mxm
:
\mxm
[ [3,2]*[-3, 0]*[ 1,-2] ]
[ [1,1]*[ 0,-2]*[-1, 3] ]
pendência
\x[3,2][1,1]
\x[-3,0][0,-2]
\x[1,-2][-1,3]
então você pode definir
\def\mxm [ [#1]*[#2]*[#3] ] [ [#4]*[#5]*[#6] ]{%
\x[#1][#4]
\x[#2][#5]
\x[#3][#6]
}
Editar:Se entendi sua demanda, então você precisa transpor os parâmetros. Quando the \mxm
é fornecido com linhas e colunas arbitrárias, você precisa converter o
\mxm
[ [A1]*[A2]*[A3]*[A4] ]
[ [B1]*[B2]*[B3]*[B4] ]
[ [C1]*[C2]*[C3]*[C4] ]
em uma série de chamadas:
\x[A1][B1][C1]
\x[A2][B2][C2]
\x[A3][B3][C3]
\x[A4][B4][C4]
Você pode testar o seguinte código:
\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
O resultado da mensagem deste código (depois \pdftex testfile
) é:
running \x[A1][B1][C1] running \x[A2][B2][C2]
running \x[A3][B3][C3] running \x[A4][B4][C4]
Responder3
Não creio que esta seja uma boa abordagem, especialmente nos oito argumentos opcionais. Mas o cliente tem sempre razão.
\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}
Responder4
As coisas seriam muito mais fáceis se você não se importasse de usar aparelho.
\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}