Поглощение аргумента, если он содержит много токенов, разделенных {}

Поглощение аргумента, если он содержит много токенов, разделенных {}

Как реализовать макрос \mymacroс одним аргументом и следующим поведением: Я хотел бы передать либо аргументы формы \mymacro{some text}, либо два вложенных аргумента, например \mymacro{{Text 1}{Text2}}. Желаемый вывод такой:

\mymacro{Some text}        ->   Some text 
\mymacro{{Some text}}      ->   Some text 
\mymacro{{Text 1}{Text 2}} ->   1: Text 1 / 2: Text 2

Итак, как я могу проверить, задана ли одна строка или два токена, разделенных {}?

решение1

Это можно сделать по \def...#{...}признаку, чтобы проверить, начинается ли параметр с внутреннего {.

\def\mymacro#1{\mymacroA#1{\end}{\end}\end}
\def\mymacroA#1#{%
   \ifx\end#1\end          % parameter begins by {
      \expandafter\mymacroB \else #1\expandafter\mymacroC
   \fi
}
\def\mymacroB#1#2#3\end{%
   \ifx\end#1\empty        % paremeter is empty
   \else\ifx\end#2\empty   % parameter has only one {}
      #1\else 1: #1 / 2: #2%
   \fi\fi
}
\def\mymacroC#1\end{}

A) \mymacro{Some text}        =   Some text 

B) \mymacro{{Some text}}      =   Some text 

C) \mymacro{{Text 1}{Text 2}} =   1: Text 1 / 2: Text 2

\bye

решение2

Вот полностью расширяемое решение вашей проблемы. Я не знаю, хотите ли вы пройти через весь этот ад.

\documentclass{article}

\makeatletter

\begingroup
  \catcode`{=12
  \global\let\bracetwelve={
\endgroup

\def\firsttoken#1#2\endfirsttoken{#1}

\def\ifelsefirstcharbrace#1{%
  \if\bracetwelve\expandafter\firsttoken\detokenize{#1}\relax\relax\endfirsttoken
    \expandafter\@firstoftwo
  \else
    \expandafter\@secondoftwo
  \fi
}

\def\stripbracesrelax#1\relax{#1}

\makeatother

\def\mymacro#1{%
  \ifelsefirstcharbrace{#1}%
    {\domymacrotwo#1\relax\enddomymacrotwo}%
    {\domymacroone{#1}}}

\def\domymacroone#1{#1}

\def\domymacrotwo#1#2\enddomymacrotwo{%
  \ifx#2\relax
    \domymacroone{#1}%
  \else
    1: #1 / 2: \stripbracesrelax#2
  \fi}

\begin{document}
\ttfamily

\edef\x{\mymacro{}} \meaning\x

\edef\x{\mymacro{Some text}} \meaning\x

\edef\x{\mymacro{{Some text}}} \meaning\x

\edef\x{\mymacro{{Text 1}{Text 2}}} \meaning\x

\edef\x{\mymacro{{}{}}} \meaning\x
\end{document}

введите описание изображения здесь


Вместо этого вы можете использовать xparse.

\documentclass{article}
\usepackage{xparse}

\DeclareDocumentCommand \mymacro { g g }
{%
  \IfValueT{#1}{\IfValueTF{#2}{1: #1 / 2: #2}{#1}}%
}

\begin{document}
\mymacro

\mymacro{Some text}

\mymacro{Some text}

\mymacro{Text 1}{Text 2}

\mymacro{}{}
\end{document}

введите описание изображения здесь

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