27

Using \@ifnextchar one can detect if e.g. the next Character is a [, e.g.:

\@ifnextchar[%
{
    %% code to execute if [ scanned.
}{
    %% code to execute if [ scanned.
}

However, I can’t seem to use \@ifnextchar{ to test if the next Character is {.

Is there any way to use \@ifnextchar to detect a {?

Is there any way at all to detect a {?

If so, please let me know.


Update 1: Okay, I think that \bgroup is a successful Answer. I think I know now (sort of) why it didn’t work when I first used it.

The Purpose I needed it for was to be able to have a Macro that can take an indefinite Number of Arguments. (E.g. listing out Authors.) These seems to run into issues once we want to place the resulting String in an Header.


Update 2: Regarding my secondary Problem (which was my original Application for all of this), is there a way to delay Commands in TeX. In particular, I want to first run a Macro which waits for an arbitrary Amount of Arguments, then run a second Command on this.

Here is the kind of thing I’m trying to do:

\def\headerauth#1{\rhead{#1\ifnextchar\bgroup{\@headerauth}{.}}}

\def\@headerauth#1{\& #1\ifnextchar\bgroup{\@headerauth}{.}}}

Without the \rhead, Things work fine. But once I use \rhead, it will only read the first Argument. The others are ignored. E.g.

\headerauth{S. Mishkin}{L. Polotov}

results in »S. Mishkin.« being placed in the Header, and »L. Polotov« placed in the main Text.

Whereas if I define \headerauth omitting the \rhead, and then use:

\rhead{\headerauth{S. Mishkin}{L. Polotov}}

I obtain »S. Mishkin & L. Polotov.« in the Header as desired.

Why doesn’t the first Thing work? (I realise that this Question probably belongs to a new Topic…)

P.s. *@doncherry* & @Yossi Farjoun: I’ve figured it out — turns out I was using the wrong Key Combination to access the ` Symbol on my Keyboard. (The same Key produces `'˚´ depending on Key Combinations.) (Took me a short while to figure out how to quote-not-use the Symbol ` (as well as \) via \` and \\ — ah, the Standard coding Tricks. Glad to see it’s very logical.)

27
\@ifnextchar\bgroup

See the definition of \input in the kernel:

\def\input{\@ifnextchar\bgroup\@iinput\@@input}

where \@iinput is able to cope with \input{file} and \@@input is an alias for the primitive \input so \input file will be processed as well.

\@ifnextchar has three arguments: (1) the token to be looked for, (2) what to do if it's found, and (3) what to do if the token is not there. After storing the arguments, it makes TeX look at the following token (not argument) and compares it (with \ifx) to the stored first argument. In case #1 is \bgroup it compares successfully to an open brace because of the statement given in the kernel

\let\bgroup={

This doesn't mean that \bgroup can be always used as a substitute for an open brace; it's allowed for this purpose only in some particular cases. This is exploited, for instance, in the definition of minipage or lrbox. For comparison purposes, \bgroup is the right substitute of {, as it can be seen by TeX as an argument for a macro.

Suppose we want to do something different when macro \xyz is followed by an open brace or not; say we want to support the syntaxes

\xyz{abc}
\xyz abc\stopxyz

using abc as the argument. Then we would do

\newcommand{\xyz}{\@ifnextchar\bgroup\@xyzb\@xyz}
\def\@xyz#1\stopxyz{\@xyzb{#1}}
\def\@xyzb#1{do something with #1}

This can also be used to define a macro with an "unknown" number of arguments, say a list of authors to go in the header:

\def\authorslist{\ignorespaces} % initialization
\def\authors#1{\g@addto@macro\authorslist{ #1}\@ifnextchar\bgroup\authors{}}

\fancyhead[R]{\authorslist}

The macro \authors appends its argument to the list (initialized so as to ignore the space before the first author) and then execute again itself until there's not a brace any more (when it does nothing).

  • 7
    Here, \bgroup is an 'implicit' token. It's a copy of {, but as it is not { does not count toward the number of braces used in the 'container' macro, so can be used in places where { cannot. Also, \@ifnextchar needs to be able to absorb the search token as an argument, which again requires that you don't use a literal {. – Joseph Wright Nov 2 '11 at 14:20
  • I tried \bgroup, but yield no luck. I used '\def\test#1{#1 \@ifnextchar\bgroup{yes}{no}} '\test{first}{second} which outputs: 'first no – R47 Nov 2 '11 at 14:22
  • @R47 See edited answer – egreg Nov 2 '11 at 14:29
  • Okay, that one works now: I had made some other mistake. But I still cannot yield any success with the following: '\def\authors#1{\fancyhead[R]{#1 \@ifnextchar\bgroup{\@einmehr}{}}} '\def\@einmehr#1{\& #1 \@ifnextchar\bgroup{\@einmehr}{}}} – R47 Nov 2 '11 at 14:32
  • 1
    @R47 Please, edit your original question instead of putting code in comments. – egreg Nov 2 '11 at 14:34

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.