TransWikia.com

Why does `endinput` bring TeX into interactive mode while there are still tokens to process?

TeX - LaTeX Asked on December 13, 2021

Minimal example consists of two files:

fileA.tex:

deffoo#1{#1}
foo{endinputinput fileB.tex}%

fileB.tex:

This is file B.
bye

I assumed that compiling fileA.tex would lead to a file fileA.pdf which contains the phrase "This is file B."

I get this but during compilation TeX enters interactive mode.

When I just press return, then fileB.tex is loaded and compilation finishes.

My question is:

Why does TeX enter interactive mode?

I assumed endinputinput fileB.tex would already be in the token-stream.

So endinput would cause TeX not to read and tokenize things from fileA.tex any more.

As input fileB.tex is already in the token-stream, that would be processed next and lead to TeX reading and tokenizing things from fileB.tex.

But why does TeX enter interactive mode before loading fileB.tex ?

Here is the console-output:

$ pdftex fileA.tex
This is pdfTeX, Version 3.14159265-2.6-1.40.19 (TeX Live 2019/dev/Debian) (preloaded format=pdftex)
 restricted write18 enabled.
entering extended mode
(./fileA.tex)
*
(./fileB.tex [1{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] )</usr/shar
e/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb>
Output written on fileA.pdf (1 page, 11997 bytes).
Transcript written on fileA.log.

2 Answers

Very nice catch. I suppose it will be examined as a potential bug, but the behavior matches the definition of endinput from page 214 of The TeXbook:

  • endinput. The expansion is null. The next time TeX gets to the end of an input line, it will stop reading from the file containing that line.

The foo{ } wrapper is an unnecessary diversion, has no effect, and so is ignored here. (It might have been intended to delay the effect of endinput, but endinput is delayed by design.)

In the case given where the line ends with % TeX is still trying to read characters of the file name when it encounters the end of the line and triggers the pending endinput. This ends input from filea.tex with the file name for the input still incomplete, so TeX looks for interactive input. Pressing Enter at the interactive prompt (*) gives a par token (because an end of line character appeared at the beginning of the input line on the console). That par terminates/delimits the file name so TeX can proceed with the input of fileb.tex, which it does. The endinput has already had its effect (the rule said "the next time") so the entire fileb.tex gets input.

Note that the definition says "the file containing that line", not "the file containing endinput", so a perhaps more interesting case (to me) is without the % on the line with input. In that case, the file name is terminated before TeX reaches an EOL, so it opens fileb.tex and reads input from it. Then at the end of the first line in fileb the pending endinput request is triggered, the rest of fileb is discarded, and input returns to whatever is left in filea.tex.

Answered by Donald Arseneau on December 13, 2021

There are two different issues.

If I remove the trailing %, I get the following from an interactive run of tex:

This is TeX, Version 3.14159265 (TeX Live 2020) (preloaded format=tex)
(./jewdokijaA.tex (./jewdokijaB.tex))
*bye
[1]
Output written on jewdokijaA.dvi (1 page, 224 bytes).
Transcript written on jewdokijaA.log.

You can notice that the second file is loaded before issuing the * prompt. In order to end the run I have to manually supply bye at the prompt. Hitting the return key would do nothing except repeating the message

(Please type a command or say `end')

and issuing the * prompt again.

If I add relax after input jewdokijaB.tex, I get the same behavior.

Why do you get

This is TeX, Version 3.14159265 (TeX Live 2020) (preloaded format=tex)
(./jewdokijaA.tex)
*
(./jewdokijaB.tex [1] )
Output written on jewdokijaA.dvi (1 page, 224 bytes).
Transcript written on jewdokijaA.log.

with your code and the run ends after pressing the return key?

In the first two cases (no % or with relax), the parsing of the file name is complete, but endinput is still lurking, so the first line of the second file is read in and endinput does its job.

In your case there's nothing else TeX can do than asking for input from you because endinput is still lurking and so nothing can be used from further lines in the main file. You can check that

input jew%
dokija.tex

will regularly input the file, but

endinputinput jew%
dokija.tex

wouldn't.

However, there's still a problem to solve. Why, with your code, the file is fully read in after hitting return?

I guess that the answer is in modules 361 and 362 of tex.web. I admit that the behavior is puzzling.

Answered by egreg on December 13, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP