I want to check whether an argument of a command is fully contained in a pair of curly braces without using any extra packages. For this I define two macros containing {
and }
with catcode 12, respectively. Then I turn the input into a string using \detokenize
and compare the first and the last token I find.
The macro should either ignore leading and trailing spaces around the group or treat them as false (ignoring has higher priority -- two versions one ignoring one not would be best).
So the following should be outputted for the ignoring version:
\MyIfGroup{{}}{true}{false} -> true\MyIfGroup{ {}}{true}{false} -> true\MyIfGroup{{} }{true}{false} -> true\MyIfGroup{ {} }{true}{false} -> true\MyIfGroup{ }{true}{false} -> false\MyIfGroup{a}{true}{false} -> false\MyIfGroup{{}a}{true}{false} -> false
The not ignoring version should return true only for the first of the above cases. Anything inside the inner pair of braces (even nested braces) shouldn't make a difference (except for unmatched braces). The case \MyIfGroup{{}{}}
is considered an edge case (by myself) and doesn't have to be detected correctly -- it would be nice though.
The following code is an ignoring version which detects everything except {}{}
(that's ok) and if there is space after the pair of braces, in which case it throws a "Runaway argument"-error.
\documentclass[]{article}\makeatletter\newcommand\MyIfEmptyTF[1] {% \if\relax\detokenize{#1}\relax \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi }\newcommand\MyIfGroupTF[1] {% \MyIfEmptyTF{#1}{\@secondoftwo} {% \expandafter\MyIfGroup@preopen\expandafter{\detokenize{#1}}% }% }\newcommand\MyIfGroup@preopen[1] {% \MyIfDetSpaceTF{#1} {\@secondoftwo} {\MyIfGroup@open#1\end@MyIfGroup}% }\long\def\MyIfGroup@open#1#2\end@MyIfGroup% {% \if\Mylbraceother#1% \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi {\MyIfGroup@close#2\end@MyIfGroup} {\@secondoftwo}% }\long\def\MyIfGroup@close#1#2\end@MyIfGroup {% \MyIfEmptyTF{#2} {% \MyIfDetSpaceTF{#1} {\@secondoftwo} {% \if\Myrbraceother#1% \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi }% } {\MyIfGroup@close#2\end@MyIfGroup} }\newcommand\MyIfDetSpaceTF[1] {% \if#1\detokenize{ }% \expandafter\@firstoftwo \else \expandafter\@secondoftwo \fi }\bgroup\catcode`\{=12\catcode`\}=12\catcode`\(=1\catcode`\)=2\gdef\Mylbraceother({)\gdef\Myrbraceother(})\egroup\makeatother\begin{document}Works: \MyIfGroupTF{{i}}{true}{false}.Works: \MyIfGroupTF{ {}}{true}{false}.Works: \MyIfGroupTF{ }{true}{false}.Works: \MyIfGroupTF{ a }{true}{false}.Works: \MyIfGroupTF{a}{true}{false}.Wrong: \MyIfGroupTF{{}{}}{true}{false}.%Doesn't compile (fails in @close): \MyIfGroupTF{{} }{true}{false}.\end{document}