9

I have a file test.tex with these contents:

\input{missing}
\input{present}

When I run PDFLaTeX with --interaction=nonstopmode it stops after the first missing input file:

$ pdflatex --interaction=nonstopmode test
This is pdfTeXk, Version 3.1415926-1.40.9 (Web2C 7.5.7)
 %&-line parsing enabled.
entering extended mode
(./test.tex
LaTeX2e <2005/12/01>
Babel <v3.8l> and hyphenation patterns for english, usenglishmax, dumylang, nohyphenation, german-x-2008-06-18, ngerman-x-2008-06-18, ancientgreek, ibycus, arabic, basque, bulgarian, catalan, pinyin, coptic, croatian, czech, danish, dutch, esperanto, estonian, farsi, finnish, french, galician, german, ngerman, monogreek, greek, hungarian, icelandic, indonesian, interlingua, irish, italian, latin, lithuanian, mongolian, mongolian2a, bokmal, nynorsk, polish, portuguese, romanian, russian, sanskrit, serbian, slovak, slovenian, spanish, swedish, turkish, ukenglish, ukrainian, uppersorbian, welsh, loaded.

! LaTeX Error: File `missing.tex' not found.

Type X to quit or <RETURN> to proceed,
or enter new name. (Default extension: tex)

Enter file name: 
! Emergency stop.
<read *> 

l.1 \input{missing}
                   ^^M
!  ==> Fatal error occurred, no output PDF file produced!
Transcript written on test.log.

How can I make PDFLaTeX continue even when missing.tex is not there? I would like to do this with either command-line options or code I can put at the beginning of any arbitrary source file, not changing the body of the source file.

3 Answers 3

7

The LaTeX macro

\IfFileExists{<filename>}{<true code>}{<false code>}

is what you're looking for in the following way:

\IfFileExists{missing.tex}{\input{missing}}{}

An abbreviated version of the above exists in the form:

\InputIfFileExists{<filename>}{<before code>}

In short, the above defaults to

\IfFileExists{<filename>}{<before code>\input{<filename>}}

Edit: In your comment, you mention that you are interested in appending .tex to missing if it is not supplied and only then. To that end, the xstring package provides \IfEndWith{<string>}{<substr>}{<true code>}{<false code>} that executes <true code> if <string> ends with <substr>, and <false code> otherwise. I used .tex for <substr> in the following code:

\usepackage{xstring}% http://ctan.org/pkg/xstring
\let\OldInputIfFileExists\InputIfFileExists
\renewcommand{\InputIfFileExists}[2]{%
  \IfFileExists{#1}%
    {\OldInputIfFileExists{#1}{#2}}%
    {\IfEndWith{#1}{.tex}{\typeout{INPUT #1}}{\typeout{INPUT #1.tex}}}%
  }
5
  • I didn't specify the problem carefully enough before. Now edited to include: I would like to do this without changing the body of the file, only command-line options or the beginning. But maybe I could get this to work by \let\oldinput\input \let\input\newinput where \newinput is a command that actually calls \InputIfFileExists instead? Oct 30, 2011 at 2:48
  • You could also try a recursive \input, keeping the source file the same, but modifying the input file, which inputs another file. Would that work? I just tried it.
    – Werner
    Oct 30, 2011 at 3:20
  • I'm not sure I understand. I've been trying something like \let\OldInputIfFileExists\InputIfFileExists\renewcommand{\InputIfFileExists}[3]{\IfFileExists{#1}{\OldInputIfFileExists{#1}{#2}{#3}}{\typeout{ERROR #1}}}\input{$*}. Apparently LaTeX \input works by calling \InputIfFileExists which is an easier place to fix this. Oct 30, 2011 at 3:30
  • I would suggest editing your original question and add a separate Edit at the bottom. Include what you've done thus far, and what is still not working. Remember that someone is reading this without context, so provide as much of that as possible.
    – Werner
    Oct 30, 2011 at 3:38
  • I've edited my answer to provide a means for conditionally adding .tex to a missing filename.
    – Werner
    Oct 30, 2011 at 4:00
1
\documentclass[a4paper]{article}

\makeatletter
\def\input@message{\typeout{\if@tempswa INPUT\else MISSING\fi\space
  \filename@base.\ifx\filename@ext\relax tex\else\filename@ext\fi}}
\renewcommand*\@iinput[1]{%
  \filename@parse{#1}%
  \InputIfFileExists {#1}{\@tempswatrue}{\@tempswafalse}%
  \input@message
}
\makeatother

\begin{document}
\input{hoffman1}%existent
\input{hoffman2.dat}%existent
\input{hoffman3}%non existent
\end{document}

The relevant part of the log file is

(./hoffman1.tex)
INPUT hoffman1.tex
(./hoffman2.dat)
INPUT hoffman2.dat
MISSING hoffman3.tex

\@iinput is the macro called by \input when it's followed by an open brace.

0

This seems to work, since LaTeX \input calls \InputIfFileExists under the hood:

\let\OldInputIfFileExists\InputIfFileExists
\renewcommand{\InputIfFileExists}[3]{\IfFileExists{#1}{\OldInputIfFileExists{#1}{#2}{#3}}{\typeout{INPUT #1}}}

Thanks to Werner for pointing out the existence of these commands.

The only problem I have remaining is that I would like the \typeout to add .tex to the filename when appropriate, but only then. For example, I would like to change this such that:

\input{missing.tex}
\input{missing}

will result in the log lines

INPUT missing.tex
INPUT missing.tex

But I suppose that is another question.

2
  • Rather post this as an edit to your original question, unless you feel that this answers your original question. Also note that \InputIfFileExists takes only 2 mandatory arguments, not 3.
    – Werner
    Oct 30, 2011 at 3:50
  • If you look at my answer, you'll see that it adds the required extension with minimal intervention on commands.
    – egreg
    Oct 31, 2011 at 13:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .