You wish to define a macro \c
. But \c
is already defined in LaTeX.
Therefore I will henceforth not refer to the macro in question as \c
.
Instead I will refer to the macro in question as \macroc
.
Are you aware that in TeX/LaTeX undelimited arguments consisting of a single token don't need to be nested in braces?
After defining \newcommand\foo[1]{This is argument 1: #1.}
,
\foo{b}
will yield the same result as
\foo b
.
After defining \newcommand\bar[2]{This is argument 1: #1. This is argument 2: #2.}
, the following calls will all yield the same result:
\bar{a}{b}
\bar a{b}
\bar {a}b
\bar ab
\bar{a} {b}
\bar a {b}
\bar {a} b
\bar a b
This is because
- you don't need braces when undelimited arguments consist of a single token.
- (La)TeX does discard space tokens preceding undelimited arguments.
When called as \macroc{a}{b}c
—how shall \macroc
"know" whether the user intends to have c
as \macroc
's third argument which consists of the single token c
or whether the user intends to have \macroc
called with only two arguments, namely {a}
and {b}
while c
shall not be considered a third argument?
The situation is ambiguous.
You can turn the situation into something unambiguous by having \macroc
process only one undelimited argument and having \macroc
check whether that argument in turn is of one of the patterns
{⟨argument 1⟩}
{⟨argument 1⟩}{⟨argument 2⟩}
{⟨argument 1⟩}{⟨argument 2⟩}{⟨argument 3⟩}
and having \macroc
act accordingly in case one of these patterns is detected and having \macroc
deliver an error-message otherwise.
I.e.,
\macroc{{⟨argument 1⟩}}
\macroc{{⟨argument 1⟩}{⟨argument 2⟩}}
\macroc{{⟨argument 1⟩}{⟨argument 2⟩}{⟨argument 3⟩}}
With the example below, \macroc
does process one undelimited argument.
Syntax: \macroc{⟨argument⟩}
.
In case ⟨argument⟩
is of pattern {⟨argument 1⟩}
,
\macrocatonearg{⟨argument 1⟩}
will be carried out.
In case ⟨argument⟩
is of pattern {⟨argument 1⟩}{⟨argument 2⟩}
,
\macrocattwoargs{⟨argument 1⟩}{⟨argument 2⟩}
will be carried out.
In case ⟨argument⟩
is of pattern {⟨argument 1⟩}{⟨argument 2⟩}{⟨argument 3⟩}
,
\macrocatthreeargs{⟨argument 1⟩}{⟨argument 2⟩}{⟨argument 3⟩}
will be carried out.
In all other cases an error-message will inform the user about a syntax-error.
Thus you can do, e.g., :
\macroc{{a}}
\macroc{{a}{b}}
\macroc{{a}{b}{c}}
\documentclass{article}
\makeatletter
%%=============================================================================
%% Paraphernalia:
%% \UD@firstoftwo, \UD@secondoftwo,
%% \UD@gobble, \UD@gobbletwo, \UD@gobblethree
%% \UD@CheckWhetherNull, \UD@CheckWhetherBrace,
%%=============================================================================
\newcommand\UD@firstoftwo[2]{#1}%
\newcommand\UD@secondoftwo[2]{#2}%
\newcommand\UD@gobble[1]{}%
\newcommand\UD@gobbletwo[2]{}%
\newcommand\UD@gobblethree[3]{}%
%%-----------------------------------------------------------------------------
%% Check whether argument is empty:
%%.............................................................................
%% \UD@CheckWhetherNull{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is empty>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked is not empty>}%
%%
%% The gist of this macro comes from Robert R. Schneck's \ifempty-macro:
%% <https://groups.google.com/forum/#!original/comp.text.tex/kuOEIQIrElc/lUg37FmhA74J>
\newcommand\UD@CheckWhetherNull[1]{%
\romannumeral0\expandafter\UD@secondoftwo\string{\expandafter
\UD@secondoftwo\expandafter{\expandafter{\string#1}\expandafter
\UD@secondoftwo\string}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
\UD@secondoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@firstoftwo}%
}%
%%-----------------------------------------------------------------------------
%% Check whether argument's first token is a catcode-1-character
%%.............................................................................
%% \UD@CheckWhetherBrace{<Argument which is to be checked>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked has leading
%% catcode-1-token>}%
%% {<Tokens to be delivered in case that argument
%% which is to be checked has no leading
%% catcode-1-token>}%
\newcommand\UD@CheckWhetherBrace[1]{%
\romannumeral0\expandafter\UD@secondoftwo\expandafter{\expandafter{%
\string#1.}\expandafter\UD@firstoftwo\expandafter{\expandafter
\UD@secondoftwo\string}\expandafter\expandafter\UD@firstoftwo{ }{}%
\UD@firstoftwo}{\expandafter\expandafter\UD@firstoftwo{ }{}\UD@secondoftwo}%
}%
%%=============================================================================
%% \macroc for processing one argument within which
%% you may have one or two or three brace-nested arguments:
%%-----------------------------------------------------------------------------
\newcommand\macrocatonearg[1]{C_#1}%
\newcommand\macrocattwoargs[2]{C_{#1}^{[#2]}}%
\newcommand\macrocatthreeargs[3]{C_{#1,#3}^{[#2]}}%
\newcommand\macrocatsyntaxerror{%
\@latex@error{Incorrect Syntax}{Specify either one or two or three arguments that are nested in braces.}%
}%
\newcommand\macroc[1]{%
\UD@CheckWhetherBrace{#1}{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@gobble#1}{%
\macrocatonearg#1%
}{%
\expandafter\UD@CheckWhetherBrace\expandafter{\UD@gobble#1}{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@gobbletwo#1}{%
\macrocattwoargs#1%
}{%
\expandafter\UD@CheckWhetherBrace\expandafter{\UD@gobbletwo#1}{%
\expandafter\UD@CheckWhetherNull\expandafter{\UD@gobblethree#1}{%
\macrocatthreeargs#1%
}{\macrocatsyntaxerror}%
}{\macrocatsyntaxerror}%
}%
}{\macrocatsyntaxerror}%
}%
}{\macrocatsyntaxerror}%
}%
\makeatother
\begin{document}
\verb|$\macroc{{a}}$|: $\macroc{{a}}$ \bigskip
\verb|$\macroc{{a}{b}}$|: $\macroc{{a}{b}}$ \bigskip
\verb|$\macroc{{a}{b}{c}}$|: $\macroc{{a}{b}{c}}$ \bigskip
% Syntax-errors:
%
% $\macroc{{a}{b}{c}{d}}$
%
% $\macroc{ {a}}$
%
% $\macroc{{a} {b}}$
%
% $\macroc{a}$
%
% $\macroc{}$
\end{document}

\c{a}bc
? Shall this mean\c
has one arg and the one-arg-call to\c
is trailed by lettersb
andc
which do not form args of\c
? Shall this mean a three-argument-call to\c
with two args just not being nested in braces as braces are not really needed with single-token-arguments? You can check if a single-argument-macro's arg in turn consists of three or two or one brace-delimited arguments, i.e.,\c{{a}{b}{c}}
, but then you need to specify behavior for other cases and spaces as well.