命令內帶有參數和多個結果(命令內...)

命令內帶有參數和多個結果(命令內...)

我想在另一個命令中重複使用執行相同類型操作(傳入表達式的特定解析)的命令,該命令應該會形成文檔的內容,並且也可以在文檔正文或第三個命令中重複出現。

\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

[02/05/2017] 範例替換為更現實的情況。現在它不能按我想要的方式工作。

螢幕截圖

[04/05/2017] 無論如何,有些事情超出了我的理解(這可能是不可避免的)...

\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}%
}

在此輸入影像描述

相關內容