[Tex/LaTex] Demonic correspondence: Best practices when defining devils in TiKZ

best practicessymbolstikz-pgf

angels and devils

tikzsymbols defines a series of symbols which can be used in text (or nested in larger pictures) and which can be customised in various ways e.g. scaling size, choice of colours etc.

For example:

\documentclass[10pt,tikz]{standalone}

\usepackage{tikzsymbols}
\usetikzlibrary{positioning}

\begin{document}

  \begin{tikzpicture}
    \node (yellow) {\color{yellow}\Innocey};
    \node [right=5pt of yellow] {\color{purple}\Innocey[13][][pink]};
  \end{tikzpicture}

\end{document}

two innocents

What is the best way to set up symbols of this kind? In particular, what is the best way to code symbols not covered by such existing packages? I intend this question to be a general one but I am especially interested in symbols which are designed to complement those provided by such existing solutions.

For example, suppose that I wanted to create a 'devil' symbol to complement the 'angel' symbol above. What is the best way to go about this?

Initially, I did this by modifying the code tikzsymbols uses to produce the haloed smiley. However, this depends on internal macros which disappeared or were renamed when the package was updated. So I had to recode my symbol to reflect the changes.

On the other hand, if I do not use these macros, I'm not certain how to ensure that my extension complements the symbols provided by the package. For example, I want the two smileys to be based on circles of the same size if I specify the same scaling factor in each case. And I want the basic line widths to match and so on. If I code my symbol from scratch, I worry that, although the code will be less susceptible to breaking when tikzsymbols is updated, it will be less likely that the style of my symbol will continue to match that of the package's symbols.

For completeness, here is my updated code:

\documentclass[10pt,tikz]{standalone}
\usetikzlibrary{arrows.meta,bending,positioning,fit,backgrounds}
\usepackage{tikzsymbols}
\makeatletter
  \tkzsymbls@Declare@Robust@Commandx{Devilish}[3][1=1,2={opacity=0},3=red,usedefault]{% based on \Innocey from tikzsymbols - updated 2014-11-15 due to changes in tikzsymbols (untested here but tested in scratch)
        \tikzsymbols@ifsaveboxundefined{Devilish#1#2#3}{%
          \set@tkzsymblsscl{#1}%
          \iftikzymbols@draftabsolute%
                \tksymbls@bx@Prmtrstore{#1}%
                \tikzsymbols@draftbox{1.73ex*\real{\tkzsymbls@Prmtr}}{1.909ex*\real{\tkzsymbls@Prmtr}}%
          \else%
                \ifdim\tkzsymbls@scl<0pt\set@tkzsymblsscl{-#1}\fi%
          \begin{tikzpicture}[x=2.4ex, y=2.4ex, line width=0.12ex*\tkzsymbls@scl,scale=#1]
                \fill [line width=0.05ex*\tkzsymbls@scl, #2, even odd rule] (0.25,0.47) arc (52:-52:0.17 and 0.14) (0.25,0.47) arc (50:-50:0.20 and 0.19) (-0.25,0.47) arc (128:232:0.17 and 0.14)  (-0.25,0.47) arc (130:230:0.20 and 0.19);
                \draw [line width=0.05ex*\tkzsymbls@scl, #3] (0.25,0.47) arc (52:-52:0.17 and 0.14) (0.25,0.47) arc (50:-50:0.20 and 0.19) (-0.25,0.47) arc (128:232:0.17 and 0.14)  (-0.25,0.47) arc (130:230:0.20 and 0.19);
                \fill [#2] (0,0) circle (0.33);
                \draw (0,0) circle (0.33);
                \fill (-0.1,0.075) circle (0.075);
                \fill (0.1,0.075) circle (0.075);
                \draw (-0.2,-0.1) .. controls (-0.1,-0.2) and (0.1,-0.2) .. (0.2,-0.1);
                \draw [line cap=round] (0.075,0.12) -- (0.175,0.2) (-0.075,0.12) -- (-0.175,0.2);
                \draw [line width=0.075ex*\tkzsymbls@scl, #3, -{Stealth[bend,length=#1*.4ex]}] (0.1,-.325) to [out=-90, in=-125] (.3,-.3) to [out=55, in=125] (.45,-.15) to [out=-55, in=-60] (.4,-.25) to [out=120, in=-160] (.5,-.2) to [out=20, in=-155] (.4,.175) to [out=25, in=-80] (.45,.3);
          \end{tikzpicture}%
          \fi%
        }%
        \tikzsymbols@use@box{Devilish#1#2#3}%
        \tikzsymbolsaftersymbolinput%
  }
  \tkzsymbls@Declare@Robust@Command{wDevilish}[1][3]{\Devilish[#1][opacity=0][black]}
\makeatother
\begin{document}

  \begin{tikzpicture}
    \node (green) {\color{green}\Devilish[5][][green]};
    \node (red) [right=5pt of green] {\color{red}\Devilish[13][][red]};
    \begin{scope}[on background layer]
      \node [draw, fill=black, fit=(green) (red)] {};
    \end{scope}
  \end{tikzpicture}

\end{document}

two devils

Or is there really no best way in a case like this i.e. any method will be fragile just because I'm building on something provided by a package? That is, is the only real solution in this kind of case to code all of the symbols I want from scratch? (Or to fork tikzsymbols's code and to then build on my copy of that code, which of course would not be vulnerable to future changes made to the original package.)

Best Answer

Tikzpeople package provides evil and good option to convert into a Saint or Devil corresponding symbol. Some examples:

enter image description here

\documentclass{standalone} 
\usepackage{tikzpeople}

\begin{document}
\begin{tikzpicture}[every node/.style={minimum width=1.5cm}]
\foreach \i [count=\ni] in {priest, nun, judge}
{
    \node[\i] (\i) at (0,-2.5*\ni) {};
    \node[\i, evil] (\i-evil) at (2,-2.5*\ni) {};
    \node[\i, good] (\i-saint) at (4,-2.5*\ni) {};
}
\end{tikzpicture}
\end{document}