# Detect whether there's space before and after macro

My document has a custom macro called

\newcommand{\myparenthetical}[1]{[#1]}


However, I want to be sure that in the document I always have a single space before and after the macro.

I would like

This\myparenthetical{9}is a\myparenthetical{10} test.


to appear as

This [9] is a [10] test.

not as

This[9]is a[10] test.

How would I do this with a macro?

• Try \newcommand{\myparenthetical}[1]{ [#1] } but you'll get problem with periods: foo\myparenthetical{10}. – Sigur Apr 28 '15 at 14:22
• If you want spaces, add them when typing in the document. I'm not sure what would be the purpose of using bad input for fixing it later. What if punctuation follows? There would be too many case to distinguish. – egreg Apr 28 '15 at 14:27
• you'd also need to detect the beginning of a paragraph, in the (probably vanishingly small) case where \myparenthetical comes as the first thing. really, keying a space before is more trustworthy. – barbara beeton Apr 28 '15 at 15:08
• Since you have some responses below that seem to answer your question, please consider marking one of them as ‘Accepted’ by clicking on the tickmark below their vote count (see How do you accept an answer?). This shows which answer helped you most, and it assigns reputation points to the author of the answer (and to you!). It's part of this site's idea to identify good questions and answers through upvotes and acceptance of answers. – user36296 Oct 24 '16 at 19:00

\unskip removes previous space. Depending on the mode this is horizontal or vertical space. Spaces after the command can be ignored by \ignorespaces. A space token can be set by \space and \@ifnextchar tests for following tokens to avoid space setting, if a punctuation character follows. As side effect it also removes following spaces.

Full example:

\documentclass{article}

\makeatletter
\newcommand*{\myparenthetical}[1]{%
\ifhmode
\unskip
\space
\fi
[#1]%
\@ifnextchar{.}{}{%
\@ifnextchar{,}{}{%
\@ifnextchar{;}{}{%
\@ifnextchar{!}{}{%
\@ifnextchar{?}{}{%
\@ifnextchar{)}{}{%
\@ifnextchar\par{}{%
\space
\ignorespaces
}}}}}}}%
}

\begin{document}
\myparenthetical{1} starts a sencents and ends it \myparenthetical{2}.
\myparenthetical{3}Lorem ipsum\myparenthetical{4} ,\myparenthetical{5}.

This\myparenthetical{6}is \myparenthetical{7} a\myparenthetical{8} test.
\end{document}


## Simplification

The example can be simplified by using package xspace, thanks Barbara. However, \xspace cannot be used directly, because it is intended for macros without arguments. Then the scanning for the macro name would swallow the next space. But \xspace is fine for punctuation detection. Thus the following space can be gobbled by the following \romannumeral trick, where the space is consumed by the character constant and the resulted negative number is then removed by \romannumeral:

\documentclass{article}

\usepackage{xspace}

\makeatletter
\newcommand*{\myparenthetical}[1]{%
\ifhmode
\unskip
\space
\fi
[#1]%
\expandafter\xspace\romannumeral-\x
}

\begin{document}
\myparenthetical{1} starts a sencents and ends it \myparenthetical{2}.
\myparenthetical{3}Lorem ipsum\myparenthetical{4} ,\myparenthetical{5}.

This\myparenthetical{6}is \myparenthetical{7} a\myparenthetical{8} test.
\end{document}

• how does this differ from \xspace for the following space? – barbara beeton Apr 28 '15 at 15:05
• @barbarabeeton Good hint, I have updated the answer. The difference in the normal use case of \xspace is that \myparenthetical has an argument, thus that the space afterwards is not ignored. – Heiko Oberdiek Apr 28 '15 at 15:13
• thanks, but I'm getting some strange behavior when coupling this with svmono.cls style sheet. For example, your \xspace solution has a trailing "x" after each parenthetical, e.g.: [123]x – Geremia Apr 28 '15 at 15:40
• @Geremia Probably a copy & paste error. The characters after \romannumeral are - (hyphen, U+002D), back tick (U+0060), backslash (U+005C) and the letter x (U+0078). Another way of breaking is inside moving arguments, the command is not robust. It can be fixed by using \DeclareRobustCommand instead of \newcommand`. – Heiko Oberdiek Apr 28 '15 at 17:21