我不知道允许这种做法是否正确,但我被问过很多次了。如何在下面的代码中允许方括号和圆括号之间有空格?我尝试使用,但\@ifnextchar
没有成功,也许用expl3
\documentclass{standalone}
\usepackage{tikz}
\makeatletter
\def\DrawPolygon{\@ifnextchar[{\@DrawPolygon}{\@DrawPolygon[]}}
\def\@DrawPolygon[#1](#2,#3)#4{%
\begingroup
\draw[#1] (#2)
\foreach \pt in {#2,#3}{--(\pt)}--cycle;
\endgroup
}
\makeatother
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0,0);
\coordinate (B) at (2,0);
\coordinate (C) at (2,2);
\coordinate (D) at (0,3);
\DrawPolygon [red](A,...,D) {mypolygon} %ok
% problem with \DrawPolygon [red] (A,...,D) {mypolygon}
\end{tikzpicture}
\end{document}
答案1
作为 xparse 的替代方案,对现有定义进行简单的调整就是改变
\def\@DrawPolygon[#1](#2,#3)#4{%
\begingroup
\draw[#1] (#2)
\foreach \pt in {#2,#3}{--(\pt)}--cycle;
\endgroup
}
到
\def\@DrawPolygon[#1]#2(#3,#4)#5{%
\begingroup
\draw[#1] (#3)
\foreach \pt in {#3,#4}{--(\pt)}--cycle;
\endgroup
}
这将允许]
和之间有空格(或任何内容) (
。
如果您想检查的话,您当然可以检查 #2 是否最多包含空格,但宏已经默默地丢弃#4
(现在#5
),因此对新的执行相同操作#2
似乎并不太糟糕。
答案2
您可以使用xparse
。第一个参数是可选的,默认值为空;第二个参数可以是从(
到逗号的任何值,第三个参数可以是直到的任何值)
。
\documentclass{article}
\usepackage{tikz,xparse}
\NewDocumentCommand{\DrawPolygon}{O{}r(,u)m}{%
\draw[#1] (#2) \foreach \pt in {#2,#3}{--(\pt)}--cycle;
}
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0,0); \coordinate (B) at (2,0);
\coordinate (C) at (2,2); \coordinate (D) at (0,3);
\DrawPolygon [red](A,...,D) {mypolygon}
\end{tikzpicture}
\begin{tikzpicture}
\coordinate (A) at (0,0); \coordinate (B) at (2,0);
\coordinate (C) at (2,2); \coordinate (D) at (0,3);
\DrawPolygon [red] (A,...,D) {mypolygon}
\end{tikzpicture}
\end{document}
避免参数类型可能会更好u
,但是对于这个应用程序来说,它似乎足够了。
避免以下情况的代码u
:
\ExplSyntaxOn
\NewDocumentCommand{\DrawPolygon}{O{}r()m}
{
\am_drawpolygon:nnn { #1 } { #2 } { #3 }
}
\cs_new_protected:Nn \am_drawpolygon:nnn
{
\draw[#1](\clist_item:nn { #2 } { 1 }) \foreach \pt in {#2}{--(\pt)}--cycle;
}
\ExplSyntaxOff
答案3
这是另一种方法:
\documentclass[tikz, border=2mm]{standalone}
\usepackage{tikz}
\usepackage{xparse}
\ExplSyntaxOn
\cs_new_protected:Npn \alain_draw_poly:nw #1#2,#3\q_stop
{
\group_begin:
\draw[#1] (#2)
\foreach \pt in {#2,#3} {--(\pt)} -- cycle;
\group_end:
}
\NewDocumentCommand \DrawPolygon { O{} R(){} }
{
\alain_draw_poly:nw {#1} #2 \q_stop
}
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0,0);
\coordinate (B) at (2,0);
\coordinate (C) at (2,2);
\coordinate (D) at (0,3);
\DrawPolygon [red] (A,...,D) {mypolygon}
\end{tikzpicture}
\end{document}
注意:\@DrawPolygon
在 MWE 中不使用其#4
。下面是代码的增强版本,它在多边形的质心处创建一个节点,#4
节点内容如下:
\documentclass[tikz, border=2mm]{standalone}
\usepackage{tikz}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \g__alain_pts_seq
\cs_new_protected:Npn \alain_draw_poly:nwn #1#2,#3\q_stop #4
{
\group_begin:
\draw[#1] (#2)
\foreach \pt in {#2,#3} {--(\pt)} -- cycle;
\seq_gclear:N \g__alain_pts_seq
\foreach \pt in {#2,#3}
{ \seq_gput_right:Nx \g__alain_pts_seq { \exp_not:V \pt =1 } }
\node at (barycentric~cs \c_colon_str \seq_use:Nn \g__alain_pts_seq { , })
{#4};
\group_end:
}
\NewDocumentCommand \DrawPolygon { O{} R(){} m }
{
\alain_draw_poly:nwn {#1} #2 \q_stop {#3}
}
\ExplSyntaxOff
\begin{document}
\begin{tikzpicture}
\coordinate (A) at (0,0);
\coordinate (B) at (2,0);
\coordinate (C) at (2,2);
\coordinate (D) at (0,3);
\DrawPolygon [red] (A,...,D) {My polygon}
\end{tikzpicture}
\end{document}