Wie kann ich automatisch alle Quelltextdateien in einem Ordner (rekursiv) in eine einzelne PDF-Datei mit Syntaxhervorhebung konvertieren?

29

Ich möchte den Quellcode einiger Projekte in eine druckbare Datei konvertieren, um ihn auf einem USB-Stick zu speichern und später problemlos auszudrucken. Wie kann ich das machen?

Bearbeiten

Zunächst möchte ich klarstellen, dass ich nur die nicht versteckten Dateien und Verzeichnisse drucken möchte (also keine Inhalte von .gitzB).

Um eine Liste aller nicht ausgeblendeten Dateien in nicht ausgeblendeten Verzeichnissen im aktuellen Verzeichnis zu erhalten , können Sie den find . -type f ! -regex ".*/\..*" ! -name ".*"Befehl ausführen, der in diesem Thread als Antwort angezeigt wird .

Wie im selben Thread vorgeschlagen, habe ich versucht, mithilfe des Befehls eine PDF-Datei aus den Dateien zu erstellen, find . -type f ! -regex ".*/\..*" ! -name ".*" ! -empty -print0 | xargs -0 a2ps -1 --delegate no -P pdfaber leider ist die resultierende PDF-Datei ein komplettes Durcheinander .

Bentley4
quelle
Sie wissen nicht, ob es Ihren Anforderungen entspricht, können jedoch a2ps -P file *.srcPostscript-Dateien aus Ihrem Quellcode erstellen. Die PS-Dateien müssen jedoch konvertiert und anschließend kombiniert werden.
mpy
Mit convert ( linux.about.com/od/commands/l/blcmdl1_convert.htm , imagemagick) sollten Sie dann in der Lage sein, ein PDF aus den ps-Dateien zu erstellen.
SBI
Kannst du kommentieren, was du mit "komplettes Durcheinander" meinst? Dies ( i.stack.imgur.com/LoRhv.png ) sieht für mich nicht schlecht aus. a2ps -1 --delegate=0 -l 100 --line-numbers=5 -P pdfIch habe -l100 Zeichen pro Zeile hinzugefügt , um einige Zeilenumbrüche und Zeilennummern zu vermeiden, aber das ist nur eine persönliche Einstellung.
mpy
Für die Konvertierung dieses Projekts (4 nicht leere, nicht ausgeblendete Dateien mit einer Länge von jeweils etwa einer Seite in nicht ausgeblendeten Verzeichnissen) nach PDF hatte ich ungefähr 5 Seiten Quellcode und 39 Seiten Kauderwelsch.
Bentley4

Antworten:

47

Ich war fasziniert von Ihrer Frage und wurde irgendwie mitgerissen. Diese Lösung generiert eine schöne PDF-Datei mit einem anklickbaren Index und farblich hervorgehobenem Code. Es findet alle Dateien im aktuellen Verzeichnis und in den Unterverzeichnissen und erstellt für jede einen Abschnitt in der PDF-Datei.

Es setzt voraus, dass Sie Folgendes installiert haben (die Installationsanweisungen gelten für Debian-basierte Systeme, diese sollten jedoch in den Repositorys Ihrer Distribution verfügbar sein):

  • pdflatex, colorundlistings

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

    Hierdurch sollte auch ein grundlegendes LaTeX-System installiert werden, falls Sie keines installiert haben.

Nach der Installation können Sie mit diesem Skript ein LaTeX-Dokument mit Ihrem Quellcode erstellen. Der Trick besteht darin, die listings(Teil von texlive-latex-recommended) und color(von latex-xcolor) LaTeX-Pakete zu verwenden. Das \usepackage[..]{hyperref}ist es, was die Objekte in der Tabelle der Inhalte anklickbare Links macht.

#!/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    

Führen Sie das Skript in dem Verzeichnis aus, das die Quelldateien enthält

bash src2pdf

Dadurch wird eine Datei erstellt, die all.pdfim aktuellen Verzeichnis aufgerufen wird . Ich habe dies mit einigen zufälligen Quelldateien versucht, die ich auf meinem System gefunden habe (insbesondere zwei Dateien aus der Quelle von vlc-2.0.0). Dies ist ein Screenshot der ersten beiden Seiten des resultierenden PDF:

Bildbeschreibung hier eingeben


Ein paar Kommentare:

  • Das Skript funktioniert nicht, wenn Ihre Quellcode-Dateinamen Leerzeichen enthalten. Da es sich um Quellcode handelt, gehe ich davon aus, dass dies nicht der Fall ist.
  • Ich fügte hinzu ! -name "*~", um Backup-Dateien zu vermeiden.
  • Ich empfehle Ihnen jedoch, einen spezifischeren findBefehl zu verwenden, um Ihre Dateien zu finden. Andernfalls wird jede zufällige Datei in die PDF-Datei aufgenommen. Wenn Ihre Dateien alle bestimmte Erweiterungen haben ( .cund .hzum Beispiel), sollten Sie das findim Skript durch so etwas ersetzen

    find . -name "*\.c" -o -name "\.h" | sed 's/^\..//' | 
  • Spielen Sie mit den listings Optionen . Sie können diese so anpassen, dass sie genau Ihren Wünschen entsprechen.
terdon
quelle
1
Wow, das nenne ich eine Antwort! :)
mpy
1
OMG terdon, du hattest diese Frage ^^. Anderen Personen, die das Skript testen: Wenn Sie src2pdf: line 36: warning: here-document at line 5 delimited by end-of-file (wanted EOF')beim Ausführen des Skripts darauf stoßen, müssen Sie das Leerzeichen in der EOF-Zeile löschen , damit es funktioniert.
Bentley4
1
Wenn Ihre Datei aufgerufen src2pdfwird, fügen Sie sie wie folgt ! -name "src2pdf"in die findZeile des Skripts ein find . -type f ! -regex ".*/\..*" ! -name "src2pdf" ! -name ".*" ! -name "*~" |, um sie im PDF-Dokument auszulassen.
Bentley4
1
@ Bentley4 danke! Ich habe das Leerzeichen entfernt (es wurde hinzugefügt, als ich das Skript in die Antwort eingefügt habe) und den Filter hinzugefügt, um das Skript selbst aus den findErgebnissen zu entfernen (ich hatte das Skript in einem anderen Verzeichnis gespeichert, das sich in meinem $ PATH befand, damit ich das nicht hatte Problem). Sie können auch die Sprache ändern, die für die Quelldateien verwendet wird, um ein besseres Markup zu erzielen, indem language=C++Sie die gewünschte Sprache auswählen. Sie kann mit vielen verschiedenen Sprachen umgehen (siehe hier) .
Terdon
1
@ Qubodup Ich weiß es nicht wirklich. LaTeX und UTF8 können schwierig sein. Es sollte mit \usepackage[utf8]{inputenc} \ usepackage [german] {babel} ` funktionieren, aber es schlägt bei meinen Tests fehl. Ich vermute jedoch, ich füttere es nicht wahr utf8. Das mag eine eigene Frage wert sein, aber ich schlage vor, Sie fragen nach TeX - LaTeX , sie sollten es wissen.
Terdon
2

(von StackOverflow )

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

Dies führt zu einer result.txt mit:

  • Dateiname
  • Trennzeichen (---)
  • Inhalt der .src-Datei
  • Wiederholen Sie den Vorgang von oben, bis alle * .src-Dateien fertig sind

Wenn Ihr Quellcode eine andere Erweiterung hat, ändern Sie ihn einfach nach Bedarf. Sie können auch das Echo-Bit bearbeiten, um die erforderlichen Informationen hinzuzufügen (z. B. "Dateiname $ 1" wiederholen oder das Trennzeichen ändern oder ein Trennzeichen für das Dateiende hinzufügen).

Die Verknüpfung hat andere Methoden. Verwenden Sie also die Methode, die Ihnen am besten gefällt. Ich finde dieses Modell am flexibelsten, obwohl es mit einer leichten Lernkurve verbunden ist.

Der Code läuft perfekt von einem Bash-Terminal (gerade auf einer VirtualBox Ubuntu getestet)

Wenn Ihnen der Dateiname und der Inhalt der zusammengeführten Dateien egal sind:

cat *.src > result.txt

wird einwandfrei funktionieren.

Eine andere vorgeschlagene Methode war:

grep "" *.src > result.txt

Was jeder einzelnen Zeile den Dateinamen voranstellen wird, was für einige Leute gut sein kann, persönlich finde ich zu viele Informationen, weshalb mein erster Vorschlag die obige for-Schleife ist.

Wir danken den Mitgliedern des StackOverflow-Forums.

BEARBEITEN: Ich habe gerade festgestellt, dass Sie speziell HTML oder PDF als Endergebnis benötigen. Einige Lösungen, die ich gesehen habe, bestehen darin, die Textdatei in PostScript zu drucken und dann Postscript in PDF zu konvertieren. Code, den ich gesehen habe:

groff -Tps result.txt > res.ps

dann

ps2pdf res.ps res.pdf 

(Benötigt Ghostscript)

Hoffe das hilft.

Darius
quelle
Dies funktioniert nur für Dateien mit einer bestimmten Erweiterung (.src), aber ich möchte, dass jede Datei unabhängig von der Erweiterung in dieses PDF eingefügt wird. Ich möchte jedoch nicht versteckte Verzeichnisse und nicht versteckte Dateien weglassen. Ich habe den ursprünglichen Beitrag bearbeitet. Könnten Sie ihn sich ansehen?
Bentley4
2

Ich weiß, ich bin zu spät dran, aber jemand, der nach einer Lösung sucht, könnte dies nützlich finden.

Basierend auf der Antwort von @ terdon habe ich ein BASH-Skript erstellt, das die Aufgabe erfüllt: https://github.com/eljuanchosf/source-code-to-pdf

eljuanchosf
quelle
Bitte zitieren Sie die wesentlichen Teile der Antwort aus den Referenzlinks, da die Antwort ungültig werden kann, wenn sich die verlinkten Seiten ändern.
DavidPostill