Jak mogę automatycznie przekonwertować wszystkie pliki kodu źródłowego w folderze (rekurencyjnie) na pojedynczy plik PDF z podświetleniem składni?

27

Chciałbym przekonwertować kod źródłowy kilku projektów na jeden plik do wydrukowania, aby zapisać na usb i wydrukować łatwo później. Jak mogę to zrobić?

Edytować

Po pierwsze chcę wyjaśnić, że chcę wydrukować tylko nie ukryte pliki i katalogi (więc nie ma zawartości .git na przykład.).

Dostać lista wszystkich nie ukrytych plików w niewidocznych katalogach w bieżącym katalogu możesz uruchomić find . -type f ! -regex ".*/\..*" ! -name ".*" polecenie jako odpowiedź w ten wątek .

Zgodnie z sugestią w tym samym wątku próbowałem utworzyć plik PDF z plikami za pomocą polecenia find . -type f ! -regex ".*/\..*" ! -name ".*" ! -empty -print0 | xargs -0 a2ps -1 --delegate no -P pdf ale niestety wynikowy plik pdf to kompletny bałagan .

Bentley4
źródło
Nie wiem, czy pasuje do twoich potrzeb, ale z a2ps -P file *.src możesz tworzyć pliki postscriptowe z kodu źródłowego. Jednak pliki PS muszą być konwertowane i łączone później.
mpy
Korzystanie z konwersji ( linux.about.com/od/commands/l/blcmdl1_convert.htm , imagemagick) powinieneś być wtedy w stanie zrobić jeden plik PDF z plików ps.
SBI
Czy możesz skomentować, co masz na myśli mówiąc „kompletny bałagan”? To ( i.stack.imgur.com/LoRhv.png ) nie wygląda mi tak źle, używając a2ps -1 --delegate=0 -l 100 --line-numbers=5 -P pdf -- Dodałem -l za 100 znaków na wiersz, aby zapobiec zawijaniu słów i numerom linii, ale to tylko osobiste preferencje.
mpy
Do konwersji to project (4 niepuste nie ukryte pliki, każdy o długości strony w niewidocznych katalogach) do pdf Miałem około 5 stron kodu źródłowego i 39 stron bełkotu.
Bentley4

Odpowiedzi:

47

Zaintrygowało mnie twoje pytanie i trochę mnie poruszyło. To rozwiązanie wygeneruje ładny plik PDF z klikalnym indeksem i kodem podświetlonym kolorem. Znajduje wszystkie pliki w bieżącym katalogu i podkatalogach oraz tworzy sekcję w pliku PDF dla każdego z nich (patrz uwagi poniżej, aby uzyskać bardziej szczegółowe informacje o poleceniu find).

Wymaga zainstalowania następujących elementów (instrukcje instalacji są przeznaczone dla systemów opartych na Debianie, ale powinny być dostępne w repozytoriach twojej dystrybucji):

  • pdflatex, color i listings

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

    Powinno to również zainstalować podstawowy system LaTeX, jeśli go nie masz.

Po zainstalowaniu użyj tego skryptu, aby utworzyć dokument LaTeX z kodem źródłowym. Sztuczka polega na użyciu listings (część texlive-latex-recommended ) i color (zainstalowane przez latex-xcolor ) Pakiety LaTeX. The \usepackage[..]{hyperref} to, co powoduje, że aukcje w spisie treści mogą być klikalne.

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

Uruchom skrypt w katalogu zawierającym pliki źródłowe

bash src2pdf

Spowoduje to utworzenie pliku o nazwie all.pdf w bieżącym katalogu. Próbowałem tego z kilkoma przypadkowymi plikami źródłowymi, które znalazłem w moim systemie (w szczególności dwoma plikami ze źródła vlc-2.0.0 ) i jest to zrzut ekranu pierwszych dwóch stron wynikowego pliku PDF:

enter image description here


Kilka komentarzy:

  • Skrypt nie będzie działać, jeśli nazwy plików kodu źródłowego zawierają spacje. Ponieważ mówimy o kodzie źródłowym, założę, że nie.
  • dodałem ! -name "*~" aby uniknąć plików kopii zapasowej.
  • Polecam użyć bardziej szczegółowego find polecenie, aby znaleźć pliki, w przeciwnym razie dowolny plik losowy zostanie dołączony do pliku PDF. Jeśli wszystkie twoje pliki mają określone rozszerzenia ( .c i .h na przykład), powinieneś wymienić find w skrypcie z czymś takim

    find . -name "*\.c" -o -name "\.h" | sed 's/^\..//' | 
    
  • Pobaw się z listings opcje , możesz dostosować to tak, aby było dokładnie takie, jak chcesz.
terdon
źródło
1
Wow, to właśnie nazywam odpowiedzią! :)
mpy
1
OMG terdon, byłeś właścicielem tego pytania ^^. Do innych osób próbujących skryptu: jeśli natkniesz się na src2pdf: line 36: warning: here-document at line 5 delimited by end-of-file (wanted EOF') podczas uruchamiania skryptu musisz usuń białe znaki w linii EOF aby to zadziałało.
Bentley4
1
Jeśli Twój plik jest wywoływany src2pdf następnie włóż ! -name "src2pdf" w find wiersz w skrypcie w ten sposób find . -type f ! -regex ".*/\..*" ! -name "src2pdf" ! -name ".*" ! -name "*~" | pominąć go w pdf.
Bentley4
1
@ Bentley4 dzięki! Usuwam białe znaki (zostało dodane po wklejeniu skryptu do odpowiedzi) i dodałem filtr, aby usunąć skrypt ze strony find wyniki (zapisałem skrypt w innym katalogu, który był w moim $ PATH, więc nie miałem tego problemu). Możesz także zmienić język plików źródłowych, aby uzyskać lepsze oznaczenia poprzez zmianę language=C++ cokolwiek chcesz, może obsługiwać wiele różnych języków, patrz tutaj .
terdon
1
@ qubodup Naprawdę nie wiem. LaTeX i UTF8 mogą być trudne. To powinien pracować z \usepackage[utf8]{inputenc} usepackage [german] {babel} `ale nie działa na moich testach. Podejrzewam jednak, że nie karmię go prawdziwym utf8. To może być warte własnego pytania, ale sugeruję, abyś zapytał TeX - LaTeX powinni wiedzieć.
terdon
2

(z Przepełnienie stosu )

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

Spowoduje to wynik.txt zawierający:

  • Nazwa pliku
  • separator (---)
  • Zawartość pliku .src
  • Powtarzaj od góry, aż wszystkie pliki * .src zostaną wykonane

Jeśli twój kod źródłowy ma inne rozszerzenie, zmień je w razie potrzeby. Możesz także edytować bit echa, aby dodać niezbędne informacje (być może echo „nazwa_pliku $ 1” lub zmienić separator, lub dodać separator końca pliku).

link ma inne metody, więc używaj dowolnej metody, którą lubisz najbardziej. Uważam, że ten jest najbardziej elastyczny, chociaż ma niewielką krzywą uczenia się.

Kod będzie działał doskonale z terminala bash (właśnie przetestowany na VirtualBox Ubuntu)

Jeśli nie zależy Ci na nazwie pliku i zależy Ci tylko na zawartości połączonych plików:

cat *.src > result.txt

będzie działać doskonale.

Inną sugerowaną metodą była:

grep "" *.src > result.txt

Które będą poprzedzać każdą pojedynczą linię nazwą pliku, co może być dobre dla niektórych osób, osobiście uważam, że jest to zbyt wiele informacji, dlatego moja pierwsza sugestia to pętla for powyżej.

Podziękowania dla osób z forum StackOverflow.

EDYTOWAĆ: Właśnie zdałem sobie sprawę, że jako wynik końcowy poszukujesz HTML lub PDF, niektóre rozwiązania, które widziałem, polegają na wydrukowaniu pliku tekstowego w PostScripcie, a następnie konwertowaniu PostScript na PDF. Jakiś kod, który widziałem:

groff -Tps result.txt > res.ps

następnie

ps2pdf res.ps res.pdf 

(Wymaga posiadania ghostscript)

Mam nadzieję że to pomoże.

Darius
źródło
Działa to tylko w przypadku plików o określonym rozszerzeniu (.src), ale chcę, aby każdy plik był umieszczany w tym pliku PDF niezależnie od rozszerzenia. Chciałbym jednak pominąć ukryte katalogi i nie ukryte pliki. Edytowałem oryginalny post, czy mógłbyś go obejrzeć?
Bentley4
2

Wiem, że jestem za późno, ale ktoś szukający rozwiązania może uznać to za przydatne.

Na podstawie odpowiedzi @ terdon stworzyłem skrypt BASH, który wykonuje zadanie: https://github.com/eljuanchosf/source-code-to-pdf

eljuanchosf
źródło
Podaj istotne części odpowiedzi z linków referencyjnych, ponieważ odpowiedź może stać się nieważna, jeśli zmienione strony zostaną zmienione.
DavidPostill