Quiero reutilizar un comando que realiza el mismo tipo de acción (un análisis específico de la expresión entrante) dentro del otro comando, que debería formar el contenido del documento y también puede ocurrir repetidamente en el cuerpo del documento o en el tercer comando. .
\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\ExplSyntaxOn
\int_new:N \l_opt_number_int
\cs_new_protected:Npn \parsecommand #1#2#3#4#5 {
%\NewDocumentCommand{\parsecommand}{
% m % #1 expression to parse
% m % #2 */empty
% m % #3 +/-/empty
% m % #4 part before ! / 1
% m % #5 part after ! / empty
%}{
\int_zero:N \l_opt_number_int
\tl_clear:N #2
\tl_clear:N #3
\tl_clear:N #4
\tl_clear:N #5
\tl_if_in:NnTF #1 {!} {
\tl_map_inline:Nn #1 {
\bool_set_false:N \l_done_bool
\tl_case:Nn ##1 {
* {\int_compare:nT {\l_opt_number_int < 1}{
\tl_set_eq:NN #2 ##1
\bool_set_true:N \l_done_bool
\int_set:Nn \l_opt_number_int {1}}}
- {\int_compare:nT {\l_opt_number_int < 2}{
\tl_set_eq:NN #3 ##1
\bool_set_true:N \l_done_bool
\int_set:Nn \l_opt_number_int {2}}}
+ {\int_compare:nT {\l_opt_number_int < 2}{
\tl_set_eq:NN #3 ##1
\bool_set_true:N \l_done_bool
\int_set:Nn \l_opt_number_int {2}}}
! {\int_compare:nT {\l_opt_number_int < 3}{
\bool_set_true:N \l_done_bool
\int_set:Nn \l_opt_number_int {3}}}
}
\bool_if:NF \l_done_bool {
\int_compare:nTF {\l_opt_number_int < 3}
{\tl_put_right:Nn #4 {##1}}
{\tl_put_right:Nn #5 {##1}}
}
}
}
{\tl_set_eq:NN #5 #1}
\tl_if_empty:NT #4 {\tl_put_right:Nn #4 {1}}
}
\ExplSyntaxOff
\NewDocumentCommand{\othercommandone}{m}{
\parsecommand{#1}{\a}{\b}{\c}{\d}
\{#1\} $\rightarrow$ \{\a\}\{\b\}\{\c\}\{\d\}
}
\NewDocumentCommand{\othercommandtwo}{m}{
\def\incoming{#1}
\parsecommand{\incoming}{\a}{\b}{\c}{\d}
\{\incoming\} $\rightarrow$ \{\a\}\{\b\}\{\c\}\{\d\}
}
\NewDocumentCommand{\drawcommandone}{m}{
\begin{tikzpicture}[baseline]
\parsecommand{#1}{\douter}{\danchor}{\nthy}{\dlabel}
\draw (-1,0) -- (1,0);
\node at (0,\nthy*5mm) {\dlabel};
\end{tikzpicture}
}
\NewDocumentCommand{\drawcommandtwo}{m}{
\begin{tikzpicture}[baseline]
\def\incoming{#1}
\parsecommand{\incoming}{\douter}{\danchor}{\nthy}{\dlabel}
\draw (-1,0) -- (1,0);
\node at (0,\nthy*1cm) {\dlabel};
\end{tikzpicture}
}
\begin{document}
\def\something{*+5!abc}
\def\somethingelse{+777}
\def\somethingmore{-!$\sqrt{\alpha}$}
Directly in the document command works\ldots
\parsecommand{\something}{\a}{\b}{\c}{\d}
\{\something\} $\rightarrow$ \{\a\}\{\b\}\{\c\}\{\d\}
\parsecommand{\somethingelse}{\a}{\b}{\c}{\d}
\{\somethingelse\} $\rightarrow$ \{\a\}\{\b\}\{\c\}\{\d\}
\parsecommand{\somethingmore}{\a}{\b}{\c}{\d}
\{\somethingmore\} $\rightarrow$ \{\a\}\{\b\}\{\c\}\{\d\}
\bigskip
If command is used directly with argument, there are no problems\ldots
\othercommandone{\something}
\othercommandone{\somethingelse}
\othercommandone{\somethingmore}
\bigskip
If command is used via intermediate macro, there are problems\ldots
\othercommandtwo{\something}
\othercommandtwo{\somethingelse}
\othercommandtwo{\somethingmore}
\bigskip
For purity of experiment, application inside \verb|tikzpicture| directly with argument, everything is fine\ldots
\drawcommandone{\something}
\hspace{1cm}
\drawcommandone{\somethingelse}
\hspace{1cm}
\drawcommandone{\somethingmore}
\bigskip
Finally, as it must be, with internal intermediate transformation (it is planned to split comma-separated values), problems arise again\ldots
\drawcommandtwo{\something}
\hspace{1cm}
\drawcommandtwo{\somethingelse}
\hspace{1cm}
\drawcommandtwo{\somethingmore}
\end{document}
Cuando se utiliza el comando en situaciones complejas, se producen varios errores, incluida la ausencia de algunos valores de la expresión analizada. El comando se usa dentro del tikzpicture
tercer comando interno. Quería que usara, por ejemplo, resultados similares de \pgfgettransformentries
.
[05/02/2017] Ejemplo reemplazado por una situación más realista. Ahora no funciona como quiero.
[05/04/2017] De todos modos, algo se escapa a mi comprensión (esto probablemente sea inevitable)...
\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\ExplSyntaxOn
\NewDocumentCommand{\extractfirst}{mm}{\tl_set:Nx #1 {\clist_item:Nn #2 {1} }}
\NewDocumentCommand{\extractlast}{mm}{\tl_set:Nx #1 {\clist_item:Nn #2 {-1} }}
\int_new:N \l_opt_number_int
\cs_new_protected:Npn \parsecommand #1#2#3#4#5 {
%\NewDocumentCommand{\parsecommand}{
% m % #1 expression to parse
% m % #2 */empty
% m % #3 +/-/empty
% m % #4 part before ! / 1
% m % #5 part after ! / empty
%}{
\int_zero:N \l_opt_number_int
\tl_clear:N #2
\tl_clear:N #3
\tl_clear:N #4
\tl_clear:N #5
\tl_if_in:NnTF #1 {!} {
\tl_map_inline:Nn #1 {
\bool_set_false:N \l_done_bool
\tl_case:Nn ##1 {
* {\int_compare:nT {\l_opt_number_int < 1}{
\tl_set_eq:NN #2 ##1
\bool_set_true:N \l_done_bool
\int_set:Nn \l_opt_number_int {1}}}
- {\int_compare:nT {\l_opt_number_int < 2}{
\tl_set_eq:NN #3 ##1
\bool_set_true:N \l_done_bool
\int_set:Nn \l_opt_number_int {2}}}
+ {\int_compare:nT {\l_opt_number_int < 2}{
\tl_set_eq:NN #3 ##1
\bool_set_true:N \l_done_bool
\int_set:Nn \l_opt_number_int {2}}}
! {\int_compare:nT {\l_opt_number_int < 3}{
\bool_set_true:N \l_done_bool
\int_set:Nn \l_opt_number_int {3}}}
}
\bool_if:NF \l_done_bool {
\int_compare:nTF {\l_opt_number_int < 3}
{\tl_put_right:Nn #4 {##1}}
{\tl_put_right:Nn #5 {##1}}
}
}
}
{\tl_set_eq:NN #5 #1}
\tl_if_empty:NT #4 {\tl_put_right:Nn #4 {1}}
}
\ExplSyntaxOff
\NewDocumentCommand{\drawcommandone}{m}{%
\begin{tikzpicture}[baseline]
\extractfirst{\frstprt}{#1}
\extractlast{\lstprt}{#1}
\draw (-3,0) -- (-1,0);
\node [anchor=north] at (-2,0) {\frstprt};
\parsecommand{\frstprt}{\douter}{\danchor}{\nthy}{\dlabel}
\node at (-2,\nthy*4mm) {\dlabel};
\draw (1,0) -- (3,0);
\node [anchor=north] at (2,0) {\lstprt};
\parsecommand{\lstprt}{\douter}{\danchor}{\nthy}{\dlabel}
\node at (2,\nthy*4mm) {\dlabel};
\end{tikzpicture}%
}
\NewDocumentCommand{\drawcommandtwo}{m}{%
\begin{tikzpicture}[baseline]
\def\incoming{#1}%
\extractfirst{\frstprt}{\incoming}
\extractlast{\lstprt}{\incoming}
\draw (-3,0) -- (-1,0);
\node [anchor=north] at (-2,0) {\frstprt};
\expandafter\parsecommand\expandafter{\frstprt}{\douter}{\danchor}{\nthy}{\dlabel}
\node at (-2,\nthy*4mm) {\dlabel};
\draw (1,0) -- (3,0);
\node [anchor=north] at (2,0) {\lstprt};
\expandafter\parsecommand\expandafter{\lstprt}{\douter}{\danchor}{\nthy}{\dlabel}
\node at (2,\nthy*4mm) {\dlabel};
\end{tikzpicture}%
}
\begin{document}
%\def\something{*+5!first,+2!second}
%\def\something{+777,*!150}
\def\something{3!$\sqrt{\alpha}$,2!$\beta^2$}
\drawcommandone{\something}
\vspace{1cm}
\drawcommandtwo{\something}
\end{document}
¿Cómo hacer que los resultados coincidan en este caso?
Respuesta1
Como dije en mi comentario, es necesario ampliar el argumento antes de \parsecommand
actuar en consecuencia:
\NewDocumentCommand{\drawcommandtwo}{m}{%
\begin{tikzpicture}[baseline]
\def\incoming{#1}%
\expandafter\parsecommand\expandafter{\incoming}{\douter}{\danchor}{\nthy}{\dlabel}
\draw (-1,0) -- (1,0);
\node at (0,\nthy*5mm) {\dlabel};
\end{tikzpicture}%
}