|
@@ -0,0 +1,121 @@
|
|
|
|
|
+#!/usr/bin/zsh
|
|
|
|
|
+
|
|
|
|
|
+usage() {
|
|
|
|
|
+ echo "Usage: $0 [-q quality] [--no-transitions] input.pdf"
|
|
|
|
|
+ echo " -q quality Set output quality level (0: screen, 1: ebook (default), 2: prepress)"
|
|
|
|
|
+ echo " --no-transitions Remove transitional pages (keep only the last frame before slide number changes)"
|
|
|
|
|
+ exit 1
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# Default values
|
|
|
|
|
+quality=1
|
|
|
|
|
+remove_transitions=0
|
|
|
|
|
+
|
|
|
|
|
+# Parse arguments
|
|
|
|
|
+while [[ $# -gt 0 ]]; do
|
|
|
|
|
+ case "$1" in
|
|
|
|
|
+ -q)
|
|
|
|
|
+ shift
|
|
|
|
|
+ if [[ "$1" =~ ^[0-2]$ ]]; then
|
|
|
|
|
+ quality=$1
|
|
|
|
|
+ else
|
|
|
|
|
+ echo "Invalid quality level. Use 0 (screen), 1 (ebook), or 2 (prepress)."
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ fi
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --no-transitions)
|
|
|
|
|
+ remove_transitions=1
|
|
|
|
|
+ ;;
|
|
|
|
|
+ -*)
|
|
|
|
|
+ echo "Unknown option: $1"
|
|
|
|
|
+ usage
|
|
|
|
|
+ ;;
|
|
|
|
|
+ *)
|
|
|
|
|
+ input_file="$1"
|
|
|
|
|
+ ;;
|
|
|
|
|
+ esac
|
|
|
|
|
+ shift
|
|
|
|
|
+done
|
|
|
|
|
+
|
|
|
|
|
+# Check if input file is provided
|
|
|
|
|
+if [[ -z "$input_file" ]]; then
|
|
|
|
|
+ echo "Error: No input file provided."
|
|
|
|
|
+ usage
|
|
|
|
|
+fi
|
|
|
|
|
+
|
|
|
|
|
+# Set Ghostscript quality settings
|
|
|
|
|
+case "$quality" in
|
|
|
|
|
+ 0) gs_quality="/screen" ;;
|
|
|
|
|
+ 1) gs_quality="/ebook" ;;
|
|
|
|
|
+ 2) gs_quality="/prepress" ;;
|
|
|
|
|
+esac
|
|
|
|
|
+
|
|
|
|
|
+# Create temporary file
|
|
|
|
|
+temp_file=$(mktemp)
|
|
|
|
|
+
|
|
|
|
|
+# Uncompress PDF and remove annotations
|
|
|
|
|
+pdftk "$input_file" output - uncompress | sed '/^\/Annots/d' > "$temp_file.pdf"
|
|
|
|
|
+
|
|
|
|
|
+if [[ $remove_transitions -eq 1 ]]; then
|
|
|
|
|
+ # Run dump_data once and capture its output.
|
|
|
|
|
+ dump=$(pdftk "$temp_file.pdf" dump_data)
|
|
|
|
|
+
|
|
|
|
|
+ # Get the total number of pages.
|
|
|
|
|
+ total_pages=$(echo "$dump" | awk '/^NumberOfPages/ { print $2 }')
|
|
|
|
|
+
|
|
|
|
|
+ # Read all PageLabelNewIndex values into an array.
|
|
|
|
|
+ new_indexes=($(echo "$dump" | awk '/^PageLabelNewIndex/ { print $2 }'))
|
|
|
|
|
+
|
|
|
|
|
+ endings=()
|
|
|
|
|
+
|
|
|
|
|
+ # Compute end pages for all groups except the first.
|
|
|
|
|
+ # For each boundary between slides:
|
|
|
|
|
+ # If the difference is >1, the previous slide spans multiple pages:
|
|
|
|
|
+ # so use (current new index – 1) as the end page.
|
|
|
|
|
+ # If the difference is exactly 1, then the previous slide is a single page;
|
|
|
|
|
+ # so keep its PageLabelNewIndex.
|
|
|
|
|
+ for ((i=1; i < ${#new_indexes[@]}; i++)); do
|
|
|
|
|
+ prev=${new_indexes[i-1]}
|
|
|
|
|
+ curr=${new_indexes[i]}
|
|
|
|
|
+ if (( curr - prev == 1 )); then
|
|
|
|
|
+ endings+=($prev)
|
|
|
|
|
+ else
|
|
|
|
|
+ endings+=($((curr - 1)))
|
|
|
|
|
+ fi
|
|
|
|
|
+ done
|
|
|
|
|
+
|
|
|
|
|
+ # For the final slide group:
|
|
|
|
|
+ last_index=${new_indexes[-1]}
|
|
|
|
|
+ if (( total_pages - last_index == 0 )); then
|
|
|
|
|
+ # Single–frame slide.
|
|
|
|
|
+ endings+=($last_index)
|
|
|
|
|
+ else
|
|
|
|
|
+ # Multi–frame slide.
|
|
|
|
|
+ endings+=($total_pages)
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ # Remove duplicates (if any) and sort in ascending order.
|
|
|
|
|
+ pages_to_keep=($(echo "${endings[@]}" | tr ' ' '\n' | sort -n | uniq))
|
|
|
|
|
+
|
|
|
|
|
+ # (Optional: Uncomment to debug)
|
|
|
|
|
+ # echo "Pages to keep: ${pages_to_keep[@]}"
|
|
|
|
|
+
|
|
|
|
|
+ if [[ ${#pages_to_keep[@]} -gt 0 ]]; then
|
|
|
|
|
+ pdftk "$temp_file.pdf" cat ${pages_to_keep[@]} output "$temp_file-clean.pdf"
|
|
|
|
|
+ if [[ $? -ne 0 ]]; then
|
|
|
|
|
+ echo "Error: Failed to remove transitional pages."
|
|
|
|
|
+ rm "$temp_file.pdf"
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ fi
|
|
|
|
|
+ mv "$temp_file-clean.pdf" "$temp_file.pdf"
|
|
|
|
|
+ else
|
|
|
|
|
+ echo "Warning: No transitional pages identified; keeping full document."
|
|
|
|
|
+ fi
|
|
|
|
|
+fi
|
|
|
|
|
+
|
|
|
|
|
+# Compress the PDF
|
|
|
|
|
+gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS="$gs_quality" -dNOPAUSE -dQUIET -dBATCH -sOutputFile="${input_file%.pdf}-compressed.pdf" "$temp_file.pdf"
|
|
|
|
|
+
|
|
|
|
|
+# Clean up
|
|
|
|
|
+rm "$temp_file.pdf"
|
|
|
|
|
+
|