7

I am currently reading through the TeXbook (6th printing, March 1986).

In chapter 6 Knuth explains that \input story can be used to load/process story.tex.

However, in the preceding chapter the reader learns the importance of grouping by giving the example of:

\centerline{This information should be {centered}.}

\centerline So should this.

Which shows the point that only the subsequent symbol to \centerline is being used and so for the second \centerline the S will be centered but o should this. will be on a new line, not centered.

So I was wondering why \input story works (yeah, I tested) and why it doesn't have to be \input{story} which is what I grew accustomed to in LaTeX.

It just seems counter-intuitive, because reading this the first time, the information I have by that time is that the control word \input should act on the next symbol only.

Perhaps I am missing something?

10

\centerline is a macro, defined in plain.tex with \def\centerline#1{\line{\hss#1\hss}}, so it takes an argument. As usual, an argument will be a single token (S, for example, is a single token), unless this token is a {, in which case a {...}-balanced list of tokens will be taken as the argument.

In Plain TeX \input is a primitive, so its rules are different. The primitive will look for character tokens and will stop at the first space token[1]. In LaTeX, \input is a macro, but if the next token is not a {, then it behaves as the primitive input. If the next token is a {, then \input behaves as a macro and grabs the file name as argument.

You can kind-of emulate that with \centerline by making it grab the rest of the line of input:

\def\centerline{%
  \begingroup
  \catcode`\^^M=13
  \centerlineaux}
\begingroup
\catcode`\^^M=13
\gdef\centerlineaux#1^^M{\endgroup\line{\hss#1\hss}}
\endgroup

\centerline This entire line is centered.
  But this is not.

\bye

1 There are different implementations of \input: Knuth's \input will scan character tokens until a non-character token or a space is found. If that token was a space, it is discarded. The characters found are taken as the file name.
The Web2C implementation (TeXLive and MiKTeX use that) of \input allows spaces in file names as long as the space occurrs between two ".
Finally, in all TeX engines from TeXLive 2020 onwards (before that only in LuaTeX), if the next token after the primitive \input is a {, the file name is grabbed between braces (\input{story} will input story.tex). Since this is what Knuth calls a "filesystem-dependent change", this applies to tex as well.

2
  • thank you very much. This really gave me some insight. Am I right to assume that ``\^^M` refers to the new line character? – 0xC0000022L Apr 8 '20 at 22:11
  • 1
    @0xC0000022L Yes. ^^M is a handy notation in TeX that allows you to write non-printable characters. M has character code 77 in the ASCII table, so ^^M will give a character of code 77-64=13 (the carriage return character). Usually ^^M has catcode 5 (line end character). By making it catcode 13 (or some other catcode other than 0, 1, 2, 5, 9, 10, 14, and 15) you can use it as argument delimiter in a macro. – Phelype Oleinik Apr 8 '20 at 22:16
4

\input is actually a primitive, and they are defined as part of the TeX core, not as a separate macro that is built on other macros. This is probably best explained if you look at the definition of \input and friends (within latex.ltx):

\ifx\@@input\@undefined\let\@@input\input\fi
% <some other definitions>
\def\input{\@ifnextchar\bgroup\@iinput\@@input}
% <some other definitions>
\def\@iinput#1{%
  \InputIfFileExists{#1}{}%
  {\filename@parse\@curr@file
   \edef\reserved@a{\noexpand\@missingfileerror
     {\filename@area\filename@base}%
     {\ifx\filename@ext\relax tex\else\filename@ext\fi}}%
   \reserved@a}}

Note that the sequence of commands stores \input - the TeX primitive definition - inside \@@input at the start of loading the LaTeX kernel. Then it (re)defines \input to be conditional via \@ifnextchar. This conditional checks if you supplied an opening curly brace { (or \bgroup). If so, it calls \@iinput. This would be the case when you used

\input{story}

The definition of \@iinput implies it takes a single, mandatory argument, like any other macro you use. This makes sense from your original use case. However, why does \input story work the same way? For that, we follow the false branch in the \@ifnextchar conditional. That is, \@@input.

Since \@@input is an exact copy of the \input primitive which, reads a filename as the string of non-empty characters following \input. Reference to this process is given in scan_file_name within tex.web.

2
  • Thanks a lot. The pointer to tex.web and scan_file_name is much appreciated. I'm torn about which answer to reward more by accepting it. – 0xC0000022L Apr 8 '20 at 22:13
  • @0xC0000022L At the risk of biasing your tick towards my answer, I must say: you should note that the definition of scan_file_name pointed by Werner is not the one you are using when you call tex: that's only part of it. The full definition of scan_file_name is that in tex.web (Knuth's version) plus the Web2C changes here: github.com/TeX-Live/texlive-source/blob/trunk/texk/web2c/… – Phelype Oleinik Apr 8 '20 at 22:21

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.