带有参数的命令和命令内部的多个结果(在命令内部......)

带有参数的命令和命令内部的多个结果(在命令内部......)

我想重用一个在另一个命令中执行相同类型操作(对传入表达式的特定解析)的命令,该命令应构成文档的内容,并且也可以在文档正文或第三个命令中重复出现。

\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 年 2 月 5 日] 示例已替换为更现实的情况。现在它无法按我想要的方式工作。

截屏

[2017 年 4 月 5 日] 无论如何,有些事情我无法理解(这可能是不可避免的)......

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

在此处输入图片描述

相关内容