为什么这个 MNWE(最小非工作示例)会失败?
\documentclass{article}
\usepackage{tikz}
\begin{document}
\newcommand\mypoint{(1pt,0pt)}
\begin{tikzpicture}
\node [draw,circle] at \mypoint {};
\draw (0,0) to \mypoint;
\end{tikzpicture}
\end{document}
显然,\mypoint
定义了一个非常好的坐标,因为节点创建执行得非常好,可以通过注释掉命令来验证\draw
。但是使用它画线时会出现错误。发生了什么?我该如何修复它?
这个愚蠢的 MNWE 是从更现实的情况中提炼出来的:关键是我需要能够画一条线到宏返回的点。
答案1
不同之处在于,\node
在查看下一个标记之前,它会将其展开,这使得\mypoint
变成(1pt,0pt)
。但是,to
中的会直接\draw
等待( )
,否则 TeX 编译器会引发错误。这就是 TikZ 作者编写的程序。
你必须知道宏可以有参数文本,即可以在参数之间指定某些文本。无法通过 LaTeX 的高级命令(如)访问此功能。必须使用\newcommand
较低级别的 TeX 宏(或类似命令)。您可以定义一个宏,然后等待它之后的直接字符,将直到下一个字符的所有内容作为第一个参数,然后将它和 a 之间的所有内容作为第二个参数。如果缺少任何这些字符,则会引发 TeX 编译错误。现在,这些字符必须直接跟在后面,并且不是宏的一部分(因为这会隐藏它们)或在宏内部(因为必须先关闭它们才能匹配文本)。\def
\def\mymacro(#1,#2){ .. }
(
,
)
{ }
TikZ 大量使用此功能来编写语法。因为\node
可以按任意顺序等待多个事物,所以它会先将任何事物扩展为简单事物。但是,\draw (x,y) to
仅等待(x,y)
之后,因此底层宏to
可能像上面一样定义\mymacro
。让它先扩展下一个标记会使它变得更加复杂,我猜这就是它未包含在内的原因。或者程序员根本没有考虑过这种情况。
我建议你\coordinate
在示例中改用。这样可以避免此问题。
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\coordinate (mypoint) at (1pt,0pt);
\node [draw,circle] at (mypoint) {};
\draw (0,0) to (mypoint);
\end{tikzpicture}
\end{document}