Làm cách nào tôi có thể tự động chuyển đổi tất cả các tệp mã nguồn trong một thư mục (đệ quy) thành một tệp PDF có tô sáng cú pháp?


29

Tôi muốn chuyển đổi mã nguồn của một vài dự án thành một tệp có thể in để lưu vào usb và in ra dễ dàng sau này. Làm thế nào tôi có thể làm điều đó?

Chỉnh sửa

Trước hết tôi muốn làm rõ rằng tôi chỉ muốn in các tệp và thư mục không bị ẩn (vì vậy không có nội dung nào của .gitví dụ).

Để có được danh sách tất cả các tệp không bị ẩn trong các thư mục không bị ẩn trong thư mục hiện tại, bạn có thể chạy find . -type f ! -regex ".*/\..*" ! -name ".*"lệnh như được xem như câu trả lời trong chuỗi này .

Như đã đề xuất trong cùng một chủ đề, tôi đã thử tạo một tệp pdf của các tệp bằng cách sử dụng lệnh find . -type f ! -regex ".*/\..*" ! -name ".*" ! -empty -print0 | xargs -0 a2ps -1 --delegate no -P pdfnhưng không may là tệp pdf kết quả là một mớ hỗn độn .


Không biết nó có phù hợp với nhu cầu của bạn không, nhưng với a2ps -P file *.srcbạn có thể tạo các tệp tin mô tả ra khỏi mã nguồn của mình. Nhưng các tập tin PS cần phải được chuyển đổi và kết hợp sau đó.
mpy

Sử dụng convert ( linux.about.com/od/commands/l/blcmdl1_convert.htm , fantemagick ), sau đó bạn sẽ có thể tạo một pdf từ các tệp ps.
SBI

Bạn có thể bình luận, ý của bạn là "hoàn toàn lộn xộn" không? Điều này ( i.stack.imgur.com/LoRhv.png ) có vẻ không quá tệ đối với tôi, bằng cách sử dụng a2ps -1 --delegate=0 -l 100 --line-numbers=5 -P pdf- Tôi đã thêm -l100 ký tự mỗi hàng để ngăn một số kết thúc từ và số dòng, nhưng đó chỉ là sở thích cá nhân.
mpy

Để chuyển đổi dự án này (4 tệp không ẩn không trống, mỗi tệp dài khoảng một trang trong các thư mục không bị ẩn) thành pdf, tôi có khoảng 5 trang mã nguồn và 39 trang vô nghĩa.
Bentley4

Câu trả lời:


47

Tôi bị thu hút bởi câu hỏi của bạn và đã mang đi. Giải pháp này sẽ tạo ra một tệp PDF đẹp với chỉ mục có thể nhấp và mã được tô sáng màu. Nó sẽ tìm tất cả các tệp trong thư mục và thư mục con hiện tại và tạo một phần trong tệp PDF cho mỗi tệp (xem các ghi chú bên dưới để biết cách làm cho lệnh find của bạn cụ thể hơn).

Nó yêu cầu bạn phải cài đặt như sau (hướng dẫn cài đặt dành cho các hệ thống dựa trên Debian nhưng chúng phải có sẵn trong kho lưu trữ phân phối của bạn):

  • pdflatex, colorlistings

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

    Điều này cũng sẽ cài đặt một hệ thống LaTeX cơ bản nếu bạn chưa cài đặt.

Khi chúng được cài đặt, hãy sử dụng tập lệnh này để tạo tài liệu LaTeX bằng mã nguồn của bạn. Thủ thuật là sử dụng các gói LaTeX listings(một phần của texlive-latex-recommended) và color(được cài đặt bởi latex-xcolor). Đây \usepackage[..]{hyperref}là những gì làm cho danh sách trong bảng nội dung liên kết có thể nhấp.

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

Chạy tập lệnh trong thư mục chứa các tệp nguồn

bash src2pdf

Điều đó sẽ tạo ra một tập tin được gọi all.pdftrong thư mục hiện tại. Tôi đã thử điều này với một vài tệp nguồn ngẫu nhiên tôi tìm thấy trên hệ thống của mình (cụ thể là hai tệp từ nguồn vlc-2.0.0) và đây là ảnh chụp màn hình của hai trang đầu tiên của tệp PDF kết quả:

nhập mô tả hình ảnh ở đây


Một vài ý kiến:

  • Tập lệnh sẽ không hoạt động nếu tên tệp mã nguồn của bạn chứa khoảng trắng. Vì chúng ta đang nói về mã nguồn, tôi sẽ cho rằng họ không.
  • Tôi đã thêm ! -name "*~"để tránh các tập tin sao lưu.
  • Tôi khuyên bạn nên sử dụng một findlệnh cụ thể hơn để tìm các tệp của mình, nếu không, bất kỳ tệp ngẫu nhiên nào cũng sẽ được đưa vào PDF. Nếu tất cả các tệp của bạn đều có tiện ích mở rộng cụ thể ( .c.hví dụ), bạn nên thay thế findtập lệnh bằng mã như thế này

    find . -name "*\.c" -o -name "\.h" | sed 's/^\..//' | 
  • Chơi xung quanh với các listings tùy chọn , bạn có thể điều chỉnh chính xác như bạn muốn.

1
Wow, đó là những gì tôi gọi là một câu trả lời! :)
mpy

1
OMG terdon, bạn sở hữu câu hỏi đó ^^. Đối với những người khác đang thử tập lệnh: nếu bạn gặp phải src2pdf: line 36: warning: here-document at line 5 delimited by end-of-file (wanted EOF')khi chạy tập lệnh, bạn phải xóa khoảng trắng trên dòng EOF để nó hoạt động.
Bentley4

1
Nếu tệp của bạn được gọi src2pdfthì hãy chèn ! -name "src2pdf"vào finddòng trong tập lệnh như thế này find . -type f ! -regex ".*/\..*" ! -name "src2pdf" ! -name ".*" ! -name "*~" |để bỏ qua nó trong pdf.
Bentley4

1
@ Bentley4 cảm ơn! Tôi đã xóa khoảng trắng (nó đã được thêm vào khi tôi dán đoạn mã vào câu trả lời) và thêm bộ lọc để xóa chính tập lệnh khỏi findkết quả (Tôi đã lưu tập lệnh trong một thư mục khác trong $ PATH của tôi để tôi không có vấn đề). Ngoài ra, bạn có thể thay đổi ngôn ngữ được sử dụng cho các tệp nguồn để có đánh dấu tốt hơn bằng cách thay đổi language=C++thành bất cứ điều gì bạn muốn, nó có thể xử lý nhiều ngôn ngữ khác nhau, xem tại đây .
terdon

1
@qubodup Tôi không thực sự biết. LaTeX và UTF8 có thể khó khăn. Nó sẽ hoạt động với \usepackage[utf8]{inputenc} \ usepackage [German] {babel} `nhưng nó không thành công trong các thử nghiệm của tôi. Tuy nhiên, tôi nghi ngờ tôi không cho nó ăn utf8 thật. Đó có thể là giá trị câu hỏi của riêng nó nhưng tôi khuyên bạn nên hỏi trên TeX - LaTeX , họ nên biết.
terdon

2

(từ StackOverflow )

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

Điều này sẽ dẫn đến một kết quả có chứa:

  • Tên tệp
  • dải phân cách (---)
  • Nội dung của tệp .src
  • Lặp lại từ đầu cho đến khi tất cả các tệp * .src được thực hiện

Nếu mã nguồn của bạn có phần mở rộng khác nhau, chỉ cần thay đổi khi cần thiết. Bạn cũng có thể chỉnh sửa bit echo để thêm thông tin cần thiết (có thể lặp lại "tên tệp $ 1" hoặc thay đổi dấu phân cách hoặc thêm dấu phân cách cuối tệp).

liên kết có các phương thức khác, vì vậy hãy sử dụng bất kỳ phương pháp nào bạn thích nhất. Tôi thấy cái này là linh hoạt nhất, mặc dù nó đi kèm với một đường cong học tập nhẹ.

Mã sẽ chạy hoàn hảo từ thiết bị đầu cuối bash (vừa được thử nghiệm trên VirtualBox Ubuntu)

Nếu bạn không quan tâm đến tên tệp và chỉ quan tâm đến nội dung của các tệp được hợp nhất với nhau:

cat *.src > result.txt

sẽ hoạt động hoàn toàn tốt

Một phương pháp khác được đề xuất là:

grep "" *.src > result.txt

Tiền tố này sẽ có tiền tố cho mỗi dòng với tên tệp, có thể tốt cho một số người, cá nhân tôi thấy nó có quá nhiều thông tin, do đó đề xuất đầu tiên của tôi là vòng lặp for ở trên.

Tín dụng cho những người trong diễn đàn StackOverflow.

EDIT: Tôi mới nhận ra rằng bạn là kết quả cuối cùng của HTML hoặc PDF, một số giải pháp tôi đã thấy là in tệp văn bản thành PostScript và sau đó chuyển đổi mô tả thành PDF. Một số mã tôi đã thấy:

groff -Tps result.txt > res.ps

sau đó

ps2pdf res.ps res.pdf 

(Yêu cầu bạn phải có ghostscript)

Hi vọng điêu nay co ich.


Điều này chỉ hoạt động cho các tệp của một phần mở rộng cụ thể (.src) nhưng tôi muốn mọi tệp được đặt trong pdf đó bất kể phần mở rộng. Tôi muốn bỏ qua các thư mục không ẩn và các tập tin không ẩn. Tôi đã chỉnh sửa bài viết gốc, bạn có thể xem nó không?
Bentley4

2

Tôi biết tôi đã đợi quá muộn, nhưng ai đó đang tìm giải pháp có thể thấy điều này hữu ích.

Dựa trên câu trả lời của @ terdon, tôi đã tạo một tập lệnh BASH thực hiện công việc: https://github.com/eljuanchosf/source-code-to-pdf


Vui lòng trích dẫn các phần thiết yếu của câu trả lời từ (các) liên kết tham chiếu, vì câu trả lời có thể trở nên không hợp lệ nếu (các) trang được liên kết thay đổi.
DavidPostill
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.