使用 LaTeX 读取文件

使用 LaTeX 读取文件

问题

我计划阅读一个开源项目的源代码。我有一个(也许很奇怪的)习惯,我经常按照源代码的组织方式(特别是层次结构)打印所有源代码,这在以前是这样做的手动。但是我遇到一个比较大的项目,涉及到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}

注意

  • 写入文件时,下划线_被替换为。\underscorefilename.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将重新创建列表。

相关内容