允许宏定义中的参数之间有空格

允许宏定义中的参数之间有空格

我不知道允许这种做法是否正确,但我被问过很多次了。如何在下面的代码中允许方括号和圆括号之间有空格?我尝试使用,但\@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}

在此处输入图片描述

相关内容