# Is it possible to interact with TeX mid-process?

Quoting from an answer to Typesetting the entire Song That Never Ends

I ran this code once, and aborted the process after it reported producing something like 47,000 pages (in a very short amount of time). Unfortunately, my computer complained that the resulting pdf file was "damaged" and could not be opened. A better (perhaps impossible?) answer would produce a file such that the output could actually be viewed once the process was killed (or died).

This got me curious (and it is merely a curiosity). Can TeX die gracefully? Since its output is a PDF, presumably it needs to do some non-trivial stuff at the end to ensure that the PDF is valid so merely killing TeX is too abrupt.

A more graceful method would be for TeX to ask at each shipout "Shall I continue?", but that suffers from the other extreme: it is too intrusive as the user needs to keep giving commands to keep TeX going.

Off the top of my head, the only way I can think of to communicate with a running process in a non-blocking way is via a file. At each shipout (or other), TeX can check for the existence of a file and continue if it doesn't exist, and if it does then read the file and carry out whatever actions said file contains (thus allowing for more refined communication).

Is there a better way?

-
As per usual, I have absolutely no idea how to tag this one. – Loop Space Jan 30 '13 at 10:56
Suggested tag: {to-TeX-or-not-to-TeX}. ;) – Count Zero Jan 30 '13 at 11:01
I think 'DVI mode' is the plan here, as each shipped out page can normally be viewed even if the run terminates – Joseph Wright Jan 30 '13 at 11:11
JFTR: If you hit ctrl-c and then x then also pdftex will produce a valid PDF. – Stephan Lehmke Jan 30 '13 at 16:37
@StephanLehmke Oddly enough, I haven't tested it up to that many pages either! (Hopefully my question expands sufficiently on the original "die nicely" to survive this astonishing revelation.) – Loop Space Jan 30 '13 at 17:07

Run this file

\def\resume{\let\foo\relax}

\count0=0

\foo\relax\relax\relax\relax

hello I reached \the\count0 before you stopped me

\bye


For a bit then stop it at the terminal (control-c in most shells) and enter i\resume and it will finish cleanly:

 pdftex oops
This is pdfTeX, Version 3.1415926-2.4-1.40.13 (TeX Live 2012)
restricted \write18 enabled.
entering extended mode
(./oops.tex
! Interruption.
\foo
l.7 \foo
\relax\relax\relax\relax
? i\resume
[18672624{/usr/local/texlive/2012/texmf-var/fonts/map/pdftex/updmap/pdftex.map}
] )</usr/local/texlive/2012/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb
>
Output written on oops.pdf (1 page, 14709 bytes).
Transcript written on oops.log.

-
I like it! Quick question: why all the \relaxing? – Loop Space Jan 30 '13 at 15:29
the \relax aren't needed in this version plan a was to stop the loop with a gobble command but depending on when exactly you hit ^C you needed to eat a different number of tokens so I stuck in some more so gobblefour was always safe but \let is better – David Carlisle Jan 30 '13 at 15:33

If you set \pausing=1, TeX will stop after each line of input read from the file.

-
What does "stop" mean in this context? Will it halt completely, or will it wait for some "please continue" signal? Either way, it seems to suffer from one of the issues I don't want as I basically want to be able to asynchronously send a signal to TeX. – Loop Space Jan 30 '13 at 15:09
@AndrewStacey: It will wait for user input. :-) – Martin Schröder Jan 30 '13 at 15:28
Right, so this is an implementation of my "graceful" method. The problem with this one is that I have to keep telling it to continue. What it would enable is having a controlling script which actually handled the signals and told TeX to keep going unless the script received the right signal. So, useful, but not quite what I was looking for. – Loop Space Jan 30 '13 at 15:31

Maybe setting a timer in \everypar? I used \pdfelapsedtime as shown in my post at Benchmarking various operations of TeX. In the MWE that illustrates the technique, I have used a simple

\ifdim\result sp <100000sp  \fibo \else Finish\fi


to do the time check. Code is rough and just a concept.

\documentclass[a4paper]{article}
\usepackage{fp}
\begin{document}
\makeatletter
\pdfresettimer

\newcount\numbertimes
\newcount\numone
\newcount\numtwo
\newcount\savenumone
\def\fibonacci#1{..
\numbertimes=2\numone=0
\numtwo=1
\loop
\savenumone=\the\numone  \numone=\numtwo  \numtwo=\savenumone
\repeat
}

\def\fibo{%
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
\fibonacci{30}\fibonacci{30}\fibonacci{30}\fibonacci{30}
}

\fibo\fibo\fibo\fibo\fibo\fibo\fibo\fibo\fibo\fibo

\FPset\result{\the\pdfelapsedtime}
\FPmul\result{\result}{100}
\FPround\result{\result}{16}
\result\thinspace

\ifdim\result sp <100000sp  \fibo \else Finish\fi

\makeatother

\end{document}


Change the "Finish" to \enddocument to terminate.

-