Как создать макрос, который создает другие макросы (принимает аргументы)?

Как создать макрос, который создает другие макросы (принимает аргументы)?

Я хочу создать макрос, а именно \newpoint{<point name>}{<point style>}, который создает макросы типа \Point<point name>{<x coord>}{<y coord>}{<label>}.

я виделКак определить макрос для создания нового макроса с именем, переданным в качестве аргумента?что находится на полпути, поскольку не показывает, как заставить созданный макрос получать аргументы.

Я пытался:

\newcommand*{\newpoint}[2]{%
   \tikzset{#1/.style={#2}}%
   \newcounter{point#1}\setcounter{point#1}{0}%
   \def\csname Point#1\endcsname (##1,##2)|##3;{%
        \stepcounter{point#1}\fill[#1] (##1,##2) circle (2pt) node[above](#1-\thepoint#1){##3};}%
}

Но, судя по всему, и честно говоря, это не сработало Use of \csname doesn't match it's definition... Я больше не знаю, что делаю.

Вот мой М(Н)МЫ:

\documentclass[tikz, border=2mm]{standalone}
\newcommand*{\newpoint}[2]{%
   \tikzset{#1/.style={#2}}%
   \newcounter{point#1}\setcounter{point#1}{0}%
   \def\csname Point#1\endcsname (##1,##2)|##3;{%
        \stepcounter{point#1}\fill[#1] (##1,##2) circle (2pt) node[above](#1-\thepoint#1){##3};}%
}
\newpoint{A}{red}
\begin{document}
 \begin{tikzpicture}
  \PointA(1,2)|A;
 \end{tikzpicture}
\end{document} 

решение1

Как заметил @daleif, поставьте \expandafterперед \def. И чтобы получить, \thepointAвам придется использовать \csname ... \endcsnameтам. Думаю, это то, что вам нужно:

\newcommand*{\newpoint}[2]{%
   \tikzset{#1/.style={#2}}%
   \newcounter{point#1}\setcounter{point#1}{0}%
   \expandafter\def\csname Point#1\endcsname (##1,##2)|##3;{%
        \stepcounter{point#1}\fill[#1] (##1,##2) circle (2pt) node[above](#1-\csname thepoint#1\endcsname){##3};}%
}

А вот решение без реального счетчика для каждого вызова \newpoint, основанное на решении с псевдосчетчиком от @egreg, но с приращением псевдосчетчика при каждом вызове макроса \point<name>.

\newcounter{pointnumber}
\newcommand\StepPointNumber[1]{%
    \setcounter{pointnumber}{\csname number@point#1\endcsname}%
    \stepcounter{pointnumber}
    \expandafter\xdef\csname number@point#1\endcsname{\thepointnumber}%
              \expandafter\show\csname number@point#1\endcsname
}
\newcommand*{\newpoint}[2]{%
   \tikzset{#1/.style={#2}}%
   \expandafter\def\csname number@point#1\endcsname{0}%
   \expandafter\def\csname Point#1\endcsname (##1,##2)|##3;{%
        \StepPointNumber{#1}%
        \fill[#1] (##1,##2) circle (2pt) node[above](#1-\csname number@point#1\endcsname){##3-\csname number@point#1\endcsname};}%
}

решение2

Я не вижу необходимости выделять новый счетчик, если только вы не хотите производить с ним арифметические действия.

Но главное, что вам нужно использовать их \csnameправильно:

\documentclass[tikz, border=2mm]{standalone}

\newcommand*{\newpoint}[2]{%
   \tikzset{#1/.style={#2}}%
   \expandafter\def\csname number@point#1\endcsname{0}%
   \expandafter\def\csname Point#1\endcsname (##1,##2)|##3;{%
        \fill[#1] (##1,##2) circle (2pt) node[above](#1-\csname number@point#1\endcsname){##3};}%
}

\newpoint{A}{red}

\begin{document}

\begin{tikzpicture}
  \PointA(1,2)|A;
\end{tikzpicture}

\end{document}

Связанный контент