3

How can I implement a macro \mymacro with one argument and the following behavior: I would like to pass either arguments of the form \mymacro{some text} or two nested arguments like \mymacro{{Text 1}{Text2}}. The desired output is this:

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

So, how can I test if one string or two {}-separated tokens are given?

8

Tis can be done by \def...#{...} feature in order to test if prameter begins by internal {.

\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
4

Here is a fully expandable solution to your problem. I don't know whether you want to go through all of this hell.

\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}

enter image description here


You might want to use xparse instead.

\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}

enter image description here

  • \edef\bracetwelve{\string{} is easier – egreg May 1 '17 at 9:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.