# How to make the main file recognize relative paths used in the imported files?

I'm currently using doxygen to generate some documentation for a project, and doxygen generate some LaTeX code that then can be used to generate a nice pdf.

But let's say I would like to write another document, and in that document include the doxygen generated LaTeX code as a part of that document.

How would I do that? Has anybody done this type of stuff?

My try is to get the code, generate the LaTeX code without the "header". So I end up with a dir called code/doc/latex/, seen from the place where I have my own main.tex.

And try in include that LaTeX code from my main.tex with input.

\input{ code/doc/latex/refman.tex }

But when I try to include the code/doc/latex/refman.tex (the doxygen, main.tex), he complains that he can't find the other LaTeX files that was generated by doxygen. It seems like he is searching in the same dir as my main.tex and not in code/doc/latex/.

This is more or less how the refman.tex looks like:

\chapter{Todo List}
\label{todo}
\hypertarget{todo}{}
\input{todo}
\chapter{Class Index}
\input{annotated}
\chapter{File Index}
\input{files}
\chapter{Class Documentation}
\include{struct__offsetChannel}
\include{struct__offsetPixel}
\include{struct__tPixel}
...
...

Any ideas would be welcome.

A solution could be to write a script that edits all the generated LaTeX code, and simply adds this path but this seems like a overly complicated solution.

Update:

The error I get is like this one

! LaTeX Error: File todo.tex' not found.

Update:

If I change all the \input \include and \includegraphics like this it works.

\input{todo} -> \input{code/doc/latex/todo}

But there must be a way to make LaTeX understand that he should look into the code/doc/latex/ for the code?

-
Try \input{ ./code/doc/latex/refman.tex } –  Yiannis Lazarides Oct 26 '10 at 15:53
Still the same error "! LaTeX Error: File todo.tex' not found." –  Johan Oct 26 '10 at 15:57
Can you just configure doxygen to give you the document you want? –  Matthew Leingang Oct 26 '10 at 16:12
(I'm putting this in a comment as I'm not sure it's really answering the question, but it may be so it at least warrants a comment.) It seems as though the issue is simply telling TeX where to find stuff. One (hackish) way to do that is to redefine the \input command: \let\oldinput=\input \def\input#1{\oldinput{code/doc/latex/#1}}. You should probably put things back where they were after including the doxygen generated file, and this might break other things, unfortunately. –  Loop Space Oct 26 '10 at 18:11
@Johan: a better title for this question would be "How to tell TeX where to find \include s of \include s." By saying that the question is about doxygen, you may have turned away some people who could otherwise have given an answer. –  Willie Wong Oct 27 '10 at 0:07

I'm fuzzy on the details, but the import package should do what you want. Off the top of my head, I think the syntax is

\usepackage{import}
...
\subimport{code/doc/latex/}{refman.tex}

Update: Thanks Willie for pointing out \subimport which seems to be the better command to use here over \import.

The commands \import{full_path}{file} and \subimport{path_extension}{file} set up input through standard LaTeX mechanisms (\input, \include and \includegraphics) to load files relative to the \import-ed directory. There are also \includefrom, \subincludefrom, and * variants of the commands. The author is Donald Arseneau.

-
\import takes, IIRC, the full path as the first argument. To use relative paths I think you need to use \subimport. –  Willie Wong Oct 27 '10 at 0:11
I think it should be the final solution. –  xport Jun 3 '11 at 11:20
+1, exactly what I was looking for. –  rcollyer Feb 14 '12 at 4:05
By the way, use \subimport* if you have files named the same in your document root as in the sub-import root, such as todo.tex in the example. –  Geoff May 22 '13 at 20:44
+1 A very handy little package! –  Jubobs Nov 28 '13 at 20:22

I have written my own package for this purpose.

Now there is one important new command available: \inputpaths

\inputpaths specifies the directories where \include and \input can look for the given file. By default \inputpaths is empty and therefore \include and \input have the same behavior as the normal commands.

The redefined \include and \input use the root-directory. If the file is not in the root-directory than the commands looking for the file in the specified directories.

Example:

File structure:
./main.tex
./file2.tex
./dir1/file1.tex
./dirN/file3.tex

Contents of file1.tex:

\usepackage{inputx}
...
\inputpaths{dir1,...,dirN}
...
\begin{document}

\include{file1}
\input{file2}

\end{document}

Contents of dir1/file1.tex:

\input{file3}
\input{dirN/file3}

Contents of file2.tex:

file2: Hello World!

Contents of dirN/file3.tex:

file3: Hello World!

Output:

file3: Hello World!
file3: Hello World!
file2: Hello World!

The inputx package source:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Author: Blackstev
% Email: blackstev@hotmail.com
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\ProvidesPackage{inputx}[2011/06/28 v1.0 inputx style for better file includings]
\typeout{2011/06/28 v1.0 inputx style for better file includings}

%{{{    use package
%}}}

\makeatletter

\newif\ifBreak
\Breakfalse

\gdef\inputpaths#1{\gdef\@inputpaths{#1}}
\gdef\@inputpaths{}

\newcommand{\forAllInputpaths}[2][\path]{\@for#1:=\@inputpaths\do{#2}}

\gdef\printinputpaths{
\forAllInputpaths[\path]{Path: \path}
}

%{{{ redefine include
\global\let\old@include\include
\gdef\includex#1{
\IfFileExists{#1.tex}
{
\old@include{#1}
}
{
\forAllInputpaths[\path]
{
\ifBreak
\else
\IfFileExists{\path/#1.tex}
{
\old@include{\path/#1}
\Breaktrue
}
{}
\fi
}
\ifBreak
\else
% \PackageError{includex}{'#1' can not be resolved}{'#1' can not be resolved. It is not in \@includepaths}
\old@include{#1}
\fi
\Breakfalse
}
}
\gdef\include#1{\includex{#1}}
%}}}
%{{{ redefine input
% original definition of input: \def\input{\@ifnextchar\bgroup\@iinput\@@input}
\global\let\old@input\@@input
\gdef\@@input#1{\old@input#1}
\gdef\inputx#1{
\IfFileExists{#1.tex}
{
\@@input{#1}%
}
{
\forAllInputpaths[\path]
{
\ifBreak
\else
\IfFileExists{\path/#1.tex}
{
\@@input{\path/#1}
\Breaktrue
}
{}
\fi
}
\ifBreak
\else
%\PackageError{includex}{'#1' can not be resolved}{'#1' can not be resolved. It is not in \@includepaths}
\@@input{#1}
\fi
\Breakfalse
}
}
\def\input{\@ifnextchar\bgroup\inputx\@@input}
%}}}
\makeatother
-

If you use rubber, you can simply add a directives such as these to your Latex source:

% rubber: path code/doc/latex
% rubber: path ../foo/bar

After that, \input and friends will be able to locate files also in code/doc/latex and ../foo/bar (relative to the current working directory).

Rubber implements this by setting the TEXINPUTS environment variable appropriately before invoking pdflatex, latex, etc.

-
Nice solution. One caveat: if you are using TEXINPUTS and have multiple different files of the same name but in different subdirectories, you will run into a problem with this method. –  Willie Wong Oct 27 '10 at 9:23

The quick fix for this is to create a search and replace script, and for the sake of the question I will put this here as a alternative (even if it not the most optimal thing to do).

Enter the Doxygen LaTeX dir and run this bash script.

#!/bin/bash

for f in *.tex ;
do
sed 's/$$\\includegraphics$.*$$${$$.*$$}/\1{code\/doc\/latex\/\2}/' $f |\ sed 's/$$\\include$${$$.*$$}/\1{code\/doc\/latex\/\2}/' |\ sed 's/$$\\input$${$$.*$$}/\1{code\/doc\/latex\/\2}/' |\ sed 's/$$\\end{document}$$/%\1/' >$f.tmp ;
mv $f.tmp$f;
done
-
-1 @Johan: You should use import package that has been explained in Will's answer. Changing relative paths in the imported files to absolute paths is a bad practice. –  xport Jun 3 '11 at 13:14
-1 Bad practice, yes. A document should be able to compile even if something is moved to a different location. Some might even suggest that instead of working with relative paths one can make a copy of the objects to include. But, then again you would have to make a copy every time your source updates. For projects like these I've sometimes used the operating systems symlinks instead. Stuff can still go wrong if somethings moved, but at least its an easier fix than going for absolute paths. –  DrJay Dec 4 '12 at 8:41