46

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?

10
  • Try \input{ ./code/doc/latex/refman.tex } Oct 26, 2010 at 15:53
  • Still the same error "! LaTeX Error: File `todo.tex' not found."
    – Johan
    Oct 26, 2010 at 15:57
  • Can you just configure doxygen to give you the document you want? Oct 26, 2010 at 16:12
  • 4
    (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. Oct 26, 2010 at 18:11
  • 3
    @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. Oct 27, 2010 at 0:07

4 Answers 4

47

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.

6
  • 6
    \import takes, IIRC, the full path as the first argument. To use relative paths I think you need to use \subimport. Oct 27, 2010 at 0:11
  • I think it should be the final solution. Jun 3, 2011 at 11:20
  • 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, 2013 at 20:44
  • 1
    While it fixes the issue with relative graphics, it still doesn't recognize the bibliographies relative paths. How do I fix that?
    – thc
    Mar 7, 2017 at 22:34
  • 1
    @thc: this answer helped me with my bib files as well: tex.stackexchange.com/questions/79058/… Aug 8, 2018 at 16:06
15

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: [email protected]
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\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
1
  • Hi, Can you make it work with .bib files? Apparently, it is not supported yet. Many thanks :-)
    – hola
    May 11, 2017 at 22:15
8

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.

1
  • 2
    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. Oct 27, 2010 at 9:23
-1

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
2
  • 2
    -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. Jun 3, 2011 at 13:14
  • 1
    -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, 2012 at 8:41

You must log in to answer this question.

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