2

According to item 0.2 of the xparse documentation: "TEX will find the first argument after a function name irrespective of any intervening spaces." Examples are provided, which I understand.

I am trying to create a simple macro that has no mandatory argument, but one optional argument. The text in the optional argument will be ignored. It is a non-printing memo to myself. Like this:

\DeclareDocumentCommand \printfive {O{}} {5}

Then, in the document body:

Two plus three make \printfive.
Two plus three make \printfive[last time I counted fingers].
Two plus three make \printfive [last time I counted fingers].

What I want is: The first and second should print "Two plus three make 5." The third should print "Two plus three make 5 [last time I counted fingers]." In other words, I want the macro to notice whether or not it is immediately followed by [ (without space), and behave differently.

Is this possible? I had no luck trying \@ifnextchar.

I use LuaLaTeX.

Possibly related: Behavior of xparse and "token"-type argument which I do not quite grasp.

  • 1
    The answer is 'no': would that plus some explanation suffice? – Joseph Wright Nov 28 '17 at 17:07
  • There is no space after \printfive in the third case. You see one in the typescript, but it doesn't go through the input phase. As far as TeX is concerned, cases 2 and 3 are completely identical. – egreg Nov 28 '17 at 17:10
  • @JosephWright - I can take "no" for an answer. The xparse documentation does provide an explanation, but I was not sure if that was a feature that could be turned off somehow. – user139954 Nov 28 '17 at 17:19
  • @egreg - Unfortunately, that means I cannot get what I seek. – user139954 Nov 28 '17 at 17:19
1

The rules under which TeX reads input from a text file have the consequence that there is no space in

\foo [x]

The input is seven character long, but, as far as TeX is concerned, it is four tokens:

\foo•[•x•]

(here is used for dividing tokens from each other, for expository purposes, and not part of what TeX “sees”). The space gets already ignored and discarded during the phase when the text input is transformed into tokens and there is no way to distinguish between the inputs

\foo[x]
\foo [x]

For all purposes they are perfectly equivalent. Well, barring devious tricks that are described in comments below, but that wouldn't help much in your situation.

You could trick TeX into “seeing” the space by saying \obeyspaces and then checking whether \foo is followed by an active space character (which wouldn't get ignored). However this has some consequences:

  1. consecutive spaces in the input would be honored, so a b would result in a double interword space between “a” and “b”;

  2. spaces would not get ignored at the beginning of lines (no code indentation allowed).

Not really a feasible option, I guess you agree.

You could distinguish instead between

\printfive[last time I counted fingers]

and

\printfive-[last time I counted fingers]

by doing

\NewDocumentCommand{\printfive}{t-}{%
  \IfBooleanTF{#1}
    {Whatever you want to do if - follows}
    {\printfivewithoption}%
}
\NewDocumentCommand{\printfivewithoption}{O{default}}{%
  <whatever you want to do with #1>%
}

I can't recommend using \DeclareDocumentCommand, because this will override existing commands without warning.

  • That's all I need to know. My usage is in a very limited context (no code, so no code indentation problem). So, I may be able to use your solution. As for \DeclareDocumentCommand I am working with a limited number of packages, so over-writing existing macros is no problem. The main reason I use \DeclareDocumentCommand is that it gives my inner dictator a sense of power! – user139954 Nov 28 '17 at 18:35
  • @RobtAll Try \DeclareDocumentCommand{\box}{m}{whatever} 😉 – egreg Nov 28 '17 at 18:37
  • \box does not obey. Off with its head! 😉 – user139954 Nov 28 '17 at 18:45
  • It is slightly misleading to say that \foo [x] and \foo[x] are completely equivalent: it is possible that \foo itself makes the space \active. Now, of course if this happens inside a macro argument, no change, but at top level in tex document, this is a change and will change output. \def\foo{\catcode32\active}, {\catcode32\active\gdef {ZAZA}}, {\foo [X]} vs {\foo[X]}. \bye – user4686 Nov 28 '17 at 22:17
  • @jfbu Added a comment about “devious tricks”. ;-) – egreg Nov 28 '17 at 22:47

Your Answer

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