Das ürsprüngliche Problem ist, dass
start: (1, 2), mid: (3, 4), end: (5, 6)
vom `.list`-Handler (bzw. der internen `\foreach`-Schleife) in folgende Elemente aufgeteilt wird:
- `start: (1`,
- `2)`,
- `mid: (3`,
- `4)`,
- `end: (5` und
- `6)`.
Das geht beim ersten Element noch gut, weil es dem Argumentenformat `#1: #2` noch entspricht; `2)` passt aber nicht mehr in `#1: #2` rein. Dass `\StrBetween` auch keine gescheiten Ergebnisse mehr auswirft, brauche ich glaube ich nicht mehr zu erwähnen.
Also, beschützen wir das doofe Komma eben und schmeißen nochmal ein Paar `{ }` außenrum:
\pgfkeys{/bonds/bond points={start: {(1, 2)}, mid: {(3, 4)}, end: {(5, 6)}}}
Fast! Die zwei Koordinaten werden nur als eine Einheit betracht (und die `y`-Macros gar nicht definiert). Der Haken:
util/@@coord extractor/.list={\coord}
Wieviele Elemente in der Liste siehst du? Ich sehe nur einen: `\coord`. Und `\foreach` sieht auch nur einen: Es wird nur über ein Element iteriert: `\coord`. `\startx` wird dann definiert als
\def\startx{\coord}
was zu zwei Problemen führt:
1. `\starty` ist selbstverständlich gar nicht definiert, aber theoretisch kannst du dann auch gleich
\draw (\startx) circle [radius=1cm] node {\startx};
schreiben.
2. Wenn `mid:` und `end:` bearbeitet wurde, expandiert `\coord` zu `5, 6`, und da `\startx` zu `\coords` expandiert, expandiert es auch zu `5, 6`. Es werden also alle Kreise an der gleichen Stelle gezeichnet.
Bezugnehmend auf:
> Wo ist das Problem bei der Benutzung von `\StrBetween{#2}{(}{)}[\coord]` um mir eine Liste für den `.list` handler zu erzeugen - ein Test des so erzeugten Makros `\coord` in einem `\foreach` Loop hat nämlich funktioniert und ich dachte beim `.list` handler werkelt eben ein solcher `\foreach` Loop im Hintergrund.
Ja, hinter `.list` werkelt eine komplexe `\foreach`-Loop, allerdings kennt das offizielle `\foreach` eben die zwei Alternativen:
\foreach \var/\iab/\len in {Ele/men/t 1, Ele/men/t 2, …, Ele/men/t n}
und
\foreach \var/\iab/\len in \macroDasNachEinerExpansionEineListeDerElementeLiefert
Der `.list`-Handler arbeitet nur mit der ersten Option.
Lösung: `\coord` einmal (und da wir ja nur plain Zahlen haben könnten wir es theoretisch auch mehrmals) expandieren:
util/@@coord extractor/.list/.expand once=\coord
----
Aber: Warum denn so kompliziert?
Benutze doch direkt Keys `start`, `mid` und `end`, um die Koordinaten zu speichern. (Wenn dir der Doppelpunkt als Trenner so wichtig ist, könntest du `xstring` vorher auch drüber laufen lassen und alle `:` durch `=` austauschen, bevor es PGFkeys bearbeitet.
Ich vermeide auch, die etwas altbackenen `/.store in`-Keys und verwende den besseren `.initial`-Handler. Siehe dazu bitte auch die Fragen
- [When to use a regular `.initial` key or a `.store in` key?](http://tex.stackexchange.com/q/125197/16595) und
- [What do the pgfkeys key handlers `.get` and `.store in` do?](http://tex.stackexchange.com/q/129577/16595)
auf TeX.sx.
Ein paar Styles dazu und man kann die Grafik schon beachtlich beeinflussen. (Bitte beachte, dass Kommas in den Koordinaten selbstverständlich immer noch beschützt werden müssen, wie ich das bei der Initialisierung auch gemacht habe.)
## Code (original)
\documentclass{standalone}
\usepackage[svgnames]{xcolor}
\usepackage{tikz}
\usepackage{xstring}
\newcounter{coordcounter}
\setcounter{coordcounter}{23}
\pgfkeys{
util/coord extractor/.style={
util/@coord extractor/.list={#1}
},
util/@coord extractor/.code args={#1: #2}{%
\def\tempcoordkey{#1}%
\StrBetween{#2}{(}{)}[\coord]%
\pgfkeys{
util/@@coord extractor/.list/.expand once=\coord,
bonds/counter/set={coordcounter}{23}
}%
},
util/@@coord extractor/.code={%
\pgfkeys{
/bonds/counter/step={coordcounter},
\savedpath/\tempcoordkey/\alph{coordcounter}={#1}
}%
},
bonds/counter/set/.code 2 args={\setcounter{#1}{#2}},
bonds/counter/step/.code={\stepcounter{#1}},
bonds/bond points/start/x/.store in={\startx},
bonds/bond points/start/y/.store in={\starty},
bonds/bond points/mid/x/.store in={\midx},
bonds/bond points/mid/y/.store in={\midy},
bonds/bond points/end/x/.store in={\endx},
bonds/bond points/end/y/.store in={\endy},
bonds/bond points/.code={%
\def\savedpath{/bonds/bond points}%
\pgfkeys{
util/coord extractor={#1}
}%
}
}
\begin{document}
\begin{tikzpicture}
\pgfkeys{/bonds/bond points={start: {(1, 2)}, mid: {(3, 4)}, end: {(5, 6)}}}
\draw (\startx, \starty) circle [radius=1cm] node {\startx, \starty};
\draw (\midx, \midy) circle [radius=2cm] node {\midx, \midy};
\draw (\endx, \endy) circle [radius=.5cm] node {\endx, \endy};
\end{tikzpicture}
\end{document}
## Output (original)
![alt text][1]
## Code
\documentclass[tikz]{standalone}
\newcommand*\bondset{\pgfqkeys{/bonds}}
\bondset{
bond points/start/.initial={(0,0)},
bond points/mid/.initial={(1,1)},
bond points/end/.initial={(2,2)}}
\tikzset{bonds/.code={\bondset{#1}}}
\newcommand*{\drawBond}[1][]{%
\begingroup
\bondset{#1}%
\draw[/bonds/every bond/.try, /bonds/start/.try] \pgfkeysvalueof{/bonds/bond points/start} circle [] node {start};
\draw[/bonds/every bond/.try, /bonds/mid/.try] \pgfkeysvalueof{/bonds/bond points/mid} circle [] node {mid};
\draw[/bonds/every bond/.try, /bonds/end/.try] \pgfkeysvalueof{/bonds/bond points/end} circle [] node {end};
\endgroup}
\begin{document}
\begin{tikzpicture}[radius=+1cm]
\drawBond[mid/.style={green, radius=.5cm}]
\end{tikzpicture}
\begin{tikzpicture}[bonds={every bond/.append style={radius=+1cm}}]
\drawBond[
bond points/mid=(45:1),
bond points/end=(45+90:1),
end/.style={red, radius=+.5cm}]
\end{tikzpicture}
\end{document}
## Output
![alt text][2]![alt text][3]
[1]: http://texwelt.de/wissen/upfiles/de1741.png
[2]: http://texwelt.de/wissen/upfiles/de1741_-0.png
[3]: http://texwelt.de/wissen/upfiles/de1741_-1.png