0

I tried to use ifdef command for that, but it doesn't work. It outputs text when it's passed and executes the true branch.

\documentclass{article}
\usepackage{etoolbox}

\begin{document}

\NewDocumentCommand\MainCommand{m}
{
    \ifdef{#1}
    {
        I received a command! #1
    }
    {
        It's not a command( #1
    }
}

\newcommand\somecommand
{
    Text
}

\MainCommand{\somecommand}

\MainCommand{some text}

\end{document}
6
  • 2
    Can it solve your problem using \ifcsname, then you just need to pass foo instead of \foo.
    – zpding
    Commented Jun 22 at 14:28
  • @zongpingding That's not what I need. Commented Jun 22 at 14:37
  • 1
    You want to emulate the bad syntax of, for instance, \foreach. Don't.
    – egreg
    Commented Jun 22 at 14:40
  • 1
    why would you want that? is {\acommand some text} a command or not a command?, why would you want \foo to act differently to some text if defined by \def\foo{some text} ? Commented Jun 22 at 14:47
  • Please clarify: What constellations of tokens do you subsume under the term "command"? E.g., after \let\letterA=A - is \letterA a command? The entire directive \newcommand\foo{\bar} can also be considered a command. Probably you can check blankness of the 1st argument. If not blank, check for explicit leading category-1-character-token. If no leading category-1 token extract the args 1st token and apply \meaning and analyze the result thereof. Commented Jun 22 at 15:12

2 Answers 2

3
\documentclass{article}

\ExplSyntaxOn

\NewDocumentCommand{\MainCommand}{m}
 {
  \bool_lazy_and:nnTF { \tl_if_single_p:n { #1 } } { \token_if_cs_p:N #1 }
   {I~was~called~with~the~command~\texttt{\token_to_str:N #1}}
   {I~was~not~called~with~a~command,~but~with~\texttt{#1}}
 }

\ExplSyntaxOff

\begin{document}

\MainCommand{\somecommand}

\MainCommand{some text}

\MainCommand{\'Alert}

\end{document}

enter image description here

With \bool_lazy_and:nnTF we check whether both conditions are true, but evaluation stops if the first condition turns out to be false, so avoiding the failure of the second condition.

But, for your own sanity, don't do it. Commands that receive macros as arguments should be distinct from those that receive arbitrary text.

It's true that \foreach does this, but I consider it bad syntax nonetheless. There are too many corner cases.

2

You can do this, but you should not.

enter image description here

This tests if the first token in the argument is a command.

\documentclass{article}
\usepackage[T1]{fontenc}

\begin{document}
\long\def\cleanup#1\xmaincommand{}
\def\firstoftwo#1#2{#1}
\def\secondoftwo#1#2{#2}
\NewDocumentCommand\MainCommand{m}
{%
    \expandafter\cleanup\if\relax\noexpand#1\xmaincommand\expandafter\firstoftwo\else\xmaincommand\expandafter\secondoftwo\fi
      {I received a command! \texttt{\detokenize{#1}}}%
      {It's not a command: \texttt{#1}}%
}

\newcommand\somecommand
{
    Text
}

\MainCommand{\somecommand}

\MainCommand{\somecommand\foo}

\MainCommand{some text \textbf{abc}}

\MainCommand{\textbf{abc some text}}

\MainCommand{~some text}

\MainCommand{Șome text}

\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .