645

I have a definition:

\newcommand{\arnold}{Arnold Schwarzenegger}

When I refer to it by:

\arnold is a

it is rendered as:

Arnold Schwarzeneggeris a

In order to have a space in front of "is" I would need to write

\arnold\ is a

Is there some other shorter way?

1

12 Answers 12

510

If you create a macro without arguments you should always invoke it with an empty statement after it: \arnold{}

The reason behind this is that LaTeX ignores (typed) spaces directly after the macro (they just stop the scanning for the macro’s name). You need to break that using either a protected space (as you already wrote) or an empty statement {}. I'd recommend using an empty statement, as using a protected space can generate nasty effects — for example, if that protected space is directly followed by a line break. In that case LaTeX might print two spaces instead which looks ugly and isn't wanted. Using an empty statement prevents this.

How you can add the space directly to the macro has already been answered, but do you really want this? You'd get into trouble as soon as the macro is to be followed by a punctuation mark (or if the macro is followed by a \footnote, etc.):

\arnold,
Arnold Schwarzenegger ,

I'd recommend going for the empty statement option -- one gets used to that quite fast.

12
  • 45
    "xspace" is a tiny package which basically just contains a list of punctuation marks, making it not insert the space if there is a punctuation mark.
    – Kaarel
    Commented Feb 4, 2009 at 19:17
  • 8
    Thanks for this. I have been creating two of each \newcommand, one with a space and one without, but I knew there had to be a way to make it smarter. Also, apparently you have to do this with some built in stuff, like \LaTeX{}, or you will get the same problem.
    – asmeurer
    Commented Dec 9, 2010 at 3:11
  • 31
    {\command} works as \command{} and looks nicer IMHO.
    – Trylks
    Commented Sep 10, 2013 at 13:15
  • 13
    That's a nice explanation, but why is it the accepted answer? Writing \arnold{} is one character longer than \arnold\ , so it doesn't quite satisfy the requirement for a "shorter way". (The \ approach is also Donald Knuth's recommendation, by the way.)
    – alexis
    Commented Mar 3, 2014 at 17:52
  • 22
    There are many mistakes in this answer. "LaTeX expects an argument" -> TeX ignores the space after multiletter control sequence during its tokenization. What does mean "scanning mode for the macro"? The {} isn't empty statement but it processes \bgroup\egroup. And the \ at the end of line in the source file acts like \^^M and this creates only one space.
    – wipet
    Commented Oct 16, 2014 at 4:51
358

Yes, look at the xspace package.

\usepackage{xspace}

And later on...

\newcommand{\arnold}{Arnold Schwarzenegger\xspace}
6
  • 2
    It's a tricky one. My advisor years ago told me about it or I would never have found it.
    – Uri
    Commented Feb 4, 2009 at 19:16
  • 4
    Note this will not work when you enclose it in braces again: \newcommand{\arnold}{{Arnold Schwarzenegger\xspace}} This would be useful in situations where you must enclose your commands anyway, e.g. in combination with the soul package: \hl{foo \arnold bar} would not work unless you enclose it in additional braces.
    – math
    Commented Mar 29, 2012 at 12:15
  • 59
    Importantly related: Drawbacks of xspace
    – doncherry
    Commented Dec 15, 2012 at 19:28
  • it doesn't seem to work with \defcitealias
    – Valerio
    Commented Sep 20, 2021 at 13:29
  • 2
    Please note, as @doncherry referenced, that the author of xspace himself recommends NOT using his package.
    – Suuuehgi
    Commented Apr 24, 2022 at 19:39
176

*This is a summary answer, highlighting the benefits and drawbacks for the different techniques available to preserve spaces following a control word. Conceptually, this is intended for LaTeX implementations where the control word does not accept arguments, expands to simple, possibly formatted, text, and is used primarily in prose.

Background:

The TeX input processor, after building a control sequence consisting of characters with category code = 11 (a control word), switches to state S, which skips characters with category code = 10 (space). Therefore, to preserve spaces following a control word, a character with category code < 10 or category code > 11 must be used between the control word and the following space. This the essence of the first five options below. The sixth option works after the input processor and adds a space depending on the following token.

Evaluation Criteria:

The question defines a single basis for comparison:

  1. Minimize the number of additional characters beyond the baseline control word (\arnold as an example).

Brevity should not be the only factor considered. Qualitative characteristics are also important. For example, does the approach:

  1. Allow for expected trailing spaces to be removed by mistake? In other words, are there valid variants of the control word which would remove an explicit space?
  2. Potentially add unexpected trailing spaces after the control word?
  3. Raise an error if the control word is already defined?
  4. Apply to existing control words (e.g., \LaTeX)?
  5. Enforce consistent use of the control word in the prose? As with (2), are there valid variants of the control word? The desire for consistent use stems from the otherwise reasonable interpretation of a control word as being a direct substitute for the underlying text.
  6. Create unintended consequences/conflicts with other aspects of LaTeX?

As the weight of each point above is subjective and there is no perfect solution, the best approach is largely a matter of personal preference. Factor (1) is listed in the heading of the options while the remaining factors are assessed in Benefits and Drawbacks. Each of the options below have implementations (those "With Check") to satisfy (4) and it is therefore omitted.


Option 1: Add a control space (\␣ = backslash + space) after the control word when a space is desired. Impact: 0 or 1 additional characters.

The "explicit" solution given on page 8 of The TEXbook. This yields a control sequence token (different from the character token which is generated by a space alone) and is therefore retained.

Definition: \newcommand{\arnold}{Arnold Schwarzenegger}

Example uses:

  1. Space after: He yelled ``Get to the choppa!'' in his best \arnold\ impression.
  2. Punctuation after: According to \arnold, it is pronounced Kal-e-four-knee-yah.

Benefits:

  • (3) Does not add unexpected trailing spaces.
  • (5) Applicable to preexisting control words.

Drawbacks:

  • (2) If omitted, trailing spaces will be removed (i.e., best \arnold impression above yields best Arnold Schwarzeneggerimpression).
  • (6) Not consistent usage (i.e., \arnold\ , above yields Arnold Schwarzenegger ,).

Option 2: Add {} after the control word when a space is desired or after each use.

Implementation A: Impact: 0 or 2 additional characters.

As suggested in bluebrother's answer, the { character following the control word in this approach causes the input processor to switch to state M and retain the first following space.

Definition: \newcommand{\arnold}{Arnold Schwarzenegger}

Uses:

  1. Space after: He yelled ``Get to the choppa!'' in his best \arnold{} impression.
  2. Punctuation after:
    • According to \arnold, it is pronounced Kal-e-four-knee-yah.
    • According to \arnold{}, it is pronounced Kal-e-four-knee-yah.

Benefits:

  • (3) Does not add unexpected trailing spaces.
  • (5) Applicable to preexisting control words.

Drawbacks:

  • (2) If omitted, trailing spaces will be removed (i.e., best \arnold impression above yields best Arnold Schwarzeneggerimpression).
  • (6) Not consistent usage (inclusion or omission of {} are both acceptable if followed by punctuation).
  • (7) Unintended consequences/conflicts:

    • Prevents kerning and ligatures with subsequent text if used as part of a word/acronym (see Ulrich Diez's answer).

Implementation B: Impact: 2 additional characters.

Alternative approaches which raise errors if {} does not follow the control word may be found at Drawbacks of csname method to avoid spaces after command.

Definition: Varies

Uses:

  • Space after: He yelled ``Get to the choppa!'' in his best \arnold{} impression.
  • Punctuation after: According to \arnold{}, it is pronounced Kal-e-four-knee-yah.

Benefits:

  • (2) Prevents expected trailing spaces from being removed (error raised if {} is omitted).
  • (3) Does not add unexpected trailing spaces.
  • (6) Use is mostly consistent (error raised if {} is omitted; however, {\relax} will compile).

Drawbacks:

  • (5) Not applicable to existing control words.
  • (7) Unintended consequences/conflicts:

    • Some implementations may prevent kerning and ligatures with subsequent text if used as part of a word/acronym (see Ulrich Diez's answer).

Option 3: Surround the control word in { } when a space is desired or for each use. Impact: 0 or 2 additional characters.

Suggested by Trylks in a comment to bluebrother's answer.

Definition: \newcommand{\arnold}{Arnold Schwarzenegger}

Uses:

  1. Space after: He yelled ``Get to the choppa!'' using his best {\arnold} impression.
  2. Punctuation after:
    • According to \arnold, it is pronounced Kal-e-four-knee-yah.
    • According to {\arnold}, it is pronounced Kal-e-four-knee-yah.

Benefits:

  • (3) Does not add unexpected trailing spaces.
  • (5) Applicable to preexisting control words.

Drawbacks:

  • (2) If omitted, trailing spaces will be removed (i.e., best \arnold impression above yields best Arnold Schwarzeneggerimpression).
  • (6) Not consistent usage (inclusion or omission of { } are both acceptable if followed by punctuation).
  • (7) Unintended consequences/conflicts:

    • Places the command in a group, thereby limiting the non-global effects of that command to that scope (as noted by gernot in the comments below).
    • Prevents kerning and ligatures with subsequent text if used as part of a word/acronym (see Ulrich Diez's answer).

Option 4: Add a non-letter character to the end of the control word in its definition and after each use. Impact: 1 additional character.

A variant on Przemysław Scherwentke's answer (see also lockstep's answer and yo's answer), this is perhaps the "canonical" solution (Page 204 of The TEXbook):

You can use this idea to define macros that are intended to be used in sentences, so that users don't have to worry about the possible disappearance of spaces.

By defining the control word with \def and placing a non-letter character at the beginning of the parameter text, the character will be required. As above, the definition may be wrapped in \@ifdefinable to perform the same check as \newcommand and raise an error if the control word is already defined.

Definition:

Without check: \def\arnold/{Arnold Schwarzenegger}

With check (see the Appendix at the end of this answer for an alternative implementation):

\makeatletter
    \@ifdefinable{\arnold}{\def\arnold/{Arnold Schwarzenegger}}
\makeatother

Uses:

  1. Space after: He yelled ``Get to the choppa!'' using his best \arnold/ impression.
  2. Punctuation after: According to \arnold/, it is pronounced Kal-e-four-knee-yah.

Benefits:

  • (2) Prevents expected trailing spaces from being removed (error raised if / is omitted).
  • (3) Does not add unexpected trailing spaces.
  • (6) Use is consistent (error raised if / is omitted).

Drawbacks:

  • (5) Not applicable to existing control words. Added: The Appendix at the end of this answer provides a means of redefining individual existing control words to follow this convention.

Option 5: Add # at the end of the parameter text in the definition to require { to immediately follow the control word. Impact: 2 or ? additional characters.

By defining the control word with \def and placing # at the end of the parameter text, the control word will have to be followed by an opening brace (page 204 of The TEXbook). A closing brace will also be required to close the group (see gernot's comments below), though, at the time of writing, not all editors correctly parse the warning resulting from its omission. The definition may be wrapped in \@ifdefinable to perform the same check as \newcommand and raise an error if the control word is already defined.

Definition:

Without check: \def\arnold#{Arnold Schwarzenegger}

With check (see the Appendix at the end of this answer for an alternative implementation):

\makeatletter
    \@ifdefinable{\arnold}{\def\arnold#{Arnold Schwarzenegger}}
\makeatother

Uses:

  • Space after:

    • He yelled ``Get to the choppa!'' in his best \arnold{} impression.
    • He yelled ``Get to the choppa!'' in his best \arnold{ }impression.
  • Punctuation after:

    • According to \arnold{}, it is pronounced Kal-e-four-knee-yah.

Benefits:

  • (2) Prevents expected trailing spaces from being removed (error/warning raised if {, {}, or {<anything>} is omitted).
  • (3) Does not add unexpected trailing spaces.

Drawbacks:

  • (5) Not applicable to existing control words. Added: The Appendix at the end of this answer provides a means of redefining individual existing control words to follow this convention.
  • (6) Use is not consistent. The control word may be followed by {} or {<anything>}.

Option 6: Use the xspace package and add \xspace at the end of the definition. Impact: 0* additional characters

This is Uri's answer. The xspace package acts after the input processor and adds a space depending on the token following the control word.

Definition: \newcommand{\arnold}{Arnold Schwarzenegger\xspace}

Uses:

  1. Space after:
    • He yelled ``Get to the choppa!'' in his best \arnold impression.
    • He yelled ``Get to the choppa!'' in his best \arnold{} impression.
    • He yelled ``Get to the choppa!'' in his best \arnold\ impression.
  2. Punctuation after:
    • According to \arnold, it is pronounced Kal-e-four-knee-yah.
    • According to \arnold{}, it is pronounced Kal-e-four-knee-yah.

Benefits:

  • (2) Prevents expected trailing spaces from being removed.

Drawbacks:

  • (3) May add unexpected trailing spaces.
  • (6) Use may not* be consistent.
  • (5) Not applicable to existing control words.

*Ideally, this approach would not require any additional characters any time the control word is used. However, in situations where it fails, a {} is necessary.


Appendix

An interface for adding a required delimiter to an existing parameterless macro producing text only.

\documentclass{article}

\makeatletter
\newcommand\requiredelimiter[2][########]{%
  \ifdefined#2%
    \def\@temp{\def#2#1}%
    \expandafter\@temp\expandafter{#2}%
  \else
    \@latex@error{\noexpand#2undefined}\@ehc
  \fi
}
\@onlypreamble\requiredelimiter
\makeatother

\requiredelimiter{\LaTeX}

\newcommand\arnold{Arnold Schwarzenegger}
\requiredelimiter[/]{\arnold}

\requiredelimiter{\foo} % <---- ERROR

\begin{document}

\LaTeX{} is nice

\arnold/ is strong

\end{document}

Without an optional argument, the (redefined) macro will require a pair of braces after it, like \LaTeX in the example. With the optional argument the specified token(s) will be required instead, like for \arnold in the example.

15
  • 4
    I added an appendix with an interface for (re)defining a macro needing a delimiter. Feel free to remove it if you don't think it fits in your answer.
    – egreg
    Commented Feb 1, 2016 at 10:23
  • 2
    @Guho had a discussion about this in chat a few weeks ago: chat.stackexchange.com/transcript/message/27000774#27000774
    – StrongBad
    Commented Feb 1, 2016 at 20:04
  • 2
    Apparently {} is faster than \ .
    – StrongBad
    Commented Feb 1, 2016 at 20:12
  • 1
    @Guho I usually prefer {}
    – egreg
    Commented Feb 1, 2016 at 20:53
  • 3
    You should mention a serious drawback of option 3, which eliminates it as an option: {\command} leaves only the global effects of \command, the local ones get lost. E.g., surrounding \Huge by braces makes it completely useless.
    – gernot
    Commented Apr 4, 2017 at 9:57
25

This is also an answer to this How to define a macro which does not read the next token after itself? question, hence two variants of definition. * is here a character that will never be a true argument.

\documentclass{article}

\begin{document}

%\newcommand{\ACROeg}{e.\,g.}
\def\ACROe*{e.\,g.}
This is a sample sentence, \ACROe* it does not make much sense.

\def\arnold*{Arnold Schwarzenegger}
\arnold* is a
\end{document}

enter image description here

7
  • Why “prematurely closed”? Don't you think it was a duplicate? Spreading the information across multiple questions is what this site tries to avoid.
    – egreg
    Commented Oct 15, 2014 at 21:52
  • 1
    @egreg There was no time to put there an answer, as we can assume, probably better for OP. Closing duplicates is OK for me but not near immediately. Hence “prematurely closed”. But probably I do not catch customaries of this site correctly. Commented Oct 15, 2014 at 22:01
  • 2
    @PrzemysławScherwentke A duplicate should be closed as soon as possible exactly in order to avoid spreading the information across questions. You had an additional answer? Fine, but this question is the proper place.
    – egreg
    Commented Oct 15, 2014 at 22:16
  • 1
    Interesting, but why is typing \arnold* any shorter than \arnold\ . This also has an issue with already defined macros (\TeX for example). Commented Oct 23, 2014 at 20:54
  • 1
    @PeterGrill It is rather, as mentioned, an answer to the closed question and there \ACROeg and \ACROe* have the same length. Commented Oct 23, 2014 at 21:54
17

Apart from using an empty statement

\hello{} world

You can also use a tilde as an explicit space:

\hello~world

Make sure not to put another space after the tilde, as this will result in two spaces.

1
  • 55
    However, this would make the phrase hello world inseparable end of a line when otherwise LaTeX would put them in separate lines. This may not be the desired behavior. Commented Oct 10, 2012 at 10:45
14

In previous answers it was suggested to always use an empty group like
\arnold{} is an actor or {\arnold} is an actor .

Be aware that with traditional/older TeX-engines (non-XeTeX and non-LuaTeX) empty groups can affect ligatures and kerning.

This might be relevant in case the control sequence in question does expand to something that can be part of a word or part of an acronym:

\documentclass{article}

% Layout --------
\textwidth=\paperwidth
\advance\textwidth-2cm
\oddsidemargin=1cm
\advance\oddsidemargin-1in
\advance\oddsidemargin-\hoffset
\parskip=\baselineskip
\parindent=0pt
% ---------------

\newcommand\UppercaseA{A}

\begin{document}
\Huge

Kerning between A and V not suppressed:\\
\hbox{\UppercaseA} is the first letter of the latin alphabet.\\
\UppercaseA V means Audio/Video.

Kerning between A and V suppressed:\\
\UppercaseA{} is the first letter of the latin alphabet.\\
\UppercaseA{}V means Audio/Video.

Kerning between A and V suppressed:\\
{\UppercaseA} is the first letter of the latin alphabet.\\
{\UppercaseA}V means Audio/Video.

\end{document}

enter image description here

Although this definitely is not shorter, it should be mentioned that the effect on ligatures and kerning can be avoided by not using groups but undelimited macro arguments, i.e., something like \foo{...} with \foo (first of one) being defined as
\newcommand\foo[1]{#1}:

\documentclass{article}

% Layout --------
\textwidth=\paperwidth
\advance\textwidth-2cm
\oddsidemargin=1cm
\advance\oddsidemargin-1in
\advance\oddsidemargin-\hoffset
\parskip=\baselineskip
\parindent=0pt
% ---------------    

\newcommand\UppercaseA{A}
\newcommand\foo[1]{#1}

\begin{document}
\Huge

Kerning between A and V not suppressed:\\
\hbox{\UppercaseA} is the first letter of the latin alphabet.\\
\UppercaseA V means Audio/Video.

Kerning between A and V not suppressed:\\
\foo{\UppercaseA} is the first letter of the latin alphabet.\\    
\foo{\UppercaseA}V means Audio/Video.

Kerning between A and V not suppressed:\\
\UppercaseA\foo{} is the first letter of the latin alphabet.\\        
\UppercaseA\foo{}V means Audio/Video.

\end{document}

enter image description here

The effect of grouping on ligatures and kerning can also be avoided by not using groups but by delimiting the control sequence by a character whereby I suggest not using a character of category code 11 (letter) as using a character of category code 11 (letter) would require an additional space character in the input for separating the control sequence from the delimiter:

\documentclass{article}

% Layout --------
\textwidth=\paperwidth
\advance\textwidth-2cm
\oddsidemargin=1cm
\advance\oddsidemargin-1in
\advance\oddsidemargin-\hoffset
\parskip=\baselineskip
\parindent=0pt
% ---------------

\newcommand\UppercaseA{}
\def\UppercaseA+{A}

\begin{document}
\Huge

Kerning between A and V not suppressed:\\
\UppercaseA+ is the first letter of the latin alphabet.\\
\UppercaseA+V means Audio/Video.

Kerning between A and V suppressed:\\
\UppercaseA+ is the first letter of the latin alphabet.\\
\UppercaseA+{}V means Audio/Video.

\end{document}

enter image description here

1
  • For completeness, there's no kerning suppression in lualatex. (also nice backronym for foo)
    – user202729
    Commented May 27, 2022 at 15:22
8

I do not recommend this, but for the sake of completeness, a macro name with a single non-letter character do not gobble the spaces after the macro:

\documentclass{article}
\def\æ{Arnold Schwarzenegger}
\begin{document}
\æ is an actor.  
\end{document}
11
  • 1
    Note that \@ is a predefined command in LaTeX. There are others to choose from.
    – egreg
    Commented Apr 28, 2015 at 22:09
  • @egreg yes, is not the best example. may be better
    – Fran
    Commented Apr 28, 2015 at 22:17
  • 1
    The edit is even worse. Better a seven bit character
    – egreg
    Commented Apr 28, 2015 at 22:27
  • @egreg Why worse? Because is too similar to \ae ?
    – Fran
    Commented Apr 28, 2015 at 22:33
  • 2
    May be if the string of text is "The unknow man" :)
    – Fran
    Commented Apr 29, 2015 at 7:39
5

This answer is inspired by a comment to the question "How to define a macro for a word?" which for some reason is marked as a duplicate of this question.

From time to time people ask for something like this:

If in the tex-source-code the character-sequence \arnold is trailed by a space-character, in the token-stream the control-word-token \arnold shall be trailed by an explicit space token also.

The problem with this is: (La)TeX's reading-apparatus switches to state S(skipping blanks) after inserting a control-word-token into the token-stream. When (La)TeX in the tex-source-code encounters a space-character (a character of category code 10(space)) while the reading-apparatus is in state S, it will not insert any token (and thus also not an explicit space-token) into the token-stream but will continue reading until finding characters that trigger the insertion of tokens into the token-stream.

Distinguish LaTeX's different stages of processing:

In a prior stage LaTeX does read and tokenize the tex-source-code.
During this stage, so-called tokens, e.g., macro-tokens like \arnold come into being and they get inserted into the token-stream.
During this stage characters contained in the tex-source-code may get discareded without yielding tokens. E.g., space-characters that occur behind character-sequences that yield the insertion of a control-word-token into the token-stream usually get discarded.

The carrying out of a macro-token takes place at a later stage when things already got tokenized.
Thus expanding a macro-token like \arnold does not affect the tex-source-code but does focus on the token-stream/does affect the token-stream.
Macros cannot "fetch" characters of the tex-source-code for "looking ahead". They can only "fetch" tokens from the token-stream for "looking ahead".

At this later stage, the space-characters (these are characters in the tex-source-code, not tokens) that should influence the action triggered by the \arnold-macro may already have been discarded by LaTeX's reading- and tokenizing-apparatus without triggering the insertion of explicit space-tokens into the token-stream.


What you can do is having a macro which does change the category-code of the space to something other than 10 and then looks ahead whether the following token in the token-stream is such a space-character-token with category-code differing from 10.

This works out as long as that following token in the token-stream comes into being due to reading and tokenizing tex-source-code at the time of carrying out that macro.

This does not work out when reading and tokenizing that following token has taken place at some time before carrying out that macro because in this case spaces in the source already got discarded silently.

\documentclass{article}
\makeatletter
\begingroup
\catcode`\ =12\relax%
\catcode`\^^I=12\relax%
% Don't indent the following code!
\catcode\endlinechar=12\relax%
% Each line of the following code must end with a comment-char!
\@firstofone{%
\endgroup%
\newcommand\myckecksourcespace[1]{%
\newcommand\replaceotherspacebynormalspace{}%
\def\replaceotherspacebynormalspace {#1\ignorespaces}%
\newcommand\replaceotherreturnbynormalspace{}%
\def\replaceotherreturnbynormalspace^^M{#1\ignorespaces}%
\newcommand\replaceothertabbynormalspace{}%
\def\replaceothertabbynormalspace^^I{#1\ignorespaces}%
\def\myckecksourcespace{%
\begingroup%
\catcode`\ =12\relax%
\catcode`\^^I=12\relax%
\catcode\endlinechar=12\relax%
\kernel@ifnextchar{ }{\endgroup\replaceotherspacebynormalspace}{%
\kernel@ifnextchar{^^M}{\endgroup\replaceotherreturnbynormalspace}{%
\kernel@ifnextchar{^^I}{\endgroup\replaceothertabbynormalspace}{\endgroup}%
}%
}%
}%
}%
\myckecksourcespace}{ }%
% Now we are back to normal circumstances. ;-)

\makeatother

\begin{document}
\sloppy

\newcommand{\arnold}{Arnold Schwarzenegger\myckecksourcespace}

When \LaTeX{} obtains the token that follows \verb|\arnold|
by reading and tokenizing tex-input/tex-source-code while carrying out
\verb|\arnold|, the \verb|\myckecksourcespace|-mechanism seems to work:

\begin{verbatim}
\noindent\arnold served two terms as the 38th Governor of California.\\
The 38th Governor of California was \arnold.
\end{verbatim}

\noindent\arnold served two terms as the 38th Governor of California.\\
The 38th Governor of California was \arnold.

\noindent\null\hrulefill\null

When the token that follows \verb|\arnold| stems in whatsoever way
from expansion/stems from reading and tokenizing tex-input/tex-source-code
before carrying out \verb|\arnold|, the \verb|\myckecksourcespace|-mechanism
does \textbf{not!} work as this time \LaTeX's reading-and tokenizing-apparatus
discarded space-characters that occurred in the source-code
already at the time of reading and tokenizing the definition/at the time
of reading and tokenizing the entire argument:

\begin{verbatim}
\def\test{%
  \noindent\arnold served two terms as the 38th Governor of California.\\
  The 38th Governor of California was \arnold.
}%
\test
\end{verbatim}

\def\test{%
  \noindent\arnold served two terms as the 38th Governor of California.\\
  The 38th Governor of California was \arnold.
}%
\test

\begin{verbatim}
\@firstofone{%
  \noindent\arnold served two terms as the 38th Governor of California.\\
  The 38th Governor of California was \arnold.
}
\end{verbatim}

\makeatletter
\@firstofone{%
  \noindent\arnold served two terms as the 38th Governor of California.\\
  The 38th Governor of California was \arnold.
}
\makeatother

\begin{verbatim}
\noindent\textbf{\arnold }served two terms as the 38th Governor of California.
\end{verbatim}
\noindent\textbf{\arnold }served two terms as the 38th Governor of California.

\end{document}

enter image description here

1
4

Well, as I didn't saw a related answer compared to mine (except maybe xspace itself), I'll post what I use.

\makeatletter
\def\dynamicSpace{%
    \@ifnextchar ,{}{%
        \@ifnextchar .{}{\ }%
    }%
}%
\makeatother

It's small, easy to expand and adjustable to one's own needs. The only drawback would be that it would become quite ugly after a few nestings. A possible solution would be something that is in effect a @ifnextchar switch

\makeatletter
\def\dynamicSpace{\futurelet \@my@token \@dynamicSpace}
\def\@dynamicSpace{%
    \newif\iftokhit\tokhitfalse%
    \let\cmptok=,\if\@my@token\cmptok\tokhittrue\fi%
    \let\cmptok=.\if\@my@token\cmptok\tokhittrue\fi%
    \let\cmptok=!\if\@my@token\cmptok\tokhittrue\fi%
    \let\cmptok=?\if\@my@token\cmptok\tokhittrue\fi%
    \iftokhit\else\ \fi%
}%
\makeatother

Indent is just for display; You have to remove it to work correctly.

4
  • 1
    I don't think \char` should be there.
    – egreg
    Commented Aug 27, 2017 at 17:02
  • Yeah, you're right. I was mislead by the occassions I used to see if it worked. I figured out smt else.
    – DW.com
    Commented Aug 27, 2017 at 17:39
  • 2
    There's no need for \let\cmptok: \ifx\@my@token, and similar would do; \if would break if a macro follows instead of a character token.
    – egreg
    Commented Aug 27, 2017 at 19:40
  • Whenever \dynamicSpace/\@dynamicSpace gets carried out, \newif\iftokhit gets carried out also. This is not needed. Commented Nov 21, 2019 at 20:07
3

A solution i found convenient when writing is to use an optional argument that is space by default.

\newcommand{\arnold}[1][ ]{Arnold Schwarzenegger#1}

To avoid spacing you can give the next character or nothing as the optional argument.

\arnold is a strong man.\\
\arnold[]is a strong man.\\
\arnold[is] a strong man.

Arnold

1
  • 3
    I don't really find it convenient to require \arnold[.] if you want punctuation to immediately follow the macro, where forgetting the brackets would print an unacceptable space in front of punctuation.
    – egreg
    Commented Jan 13, 2022 at 12:36
2

Here is a solution that probably works for the original question. It will not work in all situations. For example, it is suitable for ordinary flowing text, but not within equations or nested within other macros. Behold:

\documentclass{article}
\makeatletter
% In the following command, all ending percents are mandatory,
% with no space before the percent, and no space at start of each line.
\def\albert{%
Uncle Albert%
\@ifnextchar+{\@gobble}{\typeout{^^JMissing + after \string\albert\space on page \thepage.^^J}}%
}
\makeatother
\begin{document}
My \albert+ is a nice guy.
\end{document}

If the + after the command is missing, then the print will be wrong, but there will be a message in the log file. So, you know there is a problem, and where it is located. Instead of writing a message to the log file, you could make it a warning or even an error, which would require immediate attention.

The + was chosen because it is unlikely to follow someone's name, in flowing text.

Note that if there are spaces both before and after the command, then there may be a double space in the typeset text. But usually, this is less serious than having no space.

result of code

1
  • In some traditions a ‘+’ which represents a cross follows the name of clergy (or in the case of bishops, precedes it. So the Rev. John Firth might sign his name as John+ or his initials as JF+. On becoming a bishop, this would change to +John. While not uncommon in the Episcopal church in the USA, in the UK it would not be typical except, perhaps, in the case of a bishop.
    – Bryan H-M
    Commented Aug 25, 2022 at 18:31
1

You could also define the command to en with an “other” character. As an example

\def\command*{\ensuremath{\frac{i}{2}}}

then you can use \command* is \command*, \command* and \command*.


In a similar situation, with e.g. and i.e. I tend to like this macros:

\makeatletter
\newcommand*\eg{\textit{e.g.}\@ifnextchar.{\@gobble}{}}
\newcommand*\ie{\textit{i.e.}\@ifnextchar.{\@gobble}{}}
\makeatother

That way, you can use easily \eg, this without problem, and in the case that you don't want a comma following the macro, rather than using \eg{} this you can put a dot, \ie. this.

1
  • 1
    I wouldn’t use the * for this purpose since its quite often used for a variant of \command. I use /for this …
    – Tobi
    Commented Mar 29, 2017 at 10:00

You must log in to answer this question.

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