
Как реализовать макрос \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}