我想定义一个宏\mynode
(在 TikZ 内部使用),其行为取决于其参数的最后一个符号,如下所示:
\mynode{text!}
应该产生
\node[fill=red] at (0,0) {text};
而\mynode{text}
应该产生
\node at (0,0) {text};
换句话说,的定义\mynode
应该是这样的
\newcommand{\mynode}[1]{
\node[fill=red] at (0,0) {#1};
}
其中仅当以 结尾fill=red
时才提供参数(如果是这种情况,则应将花括号中的实际节点内容从感叹号中删除)。#1
!
答案1
如果!
不应该出现在 的参数中的任何其他地方\mynode
,那么这很容易:
\documentclass{article}
\usepackage{tikz}
\makeatletter
\newcommand\mynode[1]{\mynodeaux#1!\@nil}
\def\mynodeaux#1!#2\@nil{%
\if\relax\detokenize{#2}\relax
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
{\node at (0,0) {#1};}%
{\node[fill=red] at (0,0) {#1};}%
}
\makeatother
\begin{document}
\begin{tikzpicture}
\mynode{text}
\end{tikzpicture}
\bigskip
\begin{tikzpicture}
\mynode{text!}
\end{tikzpicture}
\end{document}
但是,我建议采用不同的策略,更符合标准 LaTeX 语法。
\documentclass{article}
\usepackage{tikz}
\usepackage{xparse}
\NewDocumentCommand{\mynode}{sm}{%
\IfBooleanTF{#1}
{\node[fill=red] at (0,0) {#2};}%
{\node at (0,0) {#2};}%
}
\begin{document}
\begin{tikzpicture}
\mynode{text}
\end{tikzpicture}
\bigskip
\begin{tikzpicture}
\mynode*{text}
\end{tikzpicture}
\end{document}
答案2
这个怎么样:
\documentclass{article}
\usepackage{tikz}
\makeatletter
\def\mynode{\@ifnextchar[{\mynode@}{\mynode@[]}}%]
\def\mynode@[#1]#2{\mynode@@{#1}#2\empty!\empty\relax}
\def\mynode@@#1#2!\empty#3\relax{
\def\temp{#3}
\node[#1,/utils/exec=\ifx\temp\empty\else\pgfkeysalso{fill=red}\fi] at (0,0) {#2};
}
\makeatother
\begin{document}
\begin{tikzpicture}
\mynode{hi!}
\mynode[xshift=1cm]{the!re}
\end{tikzpicture}
\end{document}
(我偷了大卫卡莱尔的代码来检查参数是否以感叹号结尾。)