TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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.

share|improve this question
    
If anyone wants to play around: [overleaf.com/4337209grgmrz] – T S Feb 14 at 22:42
1  
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
1  
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
up vote 3 down vote accepted

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}
share|improve this answer
    
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
2  
\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}
share|improve this answer
1  
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
1  
@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
1  
@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
1  
Can the macro name satip{} be produced "ordinarily"? (I assume "ordinarily" means without \csname) – T S Feb 15 at 0:30

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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