我正在尝试定义一个用于 tikz 图片的命令,该命令会根据选项字符串中的字符改变其外观。
这是一个简单的例子。我想要绘制 8 条或 15 条线,具体取决于是否指定了选项“x”,并且我想要根据是否指定选项“b”来更改线条的颜色。
这是我的代码(无法编译)
\documentclass{beamer}
\usepackage{xstring}
\usepackage{tikz}
\begin{document}
\newcommand\task[1]{
\foreach \i in {\IfSubStr{#1}{x}{0}{-7},...,7}{
\draw[\IfSubStr{#1}{b}{color=blue!20}] (0,0.2 * \i) -- (0.2,0.2 * \i);
}
}
\begin{tikzpicture}
\task{xb}
\end{tikzpicture}
\end{document}
有人能帮助我实现我的目标吗?
答案1
只有一种方法可以使其(a)更加灵活和(b)起作用:
我为此使用了键值方法。您可以轻松调整默认首选项,甚至可以将自己的值传递给您的键。
\documentclass{beamer}
\usepackage{tikz}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\keys_define:nn { mytask }
{
start .int_set:N = \l_mytask_start_int,
start .default:n = -7,
start .initial:n = 0,
color .tl_set:N = \l_mytask_color_tl,
color .default:n = {blue!20},
color .initial:n = black
}
\NewDocumentCommand { \task } { O{} }
{
\group_begin:
\keys_set:nn { mytask } { #1 }
\foreach \i in {\l_mytask_start_int,...,7}{
\draw[color=\l_mytask_color_tl] (0,0.2 * \i) -- (0.2,0.2 * \i);
}
\group_end:
}
\ExplSyntaxOff
\begin{document}
\begin{frame}
\begin{tikzpicture}
\task[start=-2]
\end{tikzpicture}
\begin{tikzpicture}
\task[color=green]
\end{tikzpicture}
\begin{tikzpicture}
\task[start,color]
\end{tikzpicture}
\end{frame}
\end{document}
感谢@egreg 提供了更 expl3-ish 的版本(我没有替换我以前的代码,因为使用 foreach 仍然可以):
\documentclass{beamer}
\usepackage{tikz}
\usepackage{expl3,xparse}
\ExplSyntaxOn
\keys_define:nn { mytask }
{
start .int_set:N = \l_mytask_start_int,
start .default:n = -7,
start .initial:n = 0,
color .tl_set:N = \l_mytask_color_tl,
color .default:n = {blue!20},
color .initial:n = black
}
\NewDocumentCommand { \task } { O{} }
{
\group_begin:
\keys_set:nn { mytask } { #1 }
\int_step_inline:nnnn { \l_mytask_start_int } { 1 } { 7 }
{
\draw[color=\l_mytask_color_tl] (0,0.2 * ##1) -- (0.2,0.2 * ##1);
}
\group_end:
}
\ExplSyntaxOff
\begin{document}
\begin{frame}
\begin{tikzpicture}
\task[start=-2]
\end{tikzpicture}
\begin{tikzpicture}
\task[color=green]
\end{tikzpicture}
\begin{tikzpicture}
\task[start,color]
\end{tikzpicture}
\end{frame}
\end{document}
答案2
我对此进行了更多的尝试,我发现即使我不能使用\IfSubStr
,但我可以在中\edef
使用。\edef
\IfSubStr
所以我现在得到了这个:
\documentclass{beamer}
\usepackage{xstring}
\usepackage{tikz}
\begin{document}
\newcommand\task[1]{
\IfSubStr{#1}{x}{\edef\starti{0}}{\edef\starti{-7}}
\IfSubStr{#1}{b}{\edef\drawcolor{blue!20}}{\edef\drawcolor{}}
\foreach \i in {\starti,...,7}{
\draw[\drawcolor] (0,0.2 * \i) -- (0.2,0.2 * \i);
}
}
\begin{tikzpicture}
\task{xb}
\end{tikzpicture}
\end{document}
不确定为什么我不能输入color=blue!20
那一秒\edef
(而不是仅仅blue!20
),但它就是这样工作的。