\environment texit-style \startcomponent texit-lookahead \startchapter[title={Lookahead}] When you look at the \TEX\ source of a macro package, your can often see constructs like this: \startTEX \def\foo#1% {We do something with "#1".} \stopTEX or maybe: \startTEX \def\foo#1{% We do something with "#1".% } \stopTEX Normally the percentage symbol is used to indicate a comment, but here are no comments. In these cases, it makes the definition effectively \startTEX \def\foo#1{do something with "#1"!} \stopTEX which is different from when we would not have that percent sign there: \startTEX \def\foo#1 {We do something with "#1"!} \stopTEX That variant is valid \TEX\ code but expects a space as delimiter of the argument to \type {\foo}. This means that you can say: \startTEX \foo{1} \foo 2 \foo {34} and \foo 56 . \stopTEX while this can trigger an error message (when no space is seen at some point) or at least give unexpected results. \startTEX \foo{1}\foo 2\foo {34}and\foo 56. \stopTEX A different use of the percent is seen in cases like this: \startTEX \def\foo#1% {We do something % with "#1".} \stopTEX This time we want to preserve the space after \type {something} because an end|-|of|-|line would either or not collapse it with \type {with} depending on how the endofline character is set up. Normally \startTEX \def\foo#1% {We do something with "#1".} \stopTEX will also add a space after something but when \TEX\ is set up to ignore lines you get a collapse. So the explicit space is a robust way out. Both cases of using or omitting the comment symbol are easy to spot as they trigger an error or result in weird typeset results. \startbuffer[defs] \def\fooA#1% {\ifnum#1>100 yes\else nop% \fi} \def\fooB#1{\ifnum#1>100 yes\else nop \fi} \def\fooC#1% {\ifnum#1>100% yes\else nop% \fi} \stopbuffer \typebuffer[defs][option=TEX] \getbuffer[defs] We test this with: \startbuffer[demo] \fooA{100} \fooB{100} \fooC{100} \fooA{101} \fooB{101} \fooC{101} \stopbuffer \typebuffer[demo][option=TEX] And the result is probably what you expect: \startlines \getbuffer[demo] \stoplines \startbuffer[defs] \def\fooA#1% {\ifnum#1>100 1\else 0% \fi} \def\fooB#1{\ifnum#1>100 1\else 0\fi} \def\fooC#1% {\ifnum#1>100% 1\else 0% \fi} \stopbuffer However, when we have the following macro body: \typebuffer[defs][option=TEX] \getbuffer[defs] We get this output. Do you see the issue? \startlines \getbuffer[demo] \stoplines A preferred way to catch this is the following as a \type {\relax} ends scanning for a number: \startbuffer[defs] \def\foo#1% {\ifnum#1>100\relax 1\else 0% \fi} \stopbuffer \typebuffer[defs][option=TEX] \getbuffer[defs] However, watch what happens here: \startbuffer[demo] \edef\result{\foo{123}} \stopbuffer \typebuffer[demo][option=TEX] \getbuffer[demo] The \type {\result} macro has the following body: \expanded{\setbuffer[result]\meaning\result\endbuffer} \typebuffer[result][option=TEX] A neat trick out of this is the following: \startbuffer[defs] \def\foo#1% {\ifnum#1>\numexpr100\relax 1\else 0% \fi} \stopbuffer \typebuffer[defs][option=TEX] \getbuffer[defs] \getbuffer[demo] Now the body of \type {\result} looks like this: \expanded{\setbuffer[result]\meaning\result\endbuffer} \typebuffer[result][option=TEX] Of course this also works: \startTEX \def\foo#1% {\ifnum#1>100 % 1\else 0% \fi} \stopTEX as a space also delimits scanning the number. But that method can actually introduce that space in the output. Think of this definition: \startbuffer[defs] \def\foo#1#2% {\ifnum#1>#2 % 1\else 0% \fi} \stopbuffer \typebuffer[defs][option=TEX] \getbuffer[defs] What if \type {#2} has a trailing space? What if it is a verbose number? What if it is a counter variable? \startbuffer[demo] \scratchcounter=100 [\foo{101}{100}] [\foo{101}{100 }] [\foo{101}\scratchcounter] \scratchcounter=101 [\foo{100}{101}] [\foo{100}{101 }] [\foo{100}\scratchcounter] \stopbuffer \typebuffer[demo][option=TEX] \startlines \getbuffer[demo] \stoplines If you really want to introduce an unpredictable situation, use a coding style like this: \startTEX \def\foo#1#2#3#4{\if#1=#2#3\else#4\fi} \stopTEX This is not that imaginary as you often see users play safe and do things like this: \startTEX \ifnum\scratchcounterone=\scratchcountertwo% ... \else ... \fi \stopTEX Here the percent sign is useless as the number scanner already got the number, just try: \startTEX \scratchcounterone=1 \scratchcountertwo=1 \ifnum\scratchcounterone=\scratchcountertwo yes \else nop \fi \stopTEX A previous one liner formatted like this really is not better! \startTEX \def\foo#1#2#3#4% {\ifnum#1=#2% #3% \else #4% \fi} \stopTEX When you define macros more often than not you don't want unexpected spaces (aka spurious spaces) which is why in \CONTEXT\ for instance setups ignores lines: \startbuffer[defs] \startsetups foo here we ignore spaces at the end of a line \stopsetups \stopbuffer \typebuffer[defs][option=TEX] \getbuffer[defs] so we get: \quotation {\directsetup{foo}} which means that the normally few times that we {\em do} want spaces we need to be explicit: \startbuffer[defs] \startsetups foo here\space we ignore\space spaces at the end\space of a line\space \stopsetups \stopbuffer \typebuffer[defs][option=TEX] \getbuffer[defs] Now we're okay: \quotation {\directsetup{foo}}. The same is true for: \startTEX \starttexdefinition foo here\space we ignore\space spaces at the end\space of a line\space \stoptexdefinition \stopTEX There are more cases where \TEX\ will look further. Take for example skip (glue) scanning. A glue specification can have \type {plus} and \type {minus} fields. \startbuffer[defs] \scratchdimenone=10pt \scratchskipone =10pt plus 10pt minus 10pt \scratchskiptwo =0pt \stopbuffer \typebuffer[defs][option=TEX] Now take the following test: \startbuffer[demo] {1 \scratchskiptwo 10pt plus 10pt \relax\the\scratchskiptwo} {2 \scratchskiptwo \scratchdimenone plus 10pt \relax\the\scratchskiptwo} {3 \scratchskiptwo 1\scratchdimenone plus 10pt \relax\the\scratchskiptwo} {4 \scratchskiptwo \scratchskipone plus 10pt \relax\the\scratchskiptwo} {5 \scratchskiptwo 1\scratchskipone plus 10pt \relax\the\scratchskiptwo} \stopbuffer \typebuffer[demo][option=TEX] \startlines \inlinebuffer[defs]\getbuffer[demo] \stoplines If you wonder what the second \type {\relax} does, here is a variant: \startlines {1 \scratchskiptwo 10pt plus 10pt \the\scratchskiptwo} {2 \scratchskiptwo \scratchdimenone plus 10pt \the\scratchskiptwo} {3 \scratchskiptwo 1\scratchdimenone plus 10pt \the\scratchskiptwo} {4 \scratchskiptwo \scratchskipone plus 10pt \the\scratchskiptwo} {5 \scratchskiptwo 1\scratchskipone plus 10pt \the\scratchskiptwo} \stoplines \typebuffer[demo][option=TEX] \startlines \inlinebuffer[defs]\getbuffer[demo] \stoplines In this second variant \TEX\ happily keep looking for a glue specification when it sees the \type {\the} so it serializes \type {\scratchskiptwo}. But as it sees \type {0pt} then, it stops scanning the glue spec. What we get typeset is the old value, not the new one! If you want to prevent this you need to \type {\relax}. Another case where \TEX\ keeps scanning is the following: \startbuffer[demo] \vrule width 40pt height 2pt depth 5pt \quad \vrule width 40pt height 20pt depth 5pt height 10pt \quad \vrule width 40pt height 10pt height 20pt \quad \vrule width 40pt height 20pt depth 5pt height 10pt width 80pt \stopbuffer \typebuffer[demo][option=TEX] This gives the rules: \startlinecorrection \darkgray \getbuffer[demo] \stoplinecorrection So you can overload dimensions. The space before the \type {quad} is gobbled as part of the look ahead for more keywords. Often rules (just like glue assignments) are wrapped in macro definitions where the macro writer used \type {\relax} to look ahead. That way you prevent an error message in cases like: \startTEX \def\foo{\vrule width 40pt height 2pt} The \foo depth of this thought is amazing. \stopTEX because \type {of} definitely is not a valid dimension. Even more subtle is: \startTEX \def\foo{\hskip 10pt plus 1fil} The \foo fine points of typesetting can actually become a nightmare. \stopTEX As \TEX\ will now see the \type {f} of \type {fine} as further specification and think that you want \type {1fill}. So, the most important lesson of this chapter is that you need to be aware of the way \TEX\ scans for quantities and specifications. In most cases the users can safely use a \type {\relax} to prevent a lookahead. And try to avoid adding percent signs all over the place. \stopchapter \stopcomponent