检查是否使用了 tikz 键的默认值

检查是否使用了 tikz 键的默认值

背景故事:我目前正在实施https://codereview.stackexchange.com/a/171841/145641

如何更改线路

\ifdefined\duck@hair\let\duck@eyebrow=\duck@hair\fi

因此它只适用于没有明确给出颜色的情况\duck@eyebrow


应用

我想画头发和眉毛,我希望有以下行为:如果
没有明确指定颜色,它应该检查是否\duck@hair定义并采用该颜色,或者如果\duck@hair没有定义,它应该恢复为默认颜色。

\documentclass{article}

\RequirePackage{xcolor}
\RequirePackage{tikz}

\makeatletter

\newcommand*{\duck}[1][]{\tikzset{/duck/.cd,#1}\duck@draw}

\newif\ifduck@shorthair
\newif\ifduck@eyebrow

\tikzset{
    /duck/.cd,
    shorthair/.code         = \duck@shorthairtrue           \def\duck@hair{#1},
    eyebrow/.code               = \duck@eyebrowtrue           \def\duck@eyebrow{#1},
    % setting defaults %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    shorthair/.default      = green,
    eyebrow/.default            = blue,
}

\def\duck@draw{
    % short hair %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    \ifduck@shorthair
        \path[fill=\duck@hair] 
        (1.3947,1.4175).. controls (1.4546,1.4518) and (1.4699,1.6566) .. 
        (1.4343,1.7992).. controls (1.2528,2.5033) and (0.2339,2.2710) .. 
        (0.4151,1.5907).. controls (0.4345,1.8709) and (0.7421,2.0999) .. 
        (0.9494,1.9054).. controls (1.2241,1.6476) and (1.3316,1.3814) .. 
        (1.3947,1.4175) -- cycle;
    \fi
    %
    % eye brow %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    \ifdefined\duck@hair\let\duck@eyebrow=\duck@hair\fi
    \ifduck@eyebrow
        \draw[line width=2,color=\duck@eyebrow,line cap=round] 
            (0.96,1.70) -- (0.82,1.77);
        \draw[line width=2,color=\duck@eyebrow,line cap=round] 
            (0.50,1.81) -- (0.60,1.82);
    \fi 
}
\makeatother

\begin{document}

\begin{tikzpicture}
\duck[eyebrow]
\end{tikzpicture}
\qquad
\begin{tikzpicture}
\duck[shorthair=red, eyebrow]
\end{tikzpicture}
\qquad
\begin{tikzpicture}
\duck[shorthair=pink, eyebrow=red]
\end{tikzpicture}
\qquad
\begin{tikzpicture}
\duck[shorthair, eyebrow=red]
\end{tikzpicture}


\end{document}

在此处输入图片描述

期望输出: 最后两张图片中的眉毛是红色的

答案1

一个非常糟糕的方法

\tikzset{
    /duck/.cd,
    shorthair/.store in=\duck@hair,
    eyebrow/.store in=\duck@eyebrow
}

\def\duck@draw{
    \ifdefined\duck@hair
        \path[fill=green,fill=\duck@hair]
        (1.3947,1.4175).. controls (1.4546,1.4518) and (1.4699,1.6566) .. 
        (1.4343,1.7992).. controls (1.2528,2.5033) and (0.2339,2.2710) .. 
        (0.4151,1.5907).. controls (0.4345,1.8709) and (0.7421,2.0999) .. 
        (0.9494,1.9054).. controls (1.2241,1.6476) and (1.3316,1.3814) .. 
        (1.3947,1.4175) -- cycle;
    \else
        \def\duck@hair{}
    \fi
    \ifdefined\duck@eyebrow
        \draw[line width=2,line cap=round,draw=blue,draw=\duck@hair,draw=\duck@eyebrow]
            (0.96,1.70) -- (0.82,1.77)
            (0.50,1.81) -- (0.60,1.82);
    \fi 
}

逻辑确实很糟糕。重点是:draw=fill=将测试参数是否为空。所以你不必自己测试。

答案2

假设知道默认值,另一个 if case 可以解决问题:

\pgfkeys{/duck/eyebrow/.@def/.get=\duck@test}
\ifx\duck@eyebrow\duck@test
    \ifdefined\duck@hair\let\duck@eyebrow=\duck@hair\fi
\fi%

\documentclass{article}

\RequirePackage{xcolor}
\RequirePackage{tikz}

\makeatletter
\newcommand*{\duck}[1][]{\tikzset{/duck/.cd,#1}\duck@draw}

\newif\ifduck@shorthair
\newif\ifduck@eyebrow

\tikzset{
    /duck/.cd,
    shorthair/.code         = \duck@shorthairtrue           \def\duck@hair{#1},
    eyebrow/.code               = \duck@eyebrowtrue           \def\duck@eyebrow{#1},
    % setting defaults %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    shorthair/.default      = green,
    eyebrow/.default            = blue,
}
\def\duck@draw{
% short hair %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ifduck@shorthair
    \path[fill=\duck@hair] 
    (1.3947,1.4175) .. controls (1.4546,1.4518) and (1.4699,1.6566) .. 
    (1.4343,1.7992) .. controls (1.2528,2.5033) and (0.2339,2.2710) .. 
    (0.4151,1.5907) .. controls (0.4345,1.8709) and (0.7421,2.0999) .. 
    (0.9494,1.9054) .. controls (1.2241,1.6476) and (1.3316,1.3814) .. 
    (1.3947,1.4175) -- cycle;
\fi
%
% eye brow %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfkeys{/duck/eyebrow/.@def/.get=\duck@test}
\ifx\duck@eyebrow\duck@test
    \ifdefined\duck@hair\let\duck@eyebrow=\duck@hair\fi
\fi%
\ifduck@eyebrow
    \draw[line width=2,color=\duck@eyebrow,line cap=round] 
        (0.96,1.70) -- (0.82,1.77);
    \draw[line width=2,color=\duck@eyebrow,line cap=round] 
        (0.50,1.81) -- (0.60,1.82);
\fi 
}% from `\def\duck@draw{` at the very beginning 

\makeatother

\begin{document}

\begin{tikzpicture}
\duck[eyebrow]
\end{tikzpicture}
\qquad
\begin{tikzpicture}
\duck[shorthair=red, eyebrow]
\end{tikzpicture}
\qquad
\begin{tikzpicture}
\duck[shorthair=pink, eyebrow=red]
\end{tikzpicture}
\qquad
\begin{tikzpicture}
\duck[shorthair, eyebrow=red]
\end{tikzpicture}


\end{document}

在此处输入图片描述

相关内容