¿Cómo utilizar estructuras de datos en TikZ?

¿Cómo utilizar estructuras de datos en TikZ?

Creé una declaración foreach, usandoexpl3yTikZ/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}

Imprime esto:

ingrese la descripción de la imagen aquí

Supongamos que quiero usar diferentes colores para diferentes nombres (o configurar cualquier otro parámetro). Obteniendo algo como esto:

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

ingrese la descripción de la imagen aquí

En Perl habría hecho algo como esto:

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

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

¿Es posible implementar esto en expl3?

Respuesta1

No lo sé expl3pero es posible dentro de TikZ, o mejor dicho, dentro de pgfkeys. Dado que hay un l3keyssubmódulo de LaTeX3, supongo que básicamente funciona la misma idea allí. Puede crear su estructura de datos de la misma manera que en Perl:

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

Luego puedes extraer el color de un nombre mediante, por ejemplo:

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

que es totalmente ampliable y se puede utilizar dondequiera que necesites el color de un nombre. Por supuesto, para este ejemplo no es necesaria una subclave única Frank/color(puede simplemente establecerla Frank/.initial = blue), pero si desea más propiedades, puede agregarlas dándoles también sus propias subclaves con nombre.

Respuesta2

En última instancia, esto no responde a la pregunta:

¿Es posible implementar esto en expl3?

por eso está marcado como wiki comunitario.

Además del interesante aspecto de tratar con expl3, este trabajo es perfectamente realizable simplemente con la sintaxis estándar de TikZ foreach en combinación conxstring:

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

Esto proporciona:

ingrese la descripción de la imagen aquí

La idea detrás es más o menos así:

  1. busque la cadena separadora ( =>en el ejemplo);
  2. si está presente, corte la cuerda en dos partes (nombre y color) y úselas;
  3. si no está presente, utilice la sintaxis estándar.

Por supuesto, es posible:

  • cambiar la cadena separadora;
  • hacer cosas mucho más complicadas (es decir, agregar más propiedades: simplemente anidar algunos condicionales o, de una manera más sencilla, definir una cadena separadora por propiedad).

Respuesta3

Supongamos que queremos que nuestro código admita 2 propiedades del texto: color y cursiva. Al principio definimos las listas:

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

Tenga en cuenta que expl3 no admite números en los nombres, por eso usé _a, _b, _c.

Luego ponga todas las listas en una secuencia:

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

Luego recorremos la secuencia y colocamos el marcado apropiado en el texto si es necesario:

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

En total tenemos el siguiente código:

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

Esto imprimirá:

ingrese la descripción de la imagen aquí

información relacionada