5

What means the following extract on page 46 of TeXbook?

TeX goes into state S in case (c), or in case (b) with respect to a character of category 10 (space)

Does it mean that space must be skipped in case (b)? If yes, why the following example shows contrary?

\chardef\x=`\%

\% a % case (b) - not skipped

\x a % case (c) - skipped

\bye

Also, does the "with respect to a character of category 10 (space)" part relate to "case (b)" only, or to both?


This is the full paragraph:

If TeX sees an escape character (category 0) in any state, it scans the entire control sequence name as follows. (a) If there are no more characters in the line, the name is empty (like \csname\endcsname). Otherwise (b) if the next character is not of category 11 (letter), the name consists of that single symbol. Otherwise (c) the name consists of all letters beginning with the current one and ending just before the first nonletter, or at the end of the line. This name becomes a control sequence token. TeX goes into state S in case (c), or in case (b) with respect to a character of category 10 (space); otherwise TeX goes into state M.

  • 1
    Spaces are not skipped for single non-letter characters (e.g. \%). However, TeX will skip spaces after \ , otherwise you'd end up with two consecutive spaces. – Henri Menke May 21 at 6:37
  • Note that whatever way \x is defined (even if it is undefined), spaces would be skipped after it (assuming that x still has category code 12). At this stage, only the characters and their category codes are taken into account; expansion and execution take place later, when tokens have been formed. – egreg May 21 at 8:46
  • @egreg I did not understand the "still has category code 12" part. – Igor Liferenko May 21 at 9:15
  • @IgorLiferenko Sorry, typo: I meant “category code 11”. – egreg May 21 at 9:18
4

For a different perspective: the paragraph is an attempt to explain section 354 of the TeX program, and the part about the state is the blue rectangle below (the included sections 356 and 355 happen not to affect state):

section 354 of TeX

So what it means is that if the character immediately after the escape character is either a letter, or a space [this is what is written in the TeXbook as “case (c)” and as “case (b) with respect to a character of category 10 (space)” respectively], then TeX goes into the skip_blanks state, else it goes into the mid_line state.

Because of the tangled evolutionary history of TeX and The TeXbook (my understanding is that first TeX was written, then a manual was written explaining it, then TeX was completely rewritten in such a way that the manual didn't change much(!), then the manual continued to be tweaked to account for tweaks to TeX), it can sometimes be easier (IMO) to understand some aspect of TeX by just reading the code than to read the TeXbook.


Appendix: If you find the image hard to read, here is the section again, taking the code from tex.web and reformatting it a little and putting the labels in uppercase:

  @<Scan a control...@>=
  begin
      if loc > limit then
          cur_cs := null_cs {|state| is irrelevant in this case}
      else
          begin
START_CS:
              k := loc;
              cur_chr := buffer[k];
              cat := cat_code(cur_chr);
              incr(k);
              if cat = letter then
                  state := skip_blanks
              else if cat = spacer then
                  state := skip_blanks
              else
                  state := mid_line;
              if (cat = letter) and (k <= limit) then
                  @<Scan ahead in the buffer until finding a nonletter; if an expanded code is encountered, reduce it and |goto START_CS|; otherwise if a multiletter control sequence is found, adjust |cur_cs| and |loc|, and |goto FOUND|@>
              else
                  @<If an expanded code is present, reduce it and |goto START_CS|@>;
              cur_cs := single_base + buffer[loc];
              incr(loc);
          end;
FOUND:
      cur_cmd := eq_type(cur_cs); cur_chr := equiv(cur_cs);
      if cur_cmd >= outer_call then
          check_outer_validity;
  end
  • +1 it's a shame you didn't steal the tick earlier, I just missed a 505505 palindrome because of an unfortunate "accept" just at the wrong moment:-) – David Carlisle May 22 at 7:07
  • @DavidCarlisle Ah... I guess 506605 or some later one won't be too far off :-) – ShreevatsaR May 22 at 21:34
9

in case (c), or in case (b) with respect to a character of category 10 (space);

means the cases that the character after \ is a letter (case c) or the character after \ is a space (case b (non-letter) in the case that it is a space)

So in those cases the following space is skipped,

In other cases (non-letter, non-space) then the space is not skipped.

So, a \<space> acts as case b (non letter) in that only one character is considered part of the name, but it acts like case c (letter) in that following spaces are skipped.

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.