I'm using the following code (from this answer) to convert all CPP files in the current directory to a file named code.pdf and it works well:
find . -name "*.cpp" -print0 | xargs -0 enscript -Ecpp -MLetter -fCourier8 -o - | ps2pdf - code.pdf
I would like to improve this script to:
Make it a .sh file that can take an argument specifying the extension instead of having it hardcoded to CPP;
Have it run recursively, visiting all subdirectories of the current directory;
For each subdirectory encountered, convert all files of the specified extension to a single PDF that is named $NameOfDirectory$.PDF and is placed in that subdirectory;
First, if I understand it correctly, this requirement:
For each subdirectory encountered, convert all files of the specified extension to a single PDF that is named $NameOfDirectory$.PDF
is unwise. If that means, say, a/b/c/*.cpp
gets enscripted to ./c.pdf
, then you're screwed if you also have a/d/x/c/*.cpp
, since both directories' contents map to the same PDF. It also means that *.cpp
(i.e. CPP files in the current dir) gets enscripted to a file named ./..pdf
.
Something like this, which names the PDF according to the desired extension and places it in each subdirectory alongside its source files, doesn't have those problems:
#!/usr/bin/env bash
# USAGE: ext2pdf [<ext> [<root_dir>]]
# DEFAULTS: <ext> = cpp
# <root_dir> = .
ext="${1:-cpp}"
rootdir="${2:-.}"
shopt -s nullglob
find "$rootdir" -type d | while read d; do
# With "nullglob", this loop only runs if any $d/*.$ext files exist
for f in "$d"/*.${ext}; do
out="$d/$ext".pdf
# NOTE: Uncomment the following line instead if you want to risk name collisions
#out="${rootdir}/$(basename "$d")".pdf
enscript -Ecpp -MLetter -fCourier8 -o - "$d"/*.${ext} | ps2pdf - "$out"
break # We only want this to run once
done
done