I would like to have a macro, let's call it \csword, that reads the next word in the input (i.e. sequence of letters a-zA-Z), and then executes that word as a macro. For example

\csword command
\csword command[and]{arguments}

should expand to something like


Following \csword by anything other than a letter should, say, throw an error.

In case I'm just too focused and trying to solve things the wrong way, this is the bigger picture of what I actually want to do. I want to define a macro which receives a number of options as a comma separated list. These options, however, might further receive some arguments or even optional arguments. In other words, I'm trying to turn

\myfancycommand{optionA, optionB[with]{args}, optionC{fun}, optionA}

Roughly into something like


By the way, and this is important, I should be able to repeat “options” and their order of execution matters.


Assuming @ is a letter:

\def\@@csword{\ifcat a\noexpand\next

Edit: Removed a \expandafter from line 3. It is unnecessary, and causes the macro to fail in cases like \csword foo\bar.


I would use one of the keyval-packages (keyval, xkeyval, pgfkeys ...) and define keys optionA etc so that you can use them like this:

 \myfancycommand{optionA, optionB=[with]{args}, optionC={fun}}
  • Thanks for the suggestion. I thought about that, but the = doesn't make a lot of sense (semantically) in my command so I would love to be able to get rid of it. Anyway, if there isn't anything better I might go with this option in the end. Oct 19 '10 at 14:17
  • Well keyval et al simplify things a lot as it has the parser for the comma-list encluded, removes spaces, protects the argument and so on. I don't think that it is worse the time to rewrite all these things for a small change of syntax. Also you shouldn't forget that people are used to key=value syntax. Oct 19 '10 at 14:41

On the off-chance that you'd like this to be expandable, here's another expl3 version. While this is longer than Harald's, I actually think it's more readable. On second thoughts: no, I think I'm just thinking that because I just wrote it :)

Slight downside: commands like f{o}o are executed as if they were foo. Which also means you can't have something like foo{A}, unfortunately. But foo{abc} is okay. Also, spaces mean nothing: foo foo is processed as \foofoo.


\cs_new:Npn \csword #1 {
  \cs:w \csword_aux:n #1
\cs_new:Nn \csword_aux:n {
  \tl_if_empty:nTF {#1}
  { \cs_end: } % e.g., '{}' in 'foo{}': end scanning
    \tl_if_single:nTF {#1}
      % e.g., 'o' in 'foo' or '{A}' in 'foo{A}' or '[' in 'foo[a]':
      \token_if_letter:NTF #1
      { #1 \csword_aux:n } % e.g., 'o' in 'foo'         : keep scanning
      { \cs_end: #1 }      % e.g., '[' in 'foo[a]'      : end scanning
    { \cs_end: {#1} }      % e.g., '{abc}' in 'foo{abc}': end scanning


\newcommand\foo[1][opt]{[foo: #1]}
\newcommand\baz[2][opt]{[baz: #1/#2]}

\csword foo
\csword f{o}o
\csword foo{A}
\csword foo{ABC}
\csword foo[1]
\csword baz{2}
\csword baz{22}
\csword baz[333]{222}


I just bench-marked this against Harald's solution, and it's five times slower. So it's really of academic use only :)

  • Hmm, interesting. I'll put expl3 on the list of stuff to learn some day. I could have made mine expandable too, but I decided against it because the shortcomings you mention are unavoidable then. I wonder though, if it could be done better with luatex? (Another item on my to-learn list …) Oct 20 '10 at 7:23

Here is an expl3 variant of Harald's solution:


\tl_new:N \l_csword_tl
\cs_new_protected_nopar:Npn \csword_aux_i: {
  \peek_catcode:NTF \c_letter_token {
  } {
    \use:c { \l_csword_tl }
\cs_new_protected_nopar:Npn \csword_aux_ii:N #1 {
  \tl_put_right:Nn \l_csword_tl { #1 }
\NewDocumentCommand \csword { } {
  \tl_clear:N \l_csword_tl
  • I think it's slightly nicer to put the aux_ii macro inline in the original T branch? (One of the advantages of the TF syntax.) Also, since \csword is already \protected usually I just stick with \cs_new:Npn for readability — but Joseph and I differ on that point ;) Oct 20 '10 at 5:32
  • @Will Robertson "I think it's slightly nicer to put the aux_ii macro inline in the original T branch?" How should that be possible?
    – Philipp
    Oct 20 '10 at 7:03
  • Uh, it wouldn't be! Forget I said anything :) Oct 20 '10 at 7:07

ConTeXt has a macro \dowithwargument to work with word (w for word) arguments and \dowithpargument to work with par (p for par) arguments. However, it considers a word to be anything delimited by a space. So, if you are willing to type your arguments as

\csword optionA
\csword optionB [and]{argument} % Note the space after optionB

then you can define \csword as


Edit: Another option is to capture the space delimited phrase with \dowithwargument and then use LuaTeX to add a \ in front. So

  • I was going to suggest this with \def\csword #1 {\csname #1\endcsname} but decided the restrictions on the syntax were a bit limiting. Oct 20 '10 at 6:12
  • Agreed. For completeness, \dowithwargument (and similarly \dowithpargument) works with both a word argument and a brace delimited argument; so both \csword optionA and \csword{optionA} work. That is a completely different use case then what the OP is looking for.
    – Aditya
    Oct 20 '10 at 15:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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