# How to trim .tex for each filename read from an external file?

I have an external text file that contains a list of names of TeX input files. The names have trailing extensions .tex. For example, the external text file named data.txt contains the following list:

a.tex
b.tex
c.tex


There is a PDF file for each TeX input file in the same directory in which data.txt exists.

The following codes are expected to iterate the file name without extension and import the corresponding PDF.

\documentclass{article}
\usepackage{graphicx}

\begin{document}
\loop
\includegraphics{\x}\par
\repeat
\end{document}


Could you help me to implement the trimming macro to remove .tex in \x?

-
Off-topic suggestion: Throw the list into Excel and use =SUBSTITUTE(A1;".tex";""). Add .tex whenever required by TeX. – percusse Dec 30 '11 at 11:54
I'm not sure if it helps, but the xstring package has \StrBefore. Using \StrBefore{hello.tex}{.tex} gives me hello. – Paulo Cereda Dec 30 '11 at 12:04

The LaTeX2e kernel, provides some commands for parsing paths and extensions. It is preferable to use them for this type of parsing.

The macro \filename@parse scans its argument and splits it into three parts which are then saved in the macros \filename@area, \filename@base, \filename@ext

\documentclass{article}
\begin{document}
\makeatletter
\filename@parse{path/name.tex}
\filename@area, \filename@base, \filename@ext
\makeatother
\end{document}


In your case \filename@base will represent the trimmed filename, with no path or extension information.

-
Fascinating! Is there a handy reference (perhaps even a cheat-sheet) for such commands? – qubyte Dec 30 '11 at 13:07
@MarkS.Everitt: Yes, macros2e. – Martin Scharrer Dec 30 '11 at 13:15
AFAIK, this won't work correctly with path/name.with.dots.tex, because everything after the first, not last, dot is taken as the extension. – Martin Scharrer Dec 30 '11 at 13:17
@MartinScharrer One shouldn't name files this way; but under normal circumstances this would work. What you interested is the extension and in your example the extension is with.dots.tex, which you want removed. If you save a file under latex as test.sty.tex and you input{test} LaTeX will import it with no issue. – Yiannis Lazarides Dec 30 '11 at 13:21
@YiannisLazarides: No, \input{test} will try test and then test.tex, but will not find test.sty.tex. How should it be able to know if it is not test.abc.tex, test.xyz.tex, etc. etc.; I agree that files should not be named like that, but as say, package programmer you need to think about supporting them. – Martin Scharrer Dec 30 '11 at 13:25

As already stated by Yiannis Lazarides the internal LaTeX2e \filename@parse macro can be used to parse the file name. However, the code for splitting the extension off assumes that there is only one dot in the filename and that everything after it is the file extension. Therefore you will get incorrect results for filename with multiple dots as shown below.

I recently added support for multi-dot filenames to my currfile package (shows the current file name, path, extension, etc.), by reimplementing parts of the \filename@parse internals. Unfortunately there is no public interface, but you could use it as follows:

\documentclass{article}
\usepackage{currfile}[2011/09/18]
\begin{document}
\makeatletter
\filename@parse{path/name.tex}
\filename@area, \filename@base, \filename@ext

% Will take 'width.dots.tex' as the extension
\filename@parse{path/name.with.dots.tex}
\filename@area, \filename@base, \filename@ext

% Works with internal 'currfile' redefinitions:
{
\let\filename@simple\currfile@parseext
\let\filename@base\@gobble
\filename@parse{path/name.with.dots.tex}
\filename@area, \filename@base, \filename@ext
}

\makeatother
\end{document}

-

Here is a possible definition, in which also options for every graphic file can be stated

\documentclass{article}
\usepackage{graphicx}

\makeatletter
\newcommand\includefromfile[2][]{%
\filename@parse{\@tempa}%
\begingroup\edef\x{\endgroup
\noexpand\includegraphics[#1]{\filename@base}\noexpand\par}\x
\repeat
}
\makeatother

\begin{document}
\begin{center}
\includefromfile[scale=1.2]{data.txt}
\end{center}
\end{document}


Notice that \immediate does nothing before \openin and \closein (it's different from \openout and \closeout, where in the absence of \immediate the commands would execute during the next \shipout operation that involves them).

It's important to say \noexpand\par as in some environments (notably center), \par is redefined as a macro.

-