![使用 LaTeX 读取文件](https://linux22.com/image/478198/%E4%BD%BF%E7%94%A8%20LaTeX%20%E8%AF%BB%E5%8F%96%E6%96%87%E4%BB%B6.png)
问题
我计划阅读一个开源项目的源代码。我有一个(也许很奇怪的)习惯,我经常按照源代码的组织方式(特别是层次结构)打印所有源代码,这在以前是这样做的手动。但是我遇到一个比较大的项目,涉及到100多个文件,所以一直在尝试把这个过程自动化。
我使用包minted
来排版代码,它提供了\inputminted[<options>]{<language>}{<filename>}
包含整个文件的功能。此外,它可以与listing
类似这样的环境一起使用
\begin{listing}
\inputminted{python}{<filename>.py}
\caption{xxx}
\end{listing}
现在我想使用 LaTeX 读取所有文件名,并递归使用前面的代码片段将所有这些文件排版到一组listing
环境中。这样,我可以
- 轻松包含所有代码,无需繁琐的复制粘贴。
- 通过阅读标题了解代码间的依赖关系。
然而,我不确定是否有简单的方法来做到这一点。
解决方案
我非常喜欢@SergeiGolovan 的解决方案,它可能非常适合复杂的任务。但是,对于像我这样的(相对简单的)应用程序,我发现更简单的解决方案是直接使用datatool
包。
datatool
具有相当复杂的功能,如制作表格、从输入文件绘制图表等。但我只需要它来读取外部文件
\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}
注意
- 写入文件时,下划线
_
被替换为。\underscore
filename.txt
- 为了避免可能较长的绝对路径,
name
添加了一个附加列,该列只是相对于代码库根目录的文件名。
答案1
对于这项任务,我不会使用 LaTeX,而是使用一个外部脚本来生成列表。然后使用 将其粘贴到 LaTeX 文档中make
。示例代码如下:
1)外部文档listings.tex
(打破页面间列表的部分代码取自图中为 minted 的分页符):
\documentclass[a4paper,12pt]{article}
\usepackage{minted}
\usepackage{caption}
\usepackage[margin=2cm]{geometry}
% Create a new environment for breaking code listings across pages.
% See https://tex.stackexchange.com/questions/368864/pagebreak-for-minted-in-figure
\newenvironment{longlisting}{\captionsetup{type=listing}}{}
\begin{document}
\input{mylistings.tex}
\end{document}
2)Python 中的列表生成脚本genlistings.py
(它非常基础,您可以添加任何您喜欢的内容):
#!/usr/bin/python3
import sys
import os
directory = sys.argv[1]
def Escape(string):
return string.replace("_", r"\textunderscore ")
def PrintListing(filename):
if os.path.splitext(filename)[1] == '.py':
print(r'\begin{longlisting}\inputminted{python}{%s}\caption{\texttt{%s}}\end{longlisting}' % (filename, Escape(filename)))
for root, dirs, files in os.walk(directory):
for name in files:
PrintListing(os.path.join(root, name))
3)Makefile
将它们放在一起(它在目录中搜索 Python 文件sampleproject
并创建一个包含所有找到的文件列表的文档。它使用latexmk
.):
DIR = sampleproject
PYTHONSOURCES = $(find $(DIR) -name '*.py')
all: listings.pdf
listings.pdf: listings.tex mylistings.tex
latexmk -pdf -pdflatex='pdflatex -shell-escape %O %S' $<
mylistings.tex: genlistings.py $(PYTHONSOURCES)
python3 genlistings.py $(DIR) >$@
clean:
rm -rf mylistings.tex listings.fdb_latexmk listings.fls listings.pdf listings.aux listings.log _minted-listings/
.PHONY: listings.pdf clean
只需执行make
,您就会获得所需的列表。如果有任何变化(Python 脚本中的代码、genlistings.py 脚本、listings.tex 本身),另一个make
将重新创建列表。