# Drawbacks of csname method to avoid spaces after command

I had a similar problem as this one: Space after LaTeX commands

My first attempt was something like this:

\newcommand{\satip}{SAT\textgreater IP}


This leads to the known Problem, that spaces after the command are eaten up:

\satip is a cool Protocol. %Produces: SAT>IPis a cool Protocol.
space missing ^^^


I searched around and found the mentioned Question. The provided solutions helped a lot, but I wasn't completely happy with any of them. \satip/ just looks a little bit strange in a latex document, I like \satip{} much more. It's just, if I forget to put {} behind the command, the space is missing in output. Therefor I'd like to get an error if I use it wrong.

Possible Solution:

\def\satip#{SAT\textgreater IP}
%\satip is a cool Protocol. %doesn't compile, error


This way the open brace is enforced, but the braces can contain something:

\satip{is} a cool Protocol.


This compiles well, but as it doesn't make any sense, I'd like it to produce an error. My current way to handle the Problem is this:

\expandafter\def\csname satip{}\endcsname \relax{SAT\textgreater IP}
\def\satip#1{\csname satip{}\endcsname #1\relax}

%\satip{is} a cool Protocol. %Use of \satip{} doesn't match its definition.
%\satip is a cool Protocol. %Use of \satip{} doesn't match its definition.
\satip{} is a cool Protocol. %works


Now my Question:

This Macro needs a second expansion step. Could that cause any trouble? Are there other Problems? (As I haven't found this anywhere before.)

PS: Sorry for the bad title, I didn't came up with something better. Feel free to edit.

-
If anyone wants to play around: [overleaf.com/4337209grgmrz] – T S Feb 14 at 22:42
I would just use \satip\ , and I don't see why \satip{is} should produce an error with that definition. – Paul Gessler Feb 14 at 22:51
Mmm... you can always use \satip{} is a cool protocol with your first definition \newcommand*\satip{SAT\textgreater IP}, no need to define it obscurely. – Manuel Feb 14 at 22:51
The most efficient solution is \satip\  . If you really want an error, \def\satip/ is a reasonable way to go, and surely easier to write than \satip{}. And of course in the right circumstances, the \xspace package may be an option, though it is not always the right choice (there's a question on comp.text.tex about this). – jon Feb 14 at 23:02
@PaulGessler \satip{ip} doesn't produce an error, but i want it to produce an error, since this usage doesn't make any sense. (i'm not good with english, how can i say it more clearly?) – T S Feb 14 at 23:05

You can always use

\newcommand*\satip{SAT\textgreater IP}
\satip{} is a cool protocol


I don't see the problem.

By the way, your last definition defines de macro with name satip{} (braces included in the macro name) to be followed by a \relax token. If you put the #1 between \endcsname and \relax in the \satip macro it can only work if #1 is empty (i.e., only if empty braces are given \satip{} is...).

May be this achieves what you want?

\newcommand*\satip[1]
{\if\relax\detokenize{#1}\relax
SAT\textgreater IP%
\else
\GenericError{} % <- I don't know what this argument does
{Wrong use of \string\satip{}.} % <- short version
{Wrong use of \string\satip. You must use \string\satip\space followed by an empyt argument {}'.}% <- long version
\fi}

-
I knew of the fact, that the macro satip{} is defined (additional to satip), but didn't expect any problems with this, are there any? – T S Feb 14 at 23:09
Reading your comment above: you want to use \satip{} is a cool... but you want to ensure that {} is empty, i.e. not \satip{is} a cool...? – Manuel Feb 14 at 23:11
YES!! (my englisch is to bad, sorry that this wasn't clear...) – T S Feb 14 at 23:18
\newcommand*\satip[1]{SAT\textgreater IP\if\relax\detokenize{#1}\relax\else\PackageError{ts}{wrong use of \string\satip.}{Definitely wrong use of \string\satip{}.}\fi} but I don't get why would you want that. In TeX a {} following \satip doesn't mean it's an argument of \satip. – Manuel Feb 14 at 23:37
That actually works, thanks. I haven't thought about "In TeX a {} following \satip doesn't mean it's an argument of \satip". That makes it obvious why \def\satip#{...} is ok or even better. – T S Feb 14 at 23:46

I wouldn't use {} in the name of the auxiliary macro, but the method is sound:

\newcommand{\satip}[1]{\csname satip\string+\endcsname #1\relax}
\expandafter\def\csname satip\string+\endcsname\relax{%
SAT\textgreater IP%
}


will trigger an error in case \satip{x} is used

! Use of \satip+ doesn't match its definition.
<argument> x


However \satip ip wouldn't. You should do two steps:

\newcommand{\satip}{}% initialize
\protected\def\satip#{\csname satip\string+\endcsname}
\expandafter\def\csname satip\string+\endcsname#1{%
\csname satip\string+\string+\endcsname #1\relax
}
\expandafter\def\csname satip\string+\string+\endcsname\relax{%
SAT\textgreater IP%
}


Now both \satip x and \satip{x} would trigger errors:

! Use of \satip doesn't match its definition.
l.14 \satip x

?
! Use of \satip++ doesn't match its definition.
<argument> x

l.16 \satip{x}

?


Note \protected in front of the definition of \satip, so it wouldn't be expanded in “moving arguments” contexts.

An abstract version:

\documentclass{article}

\makeatletter
\newcommand\definestringcommand[2]{%
\@ifdefinable#1{\@definestringcommand#1{#2}}%
}

\newcommand{\@definestringcommand}[2]{%
\begingroup
\escapechar=\m@ne % get rid of the backslash
% require brace
\protected\xdef#1##{\expandafter\noexpand\csname\string#1\string+\endcsname}%
% examine the argument
\expandafter\xdef\csname\string#1\string+\endcsname##1{%
\expandafter\noexpand\csname\string#1\string+\string+\endcsname##1\relax
}%
\expandafter\gdef\csname\string#1\string+\string+\endcsname\relax{#2}%
\endgroup
}
\makeatother

\definestringcommand{\satip}{SAT\textgreater IP}

\begin{document}

\satip is nice

\satip{x} is nice

\satip{} is nice

\end{document}


Whether this is useful, I leave the decision to you.

A different implementation: check for the {, then check for a following } eating up both tokens in case of success.

\documentclass{article}

\makeatletter
\newcommand\definestringcommand[2]{%
\@ifdefinable#1{\@definestringcommand#1{#2}}%
}

\newcommand{\@definestringcommand}[2]{%
\begingroup
\escapechar=\m@ne % get rid of the backslash
% require brace
\protected\xdef#1##{%
\expandafter\noexpand\csname\string#1\string+\endcsname
}%
\expandafter\gdef\csname\string#1\string+\endcsname{%
#2%
\afterassignment\@checkrightbrace\let\@forget= % the space counts
}
\endgroup
}
\newcommand{\@checkrightbrace}{%
\@ifnextchar\egroup{\let\@forget= }{\@strcmderr\let\@forget= }%
}
\newcommand{\@strcmderr}{%
\@latex@error{Non empty group}{The braces must contain nothing}%
}
\makeatother

\definestringcommand{\satip}{SAT\textgreater IP}

\begin{document}

\satip is nice

\satip{x} is nice

\satip{} is nice

\end{document}

-
Why should \satip ip produce no error? Isn't i the argument in this case? Here it produces an error: [overleaf.com/4337962szgjcf] – T S Feb 15 at 0:12
@TS Yes, it would; but not because a brace is missing. I was still thinking to the \def\satip# method. – egreg Feb 15 at 0:19
ahh ok, thanks. What's the benefit of using + in the name of the auxiliary macro? with {} the correct usage \satip{} shows up in the error message "Use of \satip{} ..." (at least in some way) – T S Feb 15 at 0:20
@TS The benefit is having a macro name that can't be ordinarily produced. The idea with {} is interesting, though I'd not use it. But it's your code, not mine. ;-) I'd simply go with \newcommand{\satip}{SAT\textgreater IP}, to be honest. – egreg Feb 15 at 0:21
Can the macro name satip{} be produced "ordinarily"? (I assume "ordinarily" means without \csname`) – T S Feb 15 at 0:30