비어 있거나 비어 있지 않은 노드 콘텐츠의 스타일 변경

비어 있거나 비어 있지 않은 노드 콘텐츠의 스타일 변경

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

다양한 다른 조합에도 유사하게 적용됩니다. 하지만 나는 그런 함수를 어떻게 작성하는지 전혀 모릅니다.

이것이 달성될 수 있는지 또는 어떻게 달성할 수 있는지 아는 사람이 있습니까?

대체적으로 노드 스타일이 노드 내용에 의존하는 것이 가능합니까? 이렇게 하면 항상 final 을 작성해야 {...}하지만 최종 결과는 이러한 중괄호가 채워졌는지 여부에 따라 달라집니다.

이 폴백에 대한 나의 첫 번째 생각은 다음과 같은 스타일을 구현해 보는 것이었습니다.

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

그러나 [1]\tikz@node@content 이 채워지기 전에 스타일이 구문 분석되어 분기가 항상 실행되기 때문에 작동하지 않는 것 같습니다 .true

궁극적으로,


tikz.code.tex[1]: 이는 특히 가 \tikz@node@content설정된 3668행을 살펴보는 것을 기반으로 합니다 .

답변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}

여기에 이미지 설명을 입력하세요

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}

관련 정보