Stil für leeren/nicht leeren Knoteninhalt ändern

Stil für leeren/nicht leeren Knoteninhalt ändern

Idealerweise wünsche ich mir einen Befehl \vertex, der sich so verhält wie

\vertex (a);                --->  \node[empty vertex] (a) {};
\vertex[foo] (a);           --->  \node[empty vertex, foo] (a) {};
\vertex[foo] (a) at (0, 0); --->  \node[empty vertex, foo] (a) at (0, 0) {};

\vertex (a) {bar};          --->  \node[filled vertex] (a) {bar};

und das Gleiche gilt für verschiedene andere Kombinationen. Ich habe jedoch keine Ahnung, wie man eine solche Funktion überhaupt schreibt.

Hat jemand eine Idee, ob und wie dies erreicht werden könnte?

Ist es als Fallback möglich, dass ein Knotenstil vom Knoteninhalt abhängt? Auf diese Weise müsste man zwar immer das finale schreiben {...}, das Endergebnis würde jedoch variieren, je nachdem, ob diese Klammern ausgefüllt sind oder nicht.

Mein erster Gedanke für diesen Fallback war, zu versuchen, einen Stil wie diesen zu implementieren.

\tikzset{
    vertex/.append code={
        \ifx\tikz@node@content\relax
            \pgfkeysalso{/tikz/shape=coordinate}
        \else
            \pgfkeysalso{/tikz/shape=circle}
            \pgfkeysalso{/tikz/draw}
        \fi
    },
}

Dies scheint jedoch nicht zu funktionieren, da der Stil analysiert wird, bevor \tikz@node@contenter aufgefüllt wird [1] , sodass der trueZweig immer ausgeführt wird.

Letzten Endes,


[1]: Dies basiert auf einem Blick auf tikz.code.tex, insbesondere auf Zeile 3668, wo \tikz@node@contentfestgelegt ist.

Antwort1

Ich denke, wenn wir hacken, ist es am einfachsten, den Parser an der Stelle zu hacken, an der er darauf besteht, dass ein Knoten Inhalt hat. Möglicherweise so ...

\documentclass[tikz,border=5]{standalone}
\makeatletter
\newif\iftikznodeallowempty
\def\tikz@@scan@fig{%
  \pgfutil@ifnextchar a{\tikz@fig@scan@at}
  {\pgfutil@ifnextchar({\tikz@fig@scan@name}
    {\pgfutil@ifnextchar[{\tikz@fig@scan@options}%
      {\pgfutil@ifnextchar\bgroup{\tikz@fig@main}%
      {\iftikznodeallowempty%
          \tikzset{every empty node/.try}%
        \else%
          \tikzerror{A node must have a (possibly empty) label text}%
       \fi%
       \tikz@fig@main{}}}}}}%}}

\tikzset{every empty node/.style={shape=coordinate}}

\def\vertex{\path \pgfextra{\tikznodeallowemptytrue} 
  node [every vertex/.try]}

\begin{document}
\begin{tikzpicture}
\vertex [label=315:v1] (v1);
\vertex [label=0:v2]   (v2) at (1,1);
\vertex [label=90:v3]  (v3) at (-1,1);
\vertex [anchor=north] (v4) at (-1,-1) {text};
\draw   [red] (v1) -- (v2) -- (v3) -- (v4.north) -- cycle;
\end{tikzpicture}
\end{document}

Bildbeschreibung hier eingeben

Es sollte jedoch darauf hingewiesen werden, dass einer der Gründe für die Generierung eines Fehlers (es sei denn, die node contentsSchlüssel wurden verwendet) darin liegt, dass der Parser die Klammern verwendet, {}um zu bestimmen, wann die Knotenspezifikation beendet ist. Daher sollte der obige Hack mit Vorsicht verwendet werden.

Antwort2

Es ist nie zu spät. Sie können überprüfen, ob ein Knoten leer ist, indem Sie die Breite von messen \pgfnodeparttextbox. Und dann \tikz@shapeentsprechend neu definieren.

\documentclass[border=30,tikz]{standalone}
\usepgflibrary{shapes.misc}
\begin{document}

\makeatletter
\def\tikz@fig@boxdone{%
%%% old definition ↓↓↓
            \tikz@atend@node%
          \ifx\tikz@text@width\pgfutil@empty%
          \else%
              \pgfutil@endminipage%
            \endgroup%
          \fi%
        \endpgfinterruptpicture%
      \egroup%
%%% new code ↓↓↓
    \ifdim0pt=\wd\pgfnodeparttextbox%
      \def\tikz@shape{cross out}\tikzset{draw=red}%
    \else%
      \def\tikz@shape{circle}\pgfkeysalso{/tikz/draw}%
    \fi%
%%% old definition ↓↓↓
    \pgfutil@ifnextchar c{\tikz@fig@mustbenamed\tikz@fig@continue}%
    {\pgfutil@ifnextchar[{\tikz@fig@mustbenamed\tikz@fig@continue}%
      {\pgfutil@ifnextchar t{\tikz@fig@mustbenamed\tikz@fig@continue}
        {\pgfutil@ifnextchar e{\tikz@fig@mustbenamed\tikz@fig@continue}
          {\ifx\tikz@after@path\pgfutil@empty\expandafter\tikz@fig@continue\else\expandafter\tikz@fig@mustbenamed\expandafter\tikz@fig@continue\fi}}}}}%}

\tikz\path(0,3)node{}
          (0,2)node{bravo}
          (0,1)node{\hbox to0pt{charlie}}
          (0,0)node{\hbox to-1pt{delta}};

\end{document}

verwandte Informationen