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