我想定义\DrawLine
下面的宏,以便可以从中调用它之内环境{tikzpicture}
或来自外部:
\newcommand*{\DrawLine}[1]{%
\IfInTikzPic{}{\tikzpicture[remember picture]}
\draw[ultra thick, ->, #1] (0,) -- (1,1) node [right] {output of DrawLine};
\IfInTikzPic{}{\endtikzpicture}%
}
当从 内部调用时,此方法可以正常工作{tikzpicture}
,但从外部调用时则不行(MWE 中注释了该行)。从外部调用会产生错误:
缺少插入的 \endgroup。
下面的 MWE 使用下面的第一个引用。其他两个引用也在注释掉的测试用例上失败了。
参考:
检测是否位于 tikzpicture 节点内。尽管此解决方案用于在节点内进行检测,但它似乎可以检测您是否在节点内
\tikzpicture
(如 MWE 中注释掉的代码所示)。
代码:
\documentclass{article}
\usepackage{tikz}
\makeatletter
\newcommand{\IfInTikzPic}[2]{% https://tex.stackexchange.com/a/121309/4301
\ifx\pgfpictureid\@undefined#2\else#1\fi%
}
\makeatother
\newcommand*{\DrawLine}[1]{%
\IfInTikzPic{}{\tikzpicture[remember picture]}
\draw[ultra thick, ->, #1] (0,) -- (1,1) node [right] {output of DrawLine};
\IfInTikzPic{}{\endtikzpicture}%
}
\begin{document}
%%% The commented out code here is to show that \IfInTikzPic works as desired
%%% (in a tikzpicture, outside of a \node).
%%%
%\textbf{IfInTikzPic}\par
%\IfInTikzPic{inside}{outside}
%
%\begin{tikzpicture}
% \IfInTikzPic{\draw [red, ultra thick]}{\draw [blue, ultra thick]} (0,0) -- (1,0);
%\end{tikzpicture}
%
%\medskip% --------------------------
\textbf{DrawLine}: Actual Output\par
%\DrawLine{blue}% <---- How do I get this case to work?
\begin{tikzpicture}
\DrawLine{orange}
\end{tikzpicture}
\medskip% --------------------------
\textbf{DrawLine}: Desired Output\par
\begin{tikzpicture}
\DrawLine{blue}
\end{tikzpicture}
\begin{tikzpicture}
\DrawLine{orange}
\end{tikzpicture}
\end{document}
答案1
下面的示例定义了\IfInTikzPic
检查curr
ent envir
onmenttikzpicture
并相应地定义\tikzstart
...\tikzend
对:
\documentclass{article}
\usepackage{tikz}
\makeatletter
\def\@tikzenvironment{tikzpicture}
\newcommand{\IfInTikzPic}{%
\edef\tikzstart{%
\ifx\@currenvir\@tikzenvironment\else
\noexpand\tikzpicture[remember picture]%
\fi
}%
\edef\tikzend{%
\ifx\@currenvir\@tikzenvironment\else
\noexpand\endtikzpicture%
\fi
}%
}
\newcommand*{\DrawLine}[1]{%
\IfInTikzPic
\tikzstart
\draw[ultra thick, ->, #1] (0,) -- (1,1) node [right] {output of DrawLine};
\tikzend%
}
\makeatother
\begin{document}
\textbf{DrawLine}: Actual Output\par
\DrawLine{blue}
\begin{tikzpicture}
\DrawLine{orange}
\end{tikzpicture}
\medskip% --------------------------
\textbf{DrawLine}: Desired Output\par
\begin{tikzpicture}
\DrawLine{blue}
\end{tikzpicture}
\begin{tikzpicture}
\DrawLine{orange}
\end{tikzpicture}
\end{document}
tikzpicture
如果需要,您还可以对其进行分组:
\newcommand{\IfInTikzPic}{%
\edef\tikzstart{%
\ifx\@currenvir\@tikzenvironment\else
\noexpand\begin{tikzpicture}[remember picture]%
\fi
}%
\edef\tikzend{%
\ifx\@currenvir\@tikzenvironment\else
\noexpand\end{tikzpicture}%
\fi
}%
}
答案2
\documentclass{article}
\usepackage{tikz}
\makeatletter
\newcommand{\IfInTikzPic}{% https://tex.stackexchange.com/a/121309/4301
\ifx\pgfpictureid\@undefined
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi
}
\makeatother
\newcommand*{\DrawLine}[1]{%
\IfInTikzPic
{\begin{tikzpicture}[remember picture]
\draw[ultra thick, ->, #1] (0,) -- (1,1) node [right] {output of DrawLine};
\end{tikzpicture}}%
{\draw[ultra thick, ->, #1] (0,) -- (1,1) node [right] {output of DrawLine};}%
}
\begin{document}
%%% The commented out code here is to show that \IfInTikzPic works as desired
%%% (in a tikzpicture, outside of a \node).
%%%
\textbf{IfInTikzPic}\par
\IfInTikzPic{inside}{outside}
\begin{tikzpicture}
\IfInTikzPic{\draw [red, ultra thick]}{\draw [blue, ultra thick]} (0,0) -- (1,0);
\end{tikzpicture}
\medskip% --------------------------
\textbf{DrawLine}: Actual Output\par
\DrawLine{blue}% <---- How do I get this case to work?
\begin{tikzpicture}
\DrawLine{orange}
\end{tikzpicture}
\medskip% --------------------------
\textbf{DrawLine}: Desired Output\par
\begin{tikzpicture}
\DrawLine{blue}
\end{tikzpicture}
\begin{tikzpicture}
\DrawLine{orange}
\end{tikzpicture}
\end{document}
或者这个版本直接强制 tikz,而不是使用 if-then-else 构造
\documentclass{article}
\usepackage{tikz}
\makeatletter
\newcommand{\ensuretikz}{% https://tex.stackexchange.com/a/121309/4301
\ifx\pgfpictureid\@undefined
\expandafter\tikzify
\else
\expandafter\@firstofone
\fi
}
\makeatother
\def\tikzify#1{\begin{tikzpicture}#1\end{tikzpicture}}
\newcommand*{\DrawLine}[1]{%
\ensuretikz
{\draw[ultra thick, ->, #1] (0,) -- (1,1) node [right] {output of DrawLine};}%
}
\begin{document}
%%% The commented out code here is to show that \IfInTikzPic works as desired
%%% (in a tikzpicture, outside of a \node).
%%%
\medskip% --------------------------
\textbf{DrawLine}: Actual Output\par
\DrawLine{blue}% <---- How do I get this case to work?
\begin{tikzpicture}
\DrawLine{orange}
\end{tikzpicture}
\medskip% --------------------------
\textbf{DrawLine}: Desired Output\par
\begin{tikzpicture}
\DrawLine{blue}
\end{tikzpicture}
\begin{tikzpicture}
\DrawLine{orange}
\end{tikzpicture}
\end{document}