通过 `tl` 变量将内容插入 tikzpicture 环境

通过 `tl` 变量将内容插入 tikzpicture 环境

自动化 tikzpicture 环境:这个想法是在环境中定义 (a)[options][styles]和 (b),不是通过将文字字符串插入环境来手动定义,而是通过插入变量来定义,变量的值可以在为该任务指定的宏中生成。使用 @egreg 对 @Tobi 的 的回答 解决了 的问题,但我仍然不得不考虑如何提供。PS 如果它再次出现在s、s 或s 中,我将不得不第五次展示。contenttikzpicturetlquestion asked Feb 5 '16 at 19:12options/stylescontentxnV

\documentclass{article}
% RN. Friday 1 December 2017
%=======================
\usepackage[check-declarations]{expl3}
\usepackage{xparse}
\usepackage{tikz}
%-----------------------
\ExplSyntaxOn
\cs_new_protected:Nn \__rn_start_tikzpicture:n {\begin{tikzpicture}[#1]}
\cs_generate_variant:Nn \__rn_start_tikzpicture:n { V }
\tl_new:N \l_rn_Aux_tl
\tl_new:N \l_rn_auxOne_tl

\tl_new:N \g_rn_tikzStyle_FR_tl
\cs_new:Npn \rn_generateTikzStyle_FR:n #1
%  PARAMETERS: #1 dummy variable 
%  RETURNS: \g_rn_tikzStyle_FR_tl to be plugged into tikzpicture environment
  {
\group_begin:
    % number of levels determines the values for level distance, sibling   distance, 
    % and node style. Computing and setting the variable adds no difficulties
    % to setting it in the following way: 
    \tl_gset:Nx \g_rn_tikzStyle_FR_tl {level~distance=10mm,
  every~node/.style={circle,draw,inner~sep=1pt},
  level~1/.style={sibling~distance=30mm}}  
\group_end:
  }  %  \rn_generateTikzStyle_FR:n

\tl_new:N \g_rn_tikzContent_FR_tl
\cs_new:Npn \rn_generateTikzContent_FR:n #1
%  PARAMETERS: #1 dummy parameter specifys the key values for the nodes of the tree.
%  RETURNS: \g_rn_tikzContent_FR_tl to be plugged into tikzpicture environment
  {
\group_begin:
    %  \tl_gset:Nn \g_rn_tikzContent_FR_tl {\node{10}child{node{5}}child{node{15}};} 
    % ... setting the return variable in above fashion works, but does not address the 
    % problem as in actual practice the content string is computed as follows: from the
    % list of keys presented in parameter #1 a \_seq variable is computed as a 
    % representation of the tree, which then serves as the basis for computing the 
    % content for the tabular and the tikzpicture environments. Tabular is bedded dow
    % and works, tikzpicture content is computed by a post-order traversal of the nodes
    % of the tree, resulting in following steps in building the content string: 
    \tl_gclear:N \g_rn_tikzContent_FR_tl
    % visiting node key = 5:    
    \tl_set:Nn \l_rn_Aux_tl {5}
    \tl_set:Nn \l_rn_auxOne_tl {child{node{\l_rn_Aux_tl}}}
    \tl_gput_right:Nx \g_rn_tikzContent_FR_tl {\l_rn_auxOne_tl}
    % visiting node key = 15:
    \tl_set:Nn \l_rn_Aux_tl {15}
    \tl_set:Nn \l_rn_auxOne_tl {child{node{\l_rn_Aux_tl}}}
    \tl_gput_right:Nn \g_rn_tikzContent_FR_tl {\l_rn_auxOne_tl}
    % visiting root of subtree, key = 10:
    \tl_set:Nn \l_rn_Aux_tl {10}
    \tl_set:Nn \l_rn_auxOne_tl {\node{\l_rn_Aux_tl}}
    \tl_gput_left:Nn \g_rn_tikzContent_FR_tl {\l_rn_auxOne_tl}
%    \tl_gput_right:Nn \g_rn_tikzContent_FR_tl {;}
\group_end:
  }  %  \rn_generateTikzContent_FR:n

\NewDocumentCommand\myShowTree{O{10,5,15}}
%  NOTE: Parameter `#1` lists the key values for which a binary search tree is 
% to be built. In this MWE `#1` is merely a dummy parameter and is as such passed
% to the macros that compute `content` and `style`. 
  {
    \rn_generateTikzStyle_FR:n {#1}
    \rn_generateTikzContent_FR:n {#1}
    \__rn_start_tikzpicture:V \g_rn_tikzStyle_FR_tl
      % my string is ineffective, but at least it does not flag compile ERROR 
      \g_rn_tikzContent_FR_tl ;  
    \end{tikzpicture}
  }  %  \myShowTree
\ExplSyntaxOff
%-----------------------
\begin{document}
\section{Native tikzpicture}
The subject of the following discussion:

\begin{tikzpicture}
[level distance=10mm,
every node/.style={circle,draw,inner sep=1pt},
level 1/.style={sibling distance=30mm}]
\node{10}child{node{5}}child{node{15}};
\end{tikzpicture}

\section{Style and Content both supplied as parameters}
\myShowTree[10,5,15]

\end{document}

答案1

它又在扩张了。

第一部分有效,因为最终您会使用 展开所有内容x。但在接下来的两个版本中,您不会展开(如果您进行更改,则可能会出现 错误\node)。在这里,我尝试解释并告诉您我认为您应该怎么做。

\tl_set:Nn \l_rn_Aux_tl { 5 }
\tl_set:Nn \l_rn_auxOne_tl { child{node{\l_rn_Aux_tl}} }
\tl_gput_right:Nx \g_rn_tikzContent_FR_tl { \l_rn_auxOne_tl }

第一行保存5在辅助标记列表中;第二行保存child{node{\l_rn_aux_tl}}在辅助标记列表中;第三行展开所有内容child{node{5}}并将其添加到 tikzcontent_fr 标记列表中。你没有一步一步地做正确的事情,但最终你得到了正确的东西。

\tl_set:Nn \l_rn_Aux_tl { 15 }
\tl_set:Nn \l_rn_auxOne_tl { child{node{\l_rn_Aux_tl}} }
\tl_gput_right:Nn \g_rn_tikzContent_FR_tl { \l_rn_auxOne_tl }

但是这里你忘了x,所以...第一行你保存15在辅助标记列表中;第二行你保存child{node{\l_rn_aux_tl}}在辅助标记列表中;第三行你不要展开任何结果,\l_rn_auxone_tl并将其添加到 tikzcontent_fr 令牌列表中。现在,该令牌列表看起来像child{node{5}}\l_rn_auxone_tl

在第三步中,你最终得到了\l_rn_auxone_tl child{node{5}}\l_rn_auxone_tl。它最终会扩展为某个值,但这不是你想要的。你希望它是\node{10}child{node{5}}child{node{15}}


你应该做的是正确地完成每个步骤,这样它才会有效。

\tl_set:Nn \l_rn_Aux_tl { 5 }

没问题,你将其存储5在标记列表中。然后在下一步中,你想将的当前值扩展\l_rn_aux_tl5,而不是将保留\l_rn_aux_tl在那里,因此你使用x

\tl_set:Nx \l_rn_auxOne_tl { child{node{\l_rn_Aux_tl}} }

因此,您会被child{node{5}}保存在那个令牌列表中;然后你想要值添加到全局令牌列表中,您不想在x这里扩展,您只想要值(基本上,扩展一次即可获取内容,仅此而已)。

\tl_gput_right:NV \g_rn_tikzContent_FR_tl \l_rn_auxOne_tl

这样做,对于每个步骤,都会得到正确的结果(即,,,:Nn然后:Nx:NV

在最后一步中,您将添加\node到令牌列表中,但它不受保护,因此会出现错误。您可以使用\exp_not:N停止扩展来纠正此问题。

\tl_set:Nn \l_rn_Aux_tl { 10 }
\tl_set:Nx \l_rn_auxOne_tl { \exp_not:N \node {\l_rn_Aux_tl} }
\tl_gput_left:NV \g_rn_tikzContent_FR_tl \l_rn_auxOne_tl

相关内容