Bagaimana saya bisa secara otomatis mengkonversi semua file kode sumber dalam folder (secara rekursif) ke satu PDF dengan penyorotan sintaksis?

29

Saya ingin mengonversi kode sumber dari beberapa proyek ke satu file yang dapat dicetak untuk menghemat usb dan mencetak dengan mudah nanti. Bagaimana saya bisa melakukan itu?

Edit

Pertama saya ingin mengklarifikasi bahwa saya hanya ingin mencetak file dan direktori yang tidak disembunyikan (jadi tidak ada konten .gitmisalnya).

Untuk mendapatkan daftar semua file yang tidak tersembunyi di direktori yang tidak tersembunyi di direktori saat ini, Anda dapat menjalankan find . -type f ! -regex ".*/\..*" ! -name ".*"perintah seperti yang terlihat di jawaban di utas ini .

Seperti yang disarankan dalam utas yang sama saya mencoba membuat file pdf dari file dengan menggunakan perintah find . -type f ! -regex ".*/\..*" ! -name ".*" ! -empty -print0 | xargs -0 a2ps -1 --delegate no -P pdftapi sayangnya file pdf yang dihasilkan adalah kekacauan lengkap .

Bentley4
sumber
Tidak tahu apakah itu sesuai dengan kebutuhan Anda, tetapi dengan a2ps -P file *.srcAnda dapat menghasilkan file postscript dari kode sumber Anda. Tetapi file PS perlu dikonversi dan digabungkan sesudahnya.
mpy
Dengan menggunakan convert ( linux.about.com/od/commands/l/blcmdl1_convert.htm , imagemagick) Anda kemudian dapat membuat satu pdf dari file ps.
SBI
Bisakah Anda berkomentar, apa yang Anda maksud dengan "kekacauan lengkap"? Ini ( i.stack.imgur.com/LoRhv.png ) terlihat tidak terlalu buruk bagi saya, menggunakan a2ps -1 --delegate=0 -l 100 --line-numbers=5 -P pdf- saya menambahkan -l100 karakter per baris untuk mencegah beberapa kata wraps dan nomor baris, tapi itu hanya preferensi pribadi.
mpy
Untuk mengonversi proyek ini (masing-masing 4 file non-kosong non-kosong sekitar satu halaman di direktori tidak tersembunyi) ke pdf saya memiliki sekitar 5 halaman kode sumber dan 39 halaman omong kosong.
Bentley4

Jawaban:

47

Saya tertarik dengan pertanyaan Anda dan agak terbawa suasana. Solusi ini akan menghasilkan file PDF yang bagus dengan indeks yang dapat diklik dan kode warna yang disorot. Ini akan menemukan semua file di direktori dan subdirektori saat ini dan membuat bagian dalam file PDF untuk masing-masing file (lihat catatan di bawah ini tentang cara membuat perintah find Anda lebih spesifik).

Ini mengharuskan Anda menginstal yang berikut ini (instruksi instal untuk sistem berbasis Debian tetapi ini harus tersedia di repositori distribusi Anda):

  • pdflatex, colordanlistings

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

    Ini juga harus menginstal sistem LaTeX dasar jika Anda belum menginstalnya.

Setelah ini diinstal, gunakan skrip ini untuk membuat dokumen LaTeX dengan kode sumber Anda. Caranya menggunakan paket listings(bagian dari texlive-latex-recommended) dan color(diinstal oleh latex-xcolor) LaTeX. Inilah \usepackage[..]{hyperref}yang membuat daftar di daftar isi tautan dapat diklik.

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

Jalankan skrip di direktori yang berisi file sumber

bash src2pdf

Itu akan membuat file yang disebut all.pdfdi direktori saat ini. Saya mencoba ini dengan beberapa file sumber acak yang saya temukan di sistem saya (khususnya, dua file dari sumber vlc-2.0.0) dan ini adalah tangkapan layar dari dua halaman pertama dari hasil PDF:

masukkan deskripsi gambar di sini


Beberapa komentar:

  • Skrip tidak akan berfungsi jika nama file kode sumber Anda berisi spasi. Karena kita berbicara tentang kode sumber, saya akan menganggap mereka tidak.
  • Saya menambahkan ! -name "*~"untuk menghindari file cadangan.
  • Saya sarankan Anda menggunakan findperintah yang lebih spesifik untuk menemukan file Anda, jika tidak, file acak apa pun akan disertakan dalam PDF. Jika semua file Anda memiliki ekstensi spesifik ( .cdan .hmisalnya), Anda harus mengganti findskrip dengan sesuatu seperti ini

    find . -name "*\.c" -o -name "\.h" | sed 's/^\..//' | 
  • Bermain-main dengan listings opsi , Anda dapat mengubah ini menjadi persis seperti yang Anda inginkan.
terdon
sumber
1
Wow, itulah yang saya sebut jawaban! :)
mpy
1
OMG terdon, Anda memiliki pertanyaan itu ^^. Untuk orang lain yang mencoba skrip: jika Anda mengalami src2pdf: line 36: warning: here-document at line 5 delimited by end-of-file (wanted EOF')saat menjalankan skrip Anda harus menghapus spasi putih pada baris EOF agar bisa berfungsi.
Bentley4
1
Jika file Anda disebut src2pdfkemudian masukkan ! -name "src2pdf"dalam findbaris dalam script seperti ini find . -type f ! -regex ".*/\..*" ! -name "src2pdf" ! -name ".*" ! -name "*~" |untuk menghilangkan dalam pdf.
Bentley4
1
@ Bentley4 terima kasih! Saya menghapus spasi (itu ditambahkan ketika saya menempelkan script ke jawabannya) dan menambahkan filter untuk menghapus script itu sendiri dari findhasil (saya telah menyimpan script di direktori lain yang ada di $ PATH saya jadi saya tidak punya itu masalah). Selain itu, Anda dapat mengubah bahasa yang digunakan untuk file sumber agar memiliki markup yang lebih baik dengan mengubah language=C++apa pun yang Anda inginkan, dapat menangani banyak bahasa berbeda, lihat di sini .
terdon
1
@ qubodup saya tidak begitu tahu. LaTeX dan UTF8 bisa rumit. Ini seharusnya bekerja dengan \usepackage[utf8]{inputenc} \ usepackage [jerman] {babel} `tetapi gagal pada pengujian saya. Namun, saya menduga saya tidak memberi makan utf8 benar. Itu mungkin bernilai pertanyaannya sendiri tetapi saya sarankan Anda bertanya di TeX - LaTeX , mereka harus tahu.
terdon
2

(dari StackOverflow )

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

Ini akan menghasilkan result.txt yang mengandung:

  • Nama file
  • pemisah (---)
  • Konten file .src
  • Ulangi dari atas sampai semua file * .src selesai

Jika kode sumber Anda memiliki ekstensi yang berbeda, ubah saja sesuai kebutuhan. Anda juga dapat mengedit bit gema untuk menambahkan informasi yang diperlukan (mungkin gema "nama file $ 1" atau mengubah pemisah, atau menambahkan pemisah akhir file).

tautan memiliki metode lain, jadi gunakan metode apa pun yang paling Anda sukai. Saya menemukan ini menjadi paling fleksibel, meskipun itu datang dengan sedikit kurva belajar.

Kode akan berjalan dengan sempurna dari terminal bash (baru saja diuji pada Ubuntu VirtualBox)

Jika Anda tidak peduli dengan nama file dan hanya peduli tentang konten file yang digabungkan:

cat *.src > result.txt

akan bekerja dengan baik.

Metode lain yang disarankan adalah:

grep "" *.src > result.txt

Yang akan mengawali setiap baris tunggal dengan nama file, yang bisa baik bagi sebagian orang, secara pribadi saya merasa terlalu banyak informasi, maka mengapa saran pertama saya adalah untuk loop di atas.

Penghargaan bagi mereka yang ada di forum orang StackOverflow.

EDIT: Saya baru menyadari bahwa Anda setelah khusus HTML atau PDF sebagai hasil akhirnya, beberapa solusi yang saya lihat adalah mencetak file teks ke dalam PostScript dan kemudian mengonversi postscript ke PDF. Beberapa kode yang pernah saya lihat:

groff -Tps result.txt > res.ps

kemudian

ps2pdf res.ps res.pdf 

(Mengharuskan Anda memiliki ghostscript)

Semoga ini membantu.

Darius
sumber
Ini hanya berfungsi untuk file dari ekstensi spesifik (.src) tapi saya ingin setiap file dimasukkan ke dalam pdf itu terlepas dari ekstensi. Saya ingin menghilangkan dir dan file yang tidak tersembunyi. Saya mengedit posting asli, dapatkah Anda melihatnya?
Bentley4
2

Saya tahu saya terlambat, tapi seseorang yang mencari solusi mungkin menemukan ini berguna.

Berdasarkan jawaban @ terdon, saya telah membuat skrip BASH yang berfungsi: https://github.com/eljuanchosf/source-code-to-pdf

eljuanchosf
sumber
Silakan kutip bagian-bagian penting dari jawaban dari tautan referensi, karena jawabannya dapat menjadi tidak valid jika halaman yang tertaut berubah.
DavidPostill