如何在 TikZ 中使用資料結構?

如何在 TikZ 中使用資料結構?

我建立了一個 foreach 語句,使用expl3TikZ/pgf:

\documentclass{article}
\usepackage{tikz}
\setlength{\parindent}{0cm}
\usepackage{expl3}
\ExplSyntaxOn
\cs_new:Npn \Counter #1 \Stopper { \tl_length:n {#1} }
\ExplSyntaxOff
\pgfmathdeclarefunction{countarray}{1}{\edef\pgfmathresult{\Counter#1\Stopper}}
\begin{document}
%array with names
\def\names{{"Katie","Frank","Laura"}}

%find the last element index
\pgfmathtruncatemacro{\Last}{countarray(\names) - 1}

%print all the elements of array
\foreach \i in {0,...,\Last} {%
  \i: \pgfmathparse{\names[\i]}\pgfmathresult\\
}
\end{document}

列印這個:

在此輸入影像描述

假設我想對不同的名稱使用不同的顏色(或設定任何其他參數)。得到這樣的東西:

Katie\\
\textcolor{blue}{Frank}\\
Laura

在此輸入影像描述

在 Perl 中,我會做這樣的事情:

my @data = (
  {"text" => "Katie"},
  {"text" => "Frank", "color" => "blue"},
  {"text" => "Laura"});

foreach(@data)
{
      if(defined($_->{color}))
      {
            print "\textcolor\{$_->{color}\}\{$_->{text}\}";
      }
      else
      {
            print $_->{text};
      }
      print "\\\\";
}

可以在 中實現嗎expl3

答案1

我不知道,expl3但在 TikZ 內,或者更確切地說,在pgfkeys.由於 LaTeX3 有一個l3keys子模組,我認為基本上相同的想法在那裡起作用。您可以使用與 Perl 中大致相同的方式建立資料結構:

\pgfkeys{
 /names/.cd,
 make name/.style = {
  #1/color/.initial = black
 },
 make name/.list = {Katie, Frank, Laura},
 Frank/color = blue
}

然後你可以透過以下方式提取名稱的顏色:

\newcommand\getcolor[1]{%
 \pgfkeysgetvalue{/names/#1/color}%
}

它是完全可擴展的,可以在任何需要名稱顏色的地方使用。當然,對於此範例,不需要單一子項Frank/color(您可以只設定Frank/.initial = blue),但如果您想要更多屬性,您也可以透過為它們提供自己的命名子項來新增它們。

答案2

這最終並沒有回答這個問題:

可以在 中實現嗎expl3

因此它被標記為社區維基。

除了處理的有趣方面之外expl3,這項工作只需使用 TikZ foreach 的標準語法並結合xstring:

\documentclass{article}
\usepackage{tikz} % won't work just with pgffor
\setlength{\parindent}{0cm}
\usepackage{xstring}
\begin{document}

\foreach \name [count=\i from 0]in{Katie,Frank=>blue,Laura=>red}{
   \IfSubStr{\name}{=>}{% true
     \StrCut{\name}{=>}\xname\namecol
     \i: \textcolor{\namecol}{\xname}\par%
   }{% false
     \i: \name\par%
   }
}

\end{document}

這提供了:

在此輸入影像描述

背後的想法或多或少是這樣的:

  1. 尋找分隔符字串(=>在範例中);
  2. 如果存在,將字串切成兩部分(名稱和顏色)並使用它們;
  3. 如果不存在,請使用標準語法。

當然,也可以:

  • 更改分隔符字串;
  • 做更複雜的事情(即添加更多屬性:只需嵌套一些條件,或以更簡單的方式為每個屬性定義分隔符號字串)。

答案3

假設,我們希望程式碼支援文字的 2 個屬性:顏色和斜體。首先我們定義plist:

%plist1 definition
\prop_new:N \l_list_a_prop
\prop_put:Nnn \l_list_a_prop { text } {Katie}

%plist2 definition
\prop_new:N \l_list_b_prop
\prop_put:Nnn \l_list_b_prop { text } {Frank}
\prop_put:Nnn \l_list_b_prop { color } {red}

%plist3 definition
\prop_new:N \l_list_c_prop
\prop_put:Nnn \l_list_c_prop { text } {Laura}
\prop_put:Nnn \l_list_c_prop { color } {blue}
\prop_put:Nnn \l_list_c_prop { italic } {yes}

請注意,expl3 不支援名稱中的數字,這就是我使用_a, _b,的原因_c

然後將所有 plist 放入一個序列中:

%putting plists to sequence
\seq_new:N \l_my_seq
\seq_push:Nn \l_my_seq { \l_list_c_prop }
\seq_push:Nn \l_my_seq { \l_list_b_prop }
\seq_push:Nn \l_my_seq { \l_list_a_prop }

然後我們循環遍歷該序列,並在必要時將適當的標記添加到文本中:

\tl_new:N \__text
\seq_map_inline:Nn \l_my_seq
{
  \prop_get:NnN #1 { text } \__text

  \prop_get:NnNT #1 { color } \color_tl
  {
    \protected@edef \__text {\textcolor{\color_tl}{\__text}}
  }

  \prop_get:NnNT #1 { italic } \italic_tl
  {
    \protected@edef \__text {\textit{\__text}}
  }

  \__text\\
}

我們總共有以下程式碼:

\documentclass{article}
\usepackage{expl3}
\usepackage{color}
\setlength\parindent{0pt}
\begin{document}
\makeatletter
\ExplSyntaxOn

%plist1 definition
\prop_new:N \l_list_a_prop
\prop_put:Nnn \l_list_a_prop { text } {Katie}

%plist2 definition
\prop_new:N \l_list_b_prop
\prop_put:Nnn \l_list_b_prop { text } {Frank}
\prop_put:Nnn \l_list_b_prop { color } {red}

%plist3 definition
\prop_new:N \l_list_c_prop
\prop_put:Nnn \l_list_c_prop { text } {Laura}
\prop_put:Nnn \l_list_c_prop { color } {blue}
\prop_put:Nnn \l_list_c_prop { italic } {yes}

%putting plists to sequence
\seq_new:N \l_my_seq
\seq_push:Nn \l_my_seq { \l_list_c_prop }
\seq_push:Nn \l_my_seq { \l_list_b_prop }
\seq_push:Nn \l_my_seq { \l_list_a_prop }

\tl_new:N \__text
\seq_map_inline:Nn \l_my_seq
{
  \prop_get:NnN #1 { text } \__text

  \prop_get:NnNT #1 { color } \color_tl
  {
    \protected@edef \__text {\textcolor{\color_tl}{\__text}}
  }

  \prop_get:NnNT #1 { italic } \italic_tl
  {
    \protected@edef \__text {\textit{\__text}}
  }

  \__text\\
}
\ExplSyntaxOff
\makeatother
\end{document}

這將打印:

在此輸入影像描述

相關內容