3

In How to properly use new options into \pgfdeclareshape of makeshape package I had a problem with including \ifx in \pgfdeclareshape which was solved by @marmot.

At this moment, I'm trying to include options using \pgfkeys. However, now I can't detected options into \anchor, while working into \setpath.

Here the code:

\documentclass[a4paper,10pt]{article}
\usepackage{filecontents}
\begin{filecontents*}{valvula.tex}
\makeatletter

% Dimensiones medidas en Autocad para las válvulas con anchura = 3mm en un
% círculo de 2mm de radio.

\def\gap{0mm}

\newdimen\radio@llave \radio@llave=2mm
\newdimen\x@llave \x@llave=1.5mm
\newdimen\y@llave \y@llave=1.32mm
\def\f@maniv{0.9} % Proporción de la longitud de la manivela

\pgfkeys{ % Colores de las mariposas de las válvulas:
  /tikz/.cd,
  color izquierda/.initial=\pgfutil@empty,
  color derecha/.initial=\pgfutil@empty,
}

\pgfkeys{
    /tikz/posicion manivela/.is choice,
    /tikz/posicion manivela/izquierda/.code={\def\pos@manivela{-1}},
    /tikz/posicion manivela/derecha/.code={\def\pos@manivela{1}}
}

%% Anchor path:

\def\generalanchor{} % No es necesario, el nodo no llevará texto.

%% Background path:

\def\valvulaborder{ % Obtiene la caja de texto correcta:

    % La parte anterior no es necesaria, no llevará texto el nodo
    % Triángulo izquierdo:
    %
    \pgfpathmoveto{\pgfpointorigin}
    \pgfpathlineto{\pgfpoint{-\x@llave}{ \y@llave}}
    \pgfpathlineto{\pgfpoint{-\x@llave}{-\y@llave}}
    \pgfpathclose
    %\typeout{\tikz@fillcolor}
    %\typein{}
    \edef\pgfutil@tmpa{\pgfkeysvalueof{/tikz/color izquierda}}
    \ifx\pgfutil@tmpa\empty
      \ifx\tikz@fillcolor\empty
        \pgfusepath{stroke}
      \else
        \pgfusepath{fill,stroke}
      \fi
    \else
      \pgfsetfillcolor{\pgfkeysvalueof{/tikz/color izquierda}}
      \pgfusepath{fill,stroke}
    \fi 
    %
    % Triángulo derecho:
    %
    %\typeout{derecha\pgfkeysvalueof{/tikz/color derecha}}
    \pgfpathmoveto{\pgfpointorigin}
    \pgfpathlineto{\pgfpoint{ \x@llave}{ \y@llave}}
    \pgfpathlineto{\pgfpoint{ \x@llave}{-\y@llave}}
    \pgfpathclose
    \edef\pgfutil@tmpa{\pgfkeysvalueof{/tikz/color derecha}}
    \ifx\pgfutil@tmpa\pgfutil@empty
      \ifx\tikz@fillcolor\empty
        \pgfusepath{stroke}
      \else
        \pgfsetfillcolor{\tikz@fillcolor}
        \pgfusepath{fill,stroke}
    \fi
    \else
      \pgfsetfillcolor{\pgfkeysvalueof{/tikz/color derecha}}
      \pgfusepath{fill,stroke}
    \fi

}

%% Declaración de la forma:

\pgfdeclareshape{valvula de esfera}{

  \setpaths{\generalanchor}{%
    \valvulaborder
    % La manivela de la válvula:
      \pgfpathmoveto{\pgfpoint{0em}{0em}}
      \pgfpathlineto{\pgfpoint{0em}{\radio@llave}}
      \ifnum\pos@manivela=-1 % a izquierda
        \pgfpathmoveto{\pgfpoint{0em}{\radio@llave}}
        \pgfpathlineto{\pgfpoint{-\f@maniv\x@llave}{\radio@llave}}
    \else % a derecha
        \pgfpathmoveto{\pgfpoint{0em}{\radio@llave}}
        \pgfpathlineto{\pgfpoint{ \f@maniv\x@llave}{\radio@llave}}
    \fi
  }

  \savedanchor{\centerpoint}{
      \pgf@x = \ctbnex
      \pgf@y = \ctbney
      \advance\pgf@x by \gap
      \advance\pgf@y by \gap
      \mincorrect{\pgf@x}{\pgfshapeminwidth}
      \mincorrect{\pgf@y}{\pgfshapeminheight}
      \advance\pgf@x\pgfshapeouterxsep
      \advance\pgf@y\pgfshapeouterysep
  }

  \inheritsavedanchors[from=valvula]
  \inheritanchorborder[from=valvula]

  \inheritanchor[from=valvula]{c}
  \inheritanchor[from=valvula]{ur}
  \inheritanchor[from=valvula]{r}
  \inheritanchor[from=valvula]{dr}
  \inheritanchor[from=valvula]{dl}
  \inheritanchor[from=valvula]{l}
  \inheritanchor[from=valvula]{ul}

  % De la manivela de la válvula
  \anchor{tc}{\centerpoint \pgf@x=0\pgf@x \pgf@y=\radio@llave}
  \anchor{tm}{\ifnum\pos@manivela=-1 % a izquierda
    \centerpoint \pgf@x=-\f@maniv\x@llave \pgf@y=\radio@llave
  \else
    \centerpoint \pgf@x= \f@maniv\x@llave \pgf@y=\radio@llave
  \fi}

}

\makeatother

\end{filecontents*}

\usepackage{tikz}

\usepackage{makeshape}

\tikzset{
  st texto/.style={
    font=\sffamily\footnotesize,
    circle,black,fill=white,inner sep=0.1em
  },
  st valvula/.style={
    draw=blue,minimum width=6mm,minimum height=3mm,line width=0.2mm
  },
  st linea nodo/.style={line width=0.1mm,latex-,orange}
}

\input{valvula.tex}

\begin{document}

\begin{tikzpicture}[
  x=1mm,y=1mm,remember picture, overlay,shift={(current page.center)}
]

\begin{scope}[shift={(0,0)}]

  \node[%
    valvula de esfera,st valvula,posicion manivela=izquierda,
    color izquierda=yellow!50,color derecha=cyan!25
  ] (v3) at (0,0) {};

  \draw[st linea nodo] (v3.tc) -- ++(90:10) node[st texto] {tc};
  \draw[st linea nodo] (v3.tm) -- ++(110:10) node[st texto] {tm};

\end{scope}


\begin{scope}[shift={(50,0)},posicion manivela=derecha]

  \node[%
    valvula de esfera,st valvula,
    color izquierda=yellow!50,color derecha=cyan!25
  ] (v4) at (0,0) {};

  \draw[st linea nodo] (v4.tc) -- ++(90:10) node[st texto] {tc};
  \draw[st linea nodo] (v4.tm) -- ++(70:10) node[st texto] (ntm) {tm};

  %
  \node[above of= ntm,red,align=center] (comentm) {Here tm should\\ be at right};
  \path (comentm) edge[red,out=0,in=90,-latex] (v4.tr);

\end{scope}


\end{tikzpicture}

\end{document}

I get the following error:

! Undefined control sequence.
\pgf@anchor@valvula de esfera@tm ...\pos@manivela

I am extremely confused. Please, can someone help me? I'm going to give up all of these.

1
  • Thank's for edition corrections. I don't know how exactly this web works.
    – aguivald
    Commented Mar 3, 2019 at 13:03

2 Answers 2

1

Here is another proposal in which the keys are not made global. I left some \typeouts in in order to indicate a possible way of debugging such codes.

\documentclass[a4paper,10pt]{article}
\usepackage{filecontents}
\begin{filecontents*}{valvula.tex}
\makeatletter

% Dimensiones medidas en Autocad para las válvulas con anchura = 3mm en un
% círculo de 2mm de radio.

\def\gap{0mm}

\newdimen\radio@llave \radio@llave=2mm
\newdimen\x@llave \x@llave=1.5mm
\newdimen\y@llave \y@llave=1.32mm
\def\f@maniv{0.9} % Proporción de la longitud de la manivela

\pgfkeys{ % Colores de las mariposas de las válvulas:
  /tikz/.cd,
  color izquierda/.initial=\pgfutil@empty,
  color derecha/.initial=\pgfutil@empty,
}

\pgfkeys{
    /tikz/posicion manivela/.is choice,
    /tikz/posicion manivela/izquierda/.code={\tikzset{posicion manivela value=-1}},
    /tikz/posicion manivela/derecha/.code={\tikzset{posicion manivela value=1}},
    /tikz/posicion manivela value/.initial=-1
    %/tikz/posicion manivela/.default=izquierda
}

%% Anchor path:

\def\generalanchor{} % No es necesario, el nodo no llevará texto.

%% Background path:

\def\valvulaborder{ % Obtiene la caja de texto correcta:

    % La parte anterior no es necesaria, no llevará texto el nodo
    % Triángulo izquierdo:
    %
    \pgfpathmoveto{\pgfpointorigin}
    \pgfpathlineto{\pgfpoint{-\x@llave}{ \y@llave}}
    \pgfpathlineto{\pgfpoint{-\x@llave}{-\y@llave}}
    \pgfpathclose
    %\typeout{\tikz@fillcolor}
    %\typein{}
    \edef\pgfutil@tmpa{\pgfkeysvalueof{/tikz/color izquierda}}
    \ifx\pgfutil@tmpa\empty
      \ifx\tikz@fillcolor\empty
        \pgfusepath{stroke}
      \else
        \pgfusepath{fill,stroke}
      \fi
    \else
      \pgfsetfillcolor{\pgfkeysvalueof{/tikz/color izquierda}}
      \pgfusepath{fill,stroke}
    \fi 
    %
    % Triángulo derecho:
    %
    %\typeout{derecha\pgfkeysvalueof{/tikz/color derecha}}
    \pgfpathmoveto{\pgfpointorigin}
    \pgfpathlineto{\pgfpoint{ \x@llave}{ \y@llave}}
    \pgfpathlineto{\pgfpoint{ \x@llave}{-\y@llave}}
    \pgfpathclose
    \edef\pgfutil@tmpa{\pgfkeysvalueof{/tikz/color derecha}}
    \ifx\pgfutil@tmpa\pgfutil@empty
      \ifx\tikz@fillcolor\empty
        \pgfusepath{stroke}
      \else
        \pgfsetfillcolor{\tikz@fillcolor}
        \pgfusepath{fill,stroke}
    \fi
    \else
      \pgfsetfillcolor{\pgfkeysvalueof{/tikz/color derecha}}
      \pgfusepath{fill,stroke}
    \fi

}

%% Declaración de la forma:

\pgfdeclareshape{valvula de esfera}{

  \setpaths{\generalanchor}{%
    \valvulaborder
    % La manivela de la válvula:
      \pgfpathmoveto{\pgfpoint{0em}{0em}}
      \pgfpathlineto{\pgfpoint{0em}{\radio@llave}}
      \typeout{\pgfkeysvalueof{/tikz/posicion manivela value}}
      \ifnum\pgfkeysvalueof{/tikz/posicion manivela value}=-1 % a izquierda
        \typeout{\pgfkeysvalueof{/tikz/posicion manivela value} worked}
        \pgfpathmoveto{\pgfpoint{0em}{\radio@llave}}
        \pgfpathlineto{\pgfpoint{-\f@maniv\x@llave}{\radio@llave}}
    \else % a derecha
        \pgfpathmoveto{\pgfpoint{0em}{\radio@llave}}
        \pgfpathlineto{\pgfpoint{ \f@maniv\x@llave}{\radio@llave}}
    \fi
  }

  \savedanchor{\centerpoint}{
      \pgf@x = \ctbnex
      \pgf@y = \ctbney
      \advance\pgf@x by \gap
      \advance\pgf@y by \gap
      \mincorrect{\pgf@x}{\pgfshapeminwidth}
      \mincorrect{\pgf@y}{\pgfshapeminheight}
      \advance\pgf@x\pgfshapeouterxsep
      \advance\pgf@y\pgfshapeouterysep
  }

  \inheritsavedanchors[from=valvula]
  \inheritanchorborder[from=valvula]

  \inheritanchor[from=valvula]{c}
  \inheritanchor[from=valvula]{ur}
  \inheritanchor[from=valvula]{r}
  \inheritanchor[from=valvula]{dr}
  \inheritanchor[from=valvula]{dl}
  \inheritanchor[from=valvula]{l}
  \inheritanchor[from=valvula]{ul}

  % De la manivela de la válvula
  \anchor{tc}{\centerpoint \pgf@x=0\pgf@x \pgf@y=\radio@llave}
  \anchor{tm}{\typeout{\pgfkeysvalueof{/tikz/posicion manivela value}}
    \ifnum\pgfkeysvalueof{/tikz/posicion manivela value}=-1 % a izquierda
    \typeout{\pgfkeysvalueof{/tikz/posicion manivela value} worked}
    \centerpoint \pgf@x=-\f@maniv\x@llave \pgf@y=\radio@llave
  \else
    \centerpoint \pgf@x= \f@maniv\x@llave \pgf@y=\radio@llave
  \fi}

}

\makeatother

\end{filecontents*}

\usepackage{tikz}

\usepackage{makeshape}

\tikzset{
  st texto/.style={
    font=\sffamily\footnotesize,
    circle,black,fill=white,inner sep=0.1em
  },
  st valvula/.style={
    draw=blue,minimum width=6mm,minimum height=3mm,line width=0.2mm
  },
  st linea nodo/.style={line width=0.1mm,latex-,orange}
}

\input{valvula.tex}

\begin{document}

\begin{tikzpicture}[
  x=1mm,y=1mm,remember picture, overlay,shift={(current page.center)}
]

\begin{scope}[shift={(0,0)}]

  \node[%
    valvula de esfera,st valvula,posicion manivela=izquierda,
    color izquierda=yellow!50,color derecha=cyan!25
  ] (v3) at (0,0) {};

  \draw[st linea nodo] (v3.tc) -- ++(90:10) node[st texto] {tc};
  \draw[st linea nodo] (v3.tm) -- ++(110:10) node[st texto] {tm};

\end{scope}


\begin{scope}[shift={(50,0)},posicion manivela=derecha]

  \node[%
    valvula de esfera,st valvula,
    color izquierda=yellow!50,color derecha=cyan!25
  ] (v4) at (0,0) {};

  \draw[st linea nodo] (v4.tc) -- ++(90:10) node[st texto] {tc};
  \draw[st linea nodo] (v4.tm) -- ++(70:10) node[st texto] (ntm) {tm};

  %
  \node[above of= ntm,red,align=center] (comentm) {Here tm should\\ be at right};
  %\path (comentm) edge[red,out=0,in=90,-latex] (v4.tr);

\end{scope}


\end{tikzpicture}

\end{document}

The last line \path (comentm) edge[red,out=0,in=90,-latex] (v4.tr); seems to require an anchor tr which is not defined as far as I can see.

enter image description here

1
  • 1
    Perfect. Obviously your solution is much better. With respect to tr anchor, it's negligilble.
    – aguivald
    Commented Mar 3, 2019 at 19:27
1

I've found the solution. It was very easy. I was a bit dazed but at the end I could think clearly.

I've substituted

\pgfkeys{
    /tikz/posicion manivela/.is choice,
    /tikz/posicion manivela/izquierda/.code={\def\pos@manivela{-1}},
    /tikz/posicion manivela/derecha/.code={\def\pos@manivela{1}}
}

by

\pgfkeys{
    /tikz/posicion manivela/.is choice,
    /tikz/posicion manivela/izquierda/.code={\xdef\pos@manivela{-1}},
    /tikz/posicion manivela/derecha/.code={\xdef\pos@manivela{1}}
}

and now it's working.

1
  • I had that, too, but I am not sure that this is the best solution because the choice made in one node will affect all subsequent ones as the key is global.
    – user121799
    Commented Mar 3, 2019 at 16:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .