如何将语法突出显示的文件夹中的所有源代码文件自动(递归)转换为单个PDF?


29

我想将一些项目的源代码转换为一个可打印的文件,以保存在USB上并在以后轻松打印。我怎样才能做到这一点?

编辑

首先,我想澄清一下,我只想打印非隐藏的文件和目录(因此,.git例如没有内容)。

要获取当前目录中非隐藏目录中所有非隐藏文件列表,您可以运行find . -type f ! -regex ".*/\..*" ! -name ".*"命令,如该线程中的答案所示

正如在同一线程中所建议的那样,我尝试通过使用命令来制作文件的pdf文件,find . -type f ! -regex ".*/\..*" ! -name ".*" ! -empty -print0 | xargs -0 a2ps -1 --delegate no -P pdf但不幸的是,生成的pdf文件是一团糟


不知道它是否适合您的需求,但是a2ps -P file *.src您可以从源代码中生成脚本文件。但是PS文件需要随后进行转换和合并。
mpy

然后,使用convert(linux.about.com/od/commands/l/blcmdl1_convert.htm和imagemagick),您应该能够从ps文件中制作一个pdf。
SBI

您能否评论“完全混乱”的含义?这个(i.stack.imgur.com/LoRhv.png)看起来对我来说还不错,我使用了a2ps -1 --delegate=0 -l 100 --line-numbers=5 -P pdf-我-l每行添加100个字符以防止某些自动换行和行号,但这只是个人喜好。
mpy

为了将这个项目(4个非空非隐藏文件,每个非隐藏目录中的每个页面大约一页)转换为pdf,我有大约5页的源代码和39页的乱码。
Bentley13年

Answers:


47

我对你的问题很感兴趣,并被带走了。该解决方案将生成一个具有可点击索引和高亮显示颜色的代码的漂亮PDF文件。它将在当前目录和子目录中找到所有文件,并在每个文件的PDF文件中创建一个部分(有关如何使find命令更具体的信息,请参见下面的注释)。

它要求您已经安装了以下软件(安装说明适用于基于Debian的系统,但是在发行版的存储库中应该可用):

  • pdflatexcolorlistings

    sudo apt-get install texlive-latex-extra latex-xcolor texlive-latex-recommended

    如果您还没有安装基本的LaTeX系统,那么它也应该安装。

安装这些文件后,使用此脚本用您的源代码创建一个LaTeX文档。诀窍是使用LaTeX软件包的listings(的一部分texlive-latex-recommended)和color(由latex-xcolor)安装。这\usepackage[..]{hyperref}就是使目录中的列表可单击的链接的原因。

#!/usr/bin/env bash

tex_file=$(mktemp) ## Random temp file name

cat<<EOF >$tex_file   ## Print the tex file header
\documentclass{article}
\usepackage{listings}
\usepackage[usenames,dvipsnames]{color}  %% Allow color names
\lstdefinestyle{customasm}{
  belowcaptionskip=1\baselineskip,
  xleftmargin=\parindent,
  language=C++,   %% Change this to whatever you write in
  breaklines=true, %% Wrap long lines
  basicstyle=\footnotesize\ttfamily,
  commentstyle=\itshape\color{Gray},
  stringstyle=\color{Black},
  keywordstyle=\bfseries\color{OliveGreen},
  identifierstyle=\color{blue},
  xleftmargin=-8em,
}        
\usepackage[colorlinks=true,linkcolor=blue]{hyperref} 
\begin{document}
\tableofcontents

EOF

find . -type f ! -regex ".*/\..*" ! -name ".*" ! -name "*~" ! -name 'src2pdf'|
sed 's/^\..//' |                 ## Change ./foo/bar.src to foo/bar.src

while read  i; do                ## Loop through each file
    name=${i//_/\\_}             ## escape underscores
    echo "\newpage" >> $tex_file   ## start each section on a new page
    echo "\section{$i}" >> $tex_file  ## Create a section for each filename

   ## This command will include the file in the PDF
    echo "\lstinputlisting[style=customasm]{$i}" >>$tex_file
done &&
echo "\end{document}" >> $tex_file &&
pdflatex $tex_file -output-directory . && 
pdflatex $tex_file -output-directory .  ## This needs to be run twice 
                                           ## for the TOC to be generated    

在包含源文件的目录中运行脚本

bash src2pdf

这将all.pdf在当前目录中创建一个名为的文件。我尝试了在系统上找到的几个随机源文件(特别是来自的两个文件)进行了尝试vlc-2.0.0,这是生成的PDF的前两页的屏幕截图:

在此处输入图片说明


几点评论:

  • 如果您的源代码文件名包含空格,则该脚本将不起作用。由于我们在谈论源代码,因此我认为它们不是。
  • 我添加! -name "*~"以避免备份文件。
  • 我建议您使用更具体的find命令来查找文件,否则,任何随机文件都将包含在PDF中。如果你的文件都有特定的扩展名(.c.h为例),则应更换find像这样的东西在脚本

    find . -name "*\.c" -o -name "\.h" | sed 's/^\..//' | 
  • 试一下这些listings 选项,您可以根据自己的需要进行调整。

1
哇,这就是我所说的答案!:)
mpy

1
OMG terdon,您拥有这个问题^^。对于尝试脚本的其他人:如果src2pdf: line 36: warning: here-document at line 5 delimited by end-of-file (wanted EOF')在运行脚本时遇到问题,则必须删除EOF行上的空格以使其起作用。
Bentley13年

1
如果您的文件被调用,src2pdf! -name "src2pdf"find脚本中插入这样的行以find . -type f ! -regex ".*/\..*" ! -name "src2pdf" ! -name ".*" ! -name "*~" |在pdf中将其忽略。
Bentley13年

1
@ Bentley4谢谢!我删除了空格(在将脚本粘贴到答案中时添加了空格),并添加了过滤器以从find结果中删除脚本本身(我已将脚本保存在$ PATH中的另一个目录中,所以我没有该空格)问题)。另外,您可以通过更改为所需的名称来更改用于源文件的语言,以具有更好的标记language=C++,它可以处理多种不同的语言,请参见此处
13年

1
@qubodup我不太清楚。LaTeX和UTF8可能很棘手。它应该\usepackage[utf8]{inputenc} \ usepackage [german] {babel}`一起使用,但是在我的测试中失败。但是,我怀疑我没有提供真正的utf8。这可能是值得回答的问题,但我建议您在TeX-LaTeX上询问,他们应该知道。
terdon

2

(来自StackOverflow

for i in *.src; do echo "$i"; echo "---"; cat "$i"; echo ; done > result.txt

这将导致result.txt包含:

  • 文档名称
  • 分隔器 ( - -)
  • .src文件的内容
  • 从顶部开始重复,直到完成所有* .src文件

如果您的源代码具有不同的扩展名,请根据需要进行更改。您还可以编辑echo位以添加必要的信息(也许echo“ filename $ 1”或更改分隔符,或添加文件结尾分隔符)。

链接还有其他方法,因此请使用您最喜欢的任何方法。我发现这是最灵活的,尽管它确实有一些学习上的困难。

该代码将从bash终端完美运行(仅在VirtualBox Ubuntu上进行了测试)

如果您不在乎文件名,而在乎合并在一起的文件的内容:

cat *.src > result.txt

会很好地工作。

建议的另一种方法是:

grep "" *.src > result.txt

它将在每行前面加上文件名,这可能对某些人有用,我个人认为它包含太多信息,因此,为什么我的第一个建议是上面的for循环。

感谢那些在StackOverflow论坛中的人。

编辑:我只是意识到,最终的结果是专门针对HTML或PDF,我见过的一些解决方案是将文本文件打印为PostScript,然后将Postscript转换为PDF。我看过的一些代码:

groff -Tps result.txt > res.ps

然后

ps2pdf res.ps res.pdf 

(要求您安装ghostscript)

希望这可以帮助。


这仅适用于具有特定扩展名(.src)的文件,但我希望将每个文件都放在该pdf中,而不管扩展名如何。我确实想省略非隐藏的目录和非隐藏的文件。我编辑了原始帖子,您可以看看吗?
Bentley4

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.