Problem
I am planning to read source code of a open-source project. With a (perhaps weird) habit, I often print all the source codes according to the way they are organized (in particular, the hierarchy) and this was previously done manually. However, I encountered a rather large project and it involves more than 100 files. Therefore, I have been trying to automate this process.
Now I have read all the file names into a text file that look that the following
I use package minted
to typeset code and it provides \inputminted[<options>]{<language>}{<filename>}
to include the entire file. Additionally, it could be used together with listing
environment that looks like
\begin{listing}
\inputminted{python}{<filename>.py}
\caption{xxx}
\end{listing}
Now I would like to use LaTeX to read all the filenames and recursively use the previous code snippet to typeset all of these files into a bunch of listing
environments. In this way, I could
- Easily include all the codes without tiresome copy-and-paste.
- Know the dependency relations among codes by reading the caption.
However, I am not sure if there is easy way to do this.
Solution
I really like @SergeiGolovan's solution, which might be a good fit for complicated task. However, for a (relatively simple) application like mine, I figured out that a simpler solution is to directly use datatool
package.
datatool
has pretty sophisticated functionalities like making table, drawing plots from input file, etc. But I just need it to read external file
\documentclass{article}
\usepackage{datatool}
\usepackage{minted}
\usepackage[nohead, margin=0.3in]{geometry}
\begin{document}
\DTLsetseparator{,}
\DTLloaddb{mydb}{filename.txt}
\DTLforeach{mydb}{\path=path,\name=name}{
\begin{listing}[H]
\inputminted[linenos, breaklines]{python}{\path}
\caption{\name}
\end{listing}
}
\end{document}
Note that
- The underscore
_
's are replaced with\underscore
when writingfilename.txt
file. - To avoid potentially long absolute path, an additional column
name
is added, which is just filename relative to root of the code repo.
Best Answer
What I would do for this task is not use LaTeX for it, but employ an external script which would generate the list of listings. And then glue it to the LaTeX document using
make
. An example code can be the following:1) The outer document
listings.tex
(a portion of code which breaks listings between pages is taken from Pagebreak for minted in figure):2) The list generating script
genlistings.py
in Python (it's very basic, you can add anything you like to it):3) The
Makefile
to put them together (it searches for Python files in thesampleproject
directory and creates a document with listings for all found files. It useslatexmk
.):Simply executing
make
, you'll get the required listings. If anything changes (the code in the Python scripts, the genlistings.py script, the listings.tex itself), anothermake
will recreate the list.