Created
December 24, 2023 05:03
-
-
Save doraTeX/693c286638abfa4ee32c8f3740b6c0bc to your computer and use it in GitHub Desktop.
A shell script to join PDFs using macOS API ( https://doratex.hatenablog.jp/entry/20220330/1648629672 )
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
SCRIPTNAME=$(basename "$0") | |
function realpath () { | |
f=$@; | |
if [ -d "$f" ]; then | |
base=""; | |
dir="$f"; | |
else | |
base="/$(basename "$f")"; | |
dir=$(dirname "$f"); | |
fi; | |
dir=$(cd "$dir" && /bin/pwd); | |
echo "$dir$base" | |
} | |
function joinPDF () { | |
/usr/bin/osascript \ | |
-e 'use framework "Quartz"' \ | |
-e "global CA, NSURL, PDFDocument" \ | |
-e "set CA to current application" \ | |
-e "set NSURL to CA's NSURL" \ | |
-e "set PDFDocument to CA's PDFDocument" \ | |
-e "on pdfPageCount(pdfPath)" \ | |
-e "set url to NSURL's fileURLWithPath:pdfPath" \ | |
-e "set doc to PDFDocument's alloc's initWithURL:url" \ | |
-e "doc's pageCount()" \ | |
-e "end pdfPageCount" \ | |
-e "on joinPDF(pdfPaths, outputPath)" \ | |
-e "set newPDF to PDFDocument's alloc's init" \ | |
-e "set pageCount to 0" \ | |
-e "repeat with pdfPath in pdfPaths" \ | |
-e "set url to (NSURL's fileURLWithPath:pdfPath)" \ | |
-e "set doc to (PDFDocument's alloc's initWithURL:url)" \ | |
-e "set lastIndex to ((my pdfPageCount(pdfPath)) - 1)" \ | |
-e "repeat with i from 0 to lastIndex" \ | |
-e "(newPDF's insertPage:(doc's pageAtIndex:i) atIndex:pageCount)" \ | |
-e "set pageCount to (pageCount + 1)" \ | |
-e "end repeat" \ | |
-e "end repeat" \ | |
-e "newPDF's writeToFile:outputPath" \ | |
-e "end joinPDF" \ | |
-e "my joinPDF({$1}, \"$2\")" \ | |
> /dev/null | |
} | |
function usage() { | |
echo "Usage: $SCRIPTNAME -o <output> <input1> <input2> ..." | |
echo | |
echo "options:" | |
echo " -h, --help Show help" | |
echo " -o <output>, --output <output> Specify output file" | |
echo | |
} | |
# parse arguments | |
declare -a args=("$@") | |
declare -a params=() | |
OUTPUT="" | |
I=0 | |
while [ $I -lt ${#args[@]} ]; do | |
OPT="${args[$I]}" | |
case $OPT in | |
-h | --help ) | |
usage | |
exit 0 | |
;; | |
-o | --output ) | |
if [[ -z "${args[$(($I+1))]}" ]]; then | |
echo "$SCRIPTNAME: option requires an argument -- $OPT" 1>&2 | |
exit 1 | |
fi | |
OUTPUT="${args[$(($I+1))]}" | |
I=$(($I+1)) | |
;; | |
-- | -) | |
I=$(($I+1)) | |
while [ $I -lt ${#args[@]} ]; do | |
params+=("${args[$I]}") | |
I=$(($I+1)) | |
done | |
break | |
;; | |
-*) | |
echo "$SCRIPTNAME: illegal option -- '$(echo $OPT | sed 's/^-*//')'" 1>&2 | |
exit 1 | |
;; | |
*) | |
if [[ ! -z "$OPT" ]] && [[ ! "$OPT" =~ ^-+ ]]; then | |
params+=( "$OPT" ) | |
fi | |
;; | |
esac | |
I=$(($I+1)) | |
done | |
# handle invalid arguments | |
if [ ${#params[@]} -eq 0 ]; then | |
echo "$SCRIPTNAME: too few arguments" 1>&2 | |
echo "Try '$SCRIPTNAME --help' for more information." 1>&2 | |
exit 1 | |
fi | |
if [ "$OUTPUT" = "" ]; then | |
echo "Option -o cannot be omitted." | |
echo "Try '$SCRIPTNAME --help' for more information." 1>&2 | |
exit 1 | |
fi | |
# change input path list into AppleScript style | |
declare -a list=() | |
for FILE in "${params[@]}"; do | |
list+=("\"$(realpath $FILE)\"") | |
done | |
INPUTS="$(echo "$(IFS=","; echo "${list[*]}")")" | |
# join PDFs | |
joinPDF "$INPUTS" "$OUTPUT" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment