# How to make spaces as command argument delimiters?

How to make spaces as command argument delimiters?

\documentclass{article}
\newcommand\foo[2]{#1 and #2.}
\begin{document}
\foo hi you
\end{document}


The expected output is

hi and you.

Of course I don't want to enclose the arguments with curly braces.

The following is not what I am looking for.

\documentclass{article}
\def\foo #1 #2 {#1 and #2.}
\begin{document}
\foo hi you
\end{document}

-
Can you elaborate on your edit? What's your problem with it? – Psirus Dec 19 '11 at 14:12

You can't do this with \newcommand. But it's possible with \def:

\def\foo #1 #2 {#1 and #2. }


Now \foo x y Something will give the expected result. However this will break in cases such as

\foo me you

Something after a blank line


because there's no space after you (the end-of-line counts as a space only if not followed by another end-of-line, when they are transformed into \par).

You can look in the TeXbook or in TeX by Topic for "delimited arguments".

-

You have to use \def which handles input as written:

\def\foo#1 #2 {#1 and #2}


Notice the extra space between #1 and #2, and after. This means that you can also write:

\foo{hi you} {you too}


However this is not a good way of writing commands.
What if the writer misses the last space. LaTeX will then search until a space is found... However if you define:

\def\foo#1 #2{#1 and #2}


No space after #2 you will find that the second token argument will only be the first token (in your case y, NOT ou).

A better solution would be to specify the end of the command with a punctuation or whatever.

\def\foo#1 #2.{#1 and #2}


Which is called as \foo hi you.. This lets you not need a brace structure around the last argument.

-

This should do what you want. It requires that you type one (and only one) space between "me" and "you", and that the second argument ("you") be followed by a newline or some number of spaces. You could expand the tests in \more so it stops picking up tokens when a space, non-letter, non-other, or \par token are seen; right now, it will pick up everything until it sees a space or \par after the second argument. I cribbed the \begingroup\lccode =* \lowercase{\endgroup\let\sp= } portion from the TexBook, Appendix D ("Dirty Tricks") where he shows how to create "funny" spaces.

\documentclass{article}
\begingroup\lccode =* \lowercase{\endgroup\let\sp= }
\newtoks\after
\def\foo#1 #2{%%
\def\test{\afterassignment\more\let\next= }%%
\def\more{\after={\next}\ifx\next\sp%%
\else%%
\ifx\next\par%%
\else\after={\next\test}%%
\fi%%
\fi\the\after}%%
#1 and #2\test%%
}
\begin{document}
\foo hi you

\foo hi you!

\foo hi you \foo hi you

\foo hi you                        hello.

\end{document}

-