空/空でないノードコンテンツのスタイルを変更する

空/空でないノードコンテンツのスタイルを変更する

\vertex理想的には、次のように動作するコマンドが欲しいです

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

他のさまざまな組み合わせについても同様ですが、そのような関数をどのように記述すればよいのかさえわかりません。

これを実現できるかどうか、あるいは実現できる方法について何かアイデアをお持ちの方はいらっしゃいますか?

フォールバックとして、ノード スタイルをノード コンテンツに依存させることは可能ですか? この方法では、常に最後の を記述する必要があります{...}が、最終結果はこれらの中括弧が満たされているかどうかによって異なります。

このフォールバックについて私が最初に考えたのは、次のようなスタイルを実装してみることでした。

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

しかし、スタイルは設定\tikz@node@contentされる前に解析されるため[1]trueブランチは常に実行されるため、これは機能しないようです。

結局、


tikz.code.tex[1]: これは、特に が設定されている行3668を調べることに基づいています\tikz@node@content

答え1

ハッキングするなら、ノードに何らかのコンテンツが必要であると要求するポイントでパーサーをハッキングするのが最も簡単だと思います。おそらく次のようになります...

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

ここに画像の説明を入力してください

ただし、エラーが生成される理由の 1 つ (node contentsキーが使用されていない場合) は、パーサーが中括弧を使用して{}ノード仕様が終了したかどうかを判断するためであり、上記のハックは注意して使用する必要があることに注意してください。

答え2

遅すぎることはありません。 の幅を測定することで、ノードが空かどうかを確認できます\pgfnodeparttextbox。その後、\tikz@shapeそれに応じて再定義します。

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

関連情報