동일한 유형의 작업(수신 표현식의 특정 구문 분석)을 수행하는 명령을 다른 명령 내에서 재사용하고 싶습니다. 이 명령은 문서의 내용을 구성해야 하며 문서 본문이나 세 번째 명령에서도 반복적으로 발생할 수 있습니다. .
\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}
복잡한 상황에서 명령을 사용하면 구문 분석된 표현식의 일부 값이 누락되는 등 다양한 오류가 발생합니다. 이 명령은 내부 세 번째 명령 내부에서 사용됩니다 tikzpicture
. 예를 들어 \pgfgettransformentries
.
[2017/02/05] 예시가 보다 현실적인 상황으로 대체되었습니다. 이제는 내 뜻대로 되지 않네요.
[2017/04/05] 어쨌든 제가 이해하기 어려운 부분이 있습니다(어쩌면 피할 수 없는 일이겠죠)...
\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}
이 경우 결과를 일치시키는 방법은 무엇입니까?
답변1
내 의견에서 말했듯이, \parsecommand
이에 대한 조치를 취하기 전에 주장을 확장해야 합니다.
\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}%
}