Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Assume I have many TeX files. For the sake of simplicity, also asssume they are in a single folder or directory.

I want to input all files from within my main LaTeX document. Actually I can create a list of those files using C# in advance.

To enrich my view about LaTeX or TeX, could you tell me whether or not this job can be done only by using pure TeX or LaTeX?


The following code, that was made by Herbert and adapted by Paulo, has been tested and it works successfully on Windows. A good day!

\documentclass{minimal}
\makeatletter
\def\app@exe{\immediate\write18}
\def\inputAllFiles#1{%
  \app@exe{cmd /c dir /b *.tex > \jobname.tmp}%
  \InputIfFileExists{\jobname.tmp}{}
  \AtEndOfDocument{\app@exe{rm -f #1/\jobname.tmp}}}
\makeatother
\begin{document}

\inputAllFiles{.}% from the current dir 

\end{document}
share|improve this question
    
As I've commented next to Herbert's answer, it is *nix dependent. As it relies on the OS to work, any solution of this type will dependent on which system you use. –  Joseph Wright Dec 23 '10 at 17:44
2  
Yes, I have no idea how it can work udner windows, but there should be similiar commands –  Herbert Dec 23 '10 at 17:47
    
@xport. No, it's just that TeX is perhaps not the best way to do it. I'd probably write a batch file to set things up, writing a suitable input file using that and then running TeX with my intermediate file as input. However, that's not really a question for this site as it's about Windows batch file programming. You've also pointed out that you can create the list in advance in C#, which is also a reasonable approach and one I guess you can implement yourself. –  Joseph Wright Dec 23 '10 at 17:50
1  
@xport. TeX does not do any handling of file processing beyond reading or writing individual files. Herbert's solution uses the Unix shell to do the work, and the same can be achieved in Windows. However, these solutions don't use TeX to do the work, they use the OS. –  Joseph Wright Dec 23 '10 at 18:35
2  
I'm not sure, but you could try to use \app@exe{cmd /c dir /b *.txt > \jobname.tmp} in Herbert's answer. On a sidenote, his code does work in Windows if you have the proper *nix tools provided by Cygwin or MSys. IMHO those tools give us more confidence than their Windows counterparts. –  Paulo Cereda Jul 30 '11 at 19:55
show 2 more comments

4 Answers

up vote 19 down vote accepted
+50
\documentclass{minimal}
\makeatletter
\def\app@exe{\immediate\write18}
\def\inputAllFiles#1{%
  \app@exe{ls #1/*.txt | xargs cat >> \jobname.tmp}%
  \InputIfFileExists{\jobname.tmp}{}
  \AtEndDocument{\app@exe{rm -f #1/\jobname.tmp}}}
\makeatother
\begin{document}

\inputAllFiles{.}% from the current dir 

\end{document}

Not really difficult. It is only an appetizer of how it can be done. This one only reads files *.txt. You have to run it with pdflatex -shell-escape test

share|improve this answer
2  
As Ryan pointed out, this is an OS-depend solution. It will fail on Windows, for a start. –  Joseph Wright Dec 23 '10 at 17:39
1  
I think the second \app@exe should be \app@exe{rm -f \jobname.tmp}. It only works for this example because #1 is .. It'd also be simpler to just run \app@exe{cat #1/*.txt > \jobname.tmp}. –  TH. Dec 23 '10 at 20:50
    
Does this delete the files after they are accessed? Why is there a rm -f \jobname.tmp? –  Village Dec 17 '11 at 23:44
    
all files are read and saved in \jobname.tmp, when is deleted after reading it into TeX –  Herbert Dec 18 '11 at 8:39
    
Are you sure there is \AtEndOfDocument? –  I am who I say I am Nov 18 '13 at 21:31
add comment

A LuaTeX solution:

the TeX driver:

\directlua{dofile("inputall.lua")}

\bye

and the Lua input file inputall.lua:

function dirtree(dir)

  if string.sub(dir, -1) == "/" then
    dir=string.sub(dir, 1, -2)
  end

  local function yieldtree(dir)
    for entry in lfs.dir(dir) do
      if not entry:match("^%.") then
        entry=dir.."/"..entry
          if lfs.isdir(entry) then
            yieldtree(entry)
          else
            coroutine.yield(entry)
          end
      end
    end
  end

  return coroutine.wrap(function() yieldtree(dir) end)
end


for i in dirtree(lfs.currentdir()) do
  local filename = i:gsub(".*/([^/]+)$","%1")
  tex.sprint("\\input " ..  filename .. " ")
end

This recurses down a directory tree and inputs all the file found. (Found the dirtree iterator in the Lua users wiki.)

share|improve this answer
    
The answer should work in both plain and LaTeX. I bet that in a few years, this answer would be a standard answer. -- But I admit that I like to give a LuaTeX answer even if the OP does not ask for it or runs a engine different to LuaTeX. –  topskip Dec 24 '10 at 20:22
    
+1 for the interesting answer. Would it be possible to add a complete minimal example we could try at home? Thanks. –  Faheem Mitha Mar 20 '11 at 9:43
    
A complete minimal LaTeX example, please. :-) –  Faheem Mitha Mar 20 '11 at 9:49
    
Is this solution portable? –  Faheem Mitha Mar 20 '11 at 10:04
add comment

If there is some sort of naming convention that is used for the files than this can be done as in Can i automatically load chapters and sections based on the filesystem?

\documentclass{article}

\newcommand*{\MaxNumOfChapters}{10}% Adjust these two settings for your needs.
\newcommand*{\MaxNumOfSections}{6}%

\usepackage{pgffor}%

\begin{document}
\foreach \c in {1,2,...,\MaxNumOfChapters}{%
    \foreach \s in {1,2,...,\MaxNumOfSections}{%
        \IfFileExists{Chapter\c/Section\s} {%
            \input{Chapter\c/Section\s}%
        }{%
                % files does not exist, so nothing to do
        }%
    }%
}%
\end{document}

This assumes that there is a directory for each chapter named Chapter<i> directory contains files named Section<n>. Should be able to customize this depending on your specific case.

This should work across different operating systems.

If there is not specfic naming convention, you can adjust this to process a list of files generated by your C# program. For example, if the C# program can generate ListOfFiles.tex as

\newcommand*{\ListOfFiles}{%
    Chapter1/Section1,
    Chapter1/Section2,
    Chapter1/Section3,
    Chapter2/Section1,
    Chapter2/Section2
}%

then you can process this as:

\documentclass{article}%
\usepackage{pgffor}%

\input{ListOfFiles}%

\begin{document}%
\foreach \c in \ListOfFiles {%
    \input{\c}%
}%
\end{document}
share|improve this answer
    
This should be the top-rated post. –  g33kz0r Apr 8 '12 at 0:48
add comment

I don't know whether you can; you probably can't, and if you could, the facilities for it are almost certainly extremely limited and likely based on \write18, which makes the OS do all the work anyway. However, I don't think you should, since it is far from being a typesetting task, which is the only kind of job TeX is designed to do. Consider:

  • If all you want is a list of \input{filename.tex}'s, and if you can already programmatically create a list of filenames using some other language, then you can also generate a TeX file (or file fragment) using that language.

  • I don't know how you created these files, but if you did it by hand, then perhaps you gave them meaningful names, like introduction.tex, body.tex, and conclusion.tex. No form of automatic sorting will give you the right order, so you're back to creating a list by some other means, for which see the previous point.

  • How many times are you going to TeX this document? If only once, you may as well just write the names in by hand and concentrate on your writing and/or other TeX coding which it contains.

Basically, this is a bookkeeping task which doesn't depend on anything within a TeX document, and therefore is better done by one of the many scripting languages which support filesystem interaction (not to mention programming in general) to a far greater extent than TeX itself.

share|improve this answer
    
thanks for answering. I have made the list of file names in advance using C# as I mentioned above. You can see my effort here :-) tex.stackexchange.com/questions/6547/… –  xport Dec 23 '10 at 16:53
    
@xport: My point is that the only way to include files is by individual \input commands, and the only way to access the filesystem is through \write18 (i.e. invoking another program) and if you're going to do that, you may as well have another program write out a TeX file fragment itself (which includes all your files) and then use just one \input to include it, rather than force TeX to do something it does quite badly. –  Ryan Reich Dec 23 '10 at 23:51
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.