Take the 2-minute tour ×
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.

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}
share|improve this question
2  
Can you elaborate on your edit? What's your problem with it? –  Psirus Dec 19 '11 at 14:12
add comment

3 Answers

up vote 10 down vote accepted

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".

share|improve this answer
add comment

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.

share|improve this answer
add comment

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}
share|improve this answer
add comment

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.