Come posso convertire automaticamente tutti i file di codice sorgente in una cartella (ricorsivamente) in un singolo PDF con l'evidenziazione della sintassi?


29

Vorrei convertire il codice sorgente di alcuni progetti in un file stampabile per salvare su un usb e stamparlo facilmente in seguito. Come lo posso fare?

modificare

Prima di tutto voglio chiarire che voglio solo stampare i file e le directory non nascosti (quindi nessun contenuto di .gites.).

Per ottenere un elenco di tutti i file non nascosti nelle directory non nascoste nella directory corrente è possibile eseguire il find . -type f ! -regex ".*/\..*" ! -name ".*"comando come visto nella risposta in questo thread .

Come suggerito in quello stesso thread ho provato a creare un file pdf dei file usando il comando find . -type f ! -regex ".*/\..*" ! -name ".*" ! -empty -print0 | xargs -0 a2ps -1 --delegate no -P pdfma sfortunatamente il file pdf risultante è un casino completo .


Non so se si adatta alle tue necessità, ma con a2ps -P file *.srcte puoi produrre file PostScript dal tuo codice sorgente. Ma i file PS devono essere convertiti e combinati in seguito.
mpy,

Usando convert ( linux.about.com/od/commands/l/blcmdl1_convert.htm , imagemagick) dovresti essere in grado di creare un pdf dai file ps.
SBI,

Puoi commentare cosa intendi con "pasticcio completo"? Questo ( i.stack.imgur.com/LoRhv.png ) non sembra troppo male per me, usando a2ps -1 --delegate=0 -l 100 --line-numbers=5 -P pdf- ho aggiunto -lper 100 caratteri per riga per evitare alcune parole e numeri di riga, ma questa è solo una preferenza personale.
mpy,

Per convertire questo progetto (4 file non vuoti non nascosti ciascuno su una pagina lunga in directory non nascoste) in pdf ho avuto circa 5 pagine di codice sorgente e 39 pagine di incomprensibili.
Bentley4,

Risposte:


47

Sono stato incuriosito dalla tua domanda e sono stato un po 'portato via. Questa soluzione genererà un bel file PDF con un indice cliccabile e un codice evidenziato a colori. Troverà tutti i file nella directory e nelle sottodirectory correnti e creerà una sezione nel file PDF per ciascuno di essi (vedere le note di seguito per come rendere il comando find più specifico).

Richiede che tu abbia installato quanto segue (le istruzioni di installazione sono per sistemi basati su Debian ma dovrebbero essere disponibili nei repository della tua distribuzione):

  • pdflatex, colorelistings

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

    Questo dovrebbe anche installare un sistema LaTeX di base se non ne hai uno installato.

Una volta installati, utilizzare questo script per creare un documento LaTeX con il codice sorgente. Il trucco sta usando i pacchetti listings(parte di texlive-latex-recommended) e color(installato da latex-xcolor) LaTeX. Il \usepackage[..]{hyperref}è ciò che rende gli annunci nel sommario link cliccabili.

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

Esegui lo script nella directory che contiene i file di origine

bash src2pdf

Ciò creerà un file chiamato all.pdfnella directory corrente. Ho provato questo con un paio di file sorgente casuali che ho trovato sul mio sistema (in particolare, due file dalla fonte di vlc-2.0.0) e questo è uno screenshot delle prime due pagine del PDF risultante:

inserisci qui la descrizione dell'immagine


Un paio di commenti:

  • Lo script non funzionerà se i nomi dei file del codice sorgente contengono spazi. Dal momento che stiamo parlando di codice sorgente, suppongo che non lo facciano.
  • Ho aggiunto ! -name "*~"per evitare i file di backup.
  • Ti consiglio di usare un findcomando più specifico per trovare i tuoi file, altrimenti qualsiasi file casuale verrà incluso nel PDF. Se tutti i tuoi file hanno estensioni specifiche ( .ce .hper esempio), dovresti sostituire la findnello script con qualcosa del genere

    find . -name "*\.c" -o -name "\.h" | sed 's/^\..//' | 
  • Gioca con le listings opzioni , puoi modificarlo per essere esattamente come lo desideri.

1
Wow, è quello che chiamo una risposta! :)
mpy,

1
Oh mio Dio, hai posseduto quella domanda ^^. Per altre persone che provano lo script: se ti imbatti src2pdf: line 36: warning: here-document at line 5 delimited by end-of-file (wanted EOF')durante l'esecuzione dello script, devi eliminare lo spazio bianco sulla riga EOF affinché funzioni.
Bentley4,

1
Se il tuo file viene chiamato, src2pdfinseriscilo ! -name "src2pdf"nella findriga nello script in questo modo find . -type f ! -regex ".*/\..*" ! -name "src2pdf" ! -name ".*" ! -name "*~" |per ometterlo nel pdf.
Bentley4

1
@ Bentley4 grazie! Ho rimosso lo spazio bianco (è stato aggiunto quando ho incollato lo script nella risposta) e ho aggiunto il filtro per rimuovere lo script stesso dai findrisultati (avevo salvato lo script in un'altra directory che era nel mio $ PATH, quindi non ne avevo problema). Inoltre, puoi cambiare la lingua utilizzata per i file sorgente per avere un markup migliore cambiando language=C++in qualsiasi cosa tu voglia, può gestire molte lingue diverse, vedi qui .
terdon,

1
@qubodup Non lo so davvero. LaTeX e UTF8 possono essere complicati. Si dovrebbe lavorare con \usepackage[utf8]{inputenc} \ usepackage [tedesco] {babel} `ma non riesce a mie prove. Tuttavia, sospetto di non dargli da mangiare vero utf8. Potrebbe valere la sua domanda, ma ti suggerisco di chiedere a TeX - LaTeX , dovrebbero saperlo.
terdon,

2

(da StackOverflow )

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

Ciò comporterà un risultato.txt contenente:

  • Nome del file
  • separatore (---)
  • Contenuto del file .src
  • Ripeti dall'alto fino a quando tutti i file * .src sono terminati

Se il tuo codice sorgente ha un'estensione diversa, basta cambiarlo secondo necessità. È inoltre possibile modificare il bit di eco per aggiungere le informazioni necessarie (magari echo "nomefile $ 1" o modificare il separatore o aggiungere un separatore di fine file).

il link ha altri metodi, quindi usa il metodo che preferisci. Trovo che questo sia il più flessibile, anche se presenta una leggera curva di apprendimento.

Il codice funzionerà perfettamente da un terminale bash (appena testato su un VirtualBox Ubuntu)

Se non ti interessa il nome del file e ti interessa solo il contenuto dei file uniti:

cat *.src > result.txt

funzionerà perfettamente bene.

Un altro metodo suggerito era:

grep "" *.src > result.txt

Che anteporrà ogni singola riga con il nome del file, che può essere buono per alcune persone, personalmente trovo troppe informazioni, quindi perché il mio primo suggerimento è il ciclo for sopra.

Ringraziamo quelli delle persone del forum StackOverflow.

EDIT: Mi sono appena reso conto che stai cercando specificamente HTML o PDF come risultato finale, alcune soluzioni che ho visto è stampare il file di testo in PostScript e quindi convertire PostScript in PDF. Qualche codice che ho visto:

groff -Tps result.txt > res.ps

poi

ps2pdf res.ps res.pdf 

(Richiede di avere ghostscript)

Spero che sia di aiuto.


Funziona solo con file di un'estensione specifica (.src) ma voglio che ogni file sia inserito in quel pdf indipendentemente dall'estensione. Vorrei però omettere directory non nascoste e file non nascosti. Ho modificato il post originale, potresti dargli un'occhiata?
Bentley4

2

So che sto aspettando troppo tardi, ma qualcuno in cerca di una soluzione potrebbe trovarlo utile.

Sulla base della risposta di @ terdon, ho creato uno script BASH che fa il lavoro: https://github.com/eljuanchosf/source-code-to-pdf


Si prega di citare le parti essenziali della risposta dai collegamenti di riferimento, in quanto la risposta può diventare non valida se le pagine collegate cambiano.
DavidPostill
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.