我构造了一个名为\mycal
(带有可选参数) 的宏来计算将在 中使用的坐标值\tikz\draw
。我发现使用这个可选参数,代码无法编译。当可选参数变为强制参数时,代码可以正常工作。但我确实需要这个可选参数。为什么以及如何解决这个问题?
梅威瑟:
\documentclass{article}
\usepackage{tikz,picture}
\begin{document}
% The following part can not compile
% \newcommand{\mycal}[3][0pt]{\the\dimexpr #2 + #3 + #1}
% \newcommand\mydraw[3]{\tikz\draw(0,0)--(\mycal[#1]{#2}{#3},0);}
% \mydraw{1pt}{2cm}{3cm}
% The following part ok!
\newcommand{\mycal}[3]{\the\dimexpr #2 + #3 + #1}
\newcommand\mydraw[3]{\tikz\draw(0,0)--(\mycal{#1}{#2}{#3},0);}
\mydraw{1pt}{2cm}{3cm}
\end{document}
答案1
您的宏不起作用,因为带有可选参数的宏不可扩展,因此不能在路径构造的中间使用。Tex 必须执行一些赋值来确定可选参数是否存在。解决方案可能是使用\pgfextra
允许您暂时中断路径构造并执行一些代码。您必须修改代码以将计算结果保存到某个寄存器,然后使用它。
\documentclass{article}
\usepackage{tikz}
\newdimen\mydimen
\newcommand\mycal[3][0cm]{\mydimen=\dimexpr #2 + #3 + #1\relax}
\newcommand\mydraw[3][0cm]{\tikz\draw(0cm,0cm) \pgfextra{\mycal[#1]{#2}{#3}} --(\mydimen,0cm);}
\begin{document}
\mydraw[1cm]{2cm}{3cm}
\mydraw{2cm}{3cm}
\end{document}
顺便说一句,在您的示例中,\mycal
实际上并不需要采用可选参数\mydraw
。
\newcommand\mycal[3]{\dimexpr #2 + #3 + #1\relax}
\newcommand\mydraw[3][0cm]{\begin{tikzpicture}\draw(0cm,0cm)-- (\mycal{#1}{#2}{#3},0cm);
编辑:
如果你坚持要使用\mycal
可选参数而不使用\pgfextra
,那么你可以使用以下技巧。它定义了一个\mycalc
带有可选参数的可扩展函数。
\documentclass{article}
\usepackage{tikz}
\makeatletter
\def\mycal#1{%
\ifx[#1\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\@mycal[}{\@mycal[0cm]{#1}}}
\def\@mycal[#1]#2#3{\dimexpr#1+#2+#3\relax}
\makeatother
\begin{document}
\tikz\draw(0cm,0cm)--(\mycal{2cm}{3cm},0cm);
\tikz\draw(0cm,0cm)--(\mycal[1cm]{2cm}{3cm},0cm);
\end{document}
新编辑:
要用\mycal{2cm,3cm}
or\mycal[1cm]{2cm,3cm}
代替\mycal{2cm}{3cm}
or,\mycal[1cm]{2cm}{3cm}
您可以定义\mycal
如下
\documentclass{article}
\usepackage{tikz}
\makeatletter
\def\mycal#1{%
\ifx[#1\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
{\@mycal[}{\@mycal[0cm]{#1}}}
\def\@mycal[#1]#2{\@@mycal{#1}#2\@nil}
\def\@@mycal#1#2,#3\@nil{\dimexpr#1+#2+#3\relax}
\makeatother
\begin{document}
\tikz\draw(0cm,0cm)--(\mycal{2cm,3cm},0cm);
\tikz\draw(0cm,0cm)--(\mycal[1cm]{2cm,3cm},0cm);
\end{document}