| @@ -48,6 +48,8 @@ ADAPTIVEMODE=$TRUE # Automatically try to guess best mode | |||||
| AUTOMATIC_SCALING=$TRUE # Default scaling in $SCALE, override by resize mode | AUTOMATIC_SCALING=$TRUE # Default scaling in $SCALE, override by resize mode | ||||
| MODE="" | MODE="" | ||||
| RESIZE_PAPER_TYPE="" | RESIZE_PAPER_TYPE="" | ||||
| CUSTOM_RESIZE_PAPER=$FALSE | |||||
| FLIP_DETECTION=$TRUE | |||||
| PGWIDTH="" | PGWIDTH="" | ||||
| PGHEIGHT="" | PGHEIGHT="" | ||||
| RESIZE_WIDTH="" | RESIZE_WIDTH="" | ||||
| @@ -76,7 +78,7 @@ EXIT_INVALID_PAPER_SIZE=50 | |||||
| # Main function called at the end | # Main function called at the end | ||||
| main() { | main() { | ||||
| printVersion 1 'verbose' | printVersion 1 'verbose' | ||||
| loadDeps | |||||
| checkDeps | |||||
| vprint " Input file: $INFILEPDF" | vprint " Input file: $INFILEPDF" | ||||
| vprint " Output file: $OUTFILEPDF" | vprint " Output file: $OUTFILEPDF" | ||||
| getPageSize | getPageSize | ||||
| @@ -118,7 +120,7 @@ main() { | |||||
| ########################## INITIALIZER ########################## | ########################## INITIALIZER ########################## | ||||
| # Loads external dependencies and checks for errors | # Loads external dependencies and checks for errors | ||||
| loadDeps() { | |||||
| initDeps() { | |||||
| GSBIN="$(which gs 2>/dev/null)" | GSBIN="$(which gs 2>/dev/null)" | ||||
| BCBIN="$(which bc 2>/dev/null)" | BCBIN="$(which bc 2>/dev/null)" | ||||
| IDBIN=$(which identify 2>/dev/null) | IDBIN=$(which identify 2>/dev/null) | ||||
| @@ -128,8 +130,11 @@ loadDeps() { | |||||
| vprint "Checking for ghostscript and bcmath" | vprint "Checking for ghostscript and bcmath" | ||||
| if notIsAvailable "$GSBIN"; then printDependency 'ghostscript'; fi | if notIsAvailable "$GSBIN"; then printDependency 'ghostscript'; fi | ||||
| if notIsAvailable "$BCBIN"; then printDependency 'bc'; fi | if notIsAvailable "$BCBIN"; then printDependency 'bc'; fi | ||||
| if [[ $MODE = "IDENTIFY" ]]; then | |||||
| } | |||||
| # Checks for dependencies errors, run after getting options | |||||
| checkDeps() { | |||||
| if [[ $MODE = "IDENTIFY" ]]; then | |||||
| vprint "Checking for imagemagick's identify" | vprint "Checking for imagemagick's identify" | ||||
| if notIsAvailable "$IDBIN"; then printDependency 'imagemagick'; fi | if notIsAvailable "$IDBIN"; then printDependency 'imagemagick'; fi | ||||
| fi | fi | ||||
| @@ -150,7 +155,7 @@ loadDeps() { | |||||
| # Parse options | # Parse options | ||||
| getOptions() { | getOptions() { | ||||
| while getopts ":vhVs:m:r:p" o; do | |||||
| while getopts ":vhVs:m:r:pf" o; do | |||||
| case "${o}" in | case "${o}" in | ||||
| v) | v) | ||||
| ((VERBOSE++)) | ((VERBOSE++)) | ||||
| @@ -176,6 +181,9 @@ getOptions() { | |||||
| printPaperInfo | printPaperInfo | ||||
| exit $EXIT_SUCCESS | exit $EXIT_SUCCESS | ||||
| ;; | ;; | ||||
| f) | |||||
| FLIP_DETECTION=$FALSE | |||||
| ;; | |||||
| *) | *) | ||||
| initError "Invalid Option: -$OPTARG" $EXIT_INVALID_OPTION | initError "Invalid Option: -$OPTARG" $EXIT_INVALID_OPTION | ||||
| ;; | ;; | ||||
| @@ -206,15 +214,16 @@ getOptions() { | |||||
| # Parses and validates the scaling factor | # Parses and validates the scaling factor | ||||
| parseScale() { | parseScale() { | ||||
| AUTOMATIC_SCALING=$FALSE | AUTOMATIC_SCALING=$FALSE | ||||
| if ! [[ -n "$1" && "$1" =~ ^-?[0-9]*([.][0-9]+)?$ && (($1 > 0 )) ]] ; then | |||||
| if ! isFloatBiggerThanZero "$1"; then | |||||
| printError "Invalid factor: $1" | printError "Invalid factor: $1" | ||||
| printError "The factor must be a floating point number greater than 0" | printError "The factor must be a floating point number greater than 0" | ||||
| printError "Example: for 80% use 0.8" | printError "Example: for 80% use 0.8" | ||||
| exit $EXIT_INVALID_SCALE | exit $EXIT_INVALID_SCALE | ||||
| fi | fi | ||||
| SCALE=$1 | |||||
| SCALE="$1" | |||||
| } | } | ||||
| ###################### GHOSTSCRIPT CALLS ####################### | ###################### GHOSTSCRIPT CALLS ####################### | ||||
| # Runs the ghostscript scaling script | # Runs the ghostscript scaling script | ||||
| @@ -241,16 +250,16 @@ pageScale() { | |||||
| # Runs the ghostscript paper resize script | # Runs the ghostscript paper resize script | ||||
| pageResize() { | pageResize() { | ||||
| getGSPaperSize "$RESIZE_PAPER_TYPE" | |||||
| isNotCustomPaper && getGSPaperSize "$RESIZE_PAPER_TYPE" | |||||
| local tmpInverter="" | local tmpInverter="" | ||||
| if [[ $PGWIDTH -gt $PGHEIGHT && $RESIZE_WIDTH -lt $RESIZE_HEIGHT ]]; then | |||||
| if [[ $FLIP_DETECTION -eq $TRUE && $PGWIDTH -gt $PGHEIGHT && $RESIZE_WIDTH -lt $RESIZE_HEIGHT ]]; then | |||||
| vprint " Flip Detect: Wrong orientation!" | vprint " Flip Detect: Wrong orientation!" | ||||
| vprint " Inverting Width <-> Height" | vprint " Inverting Width <-> Height" | ||||
| tmpInverter=$RESIZE_HEIGHT | tmpInverter=$RESIZE_HEIGHT | ||||
| RESIZE_HEIGHT=$RESIZE_WIDTH | RESIZE_HEIGHT=$RESIZE_WIDTH | ||||
| RESIZE_WIDTH=$tmpInverter | RESIZE_WIDTH=$tmpInverter | ||||
| fi | fi | ||||
| vprint " Resizing to: $(uppercase $RESIZE_PAPER_TYPE) ( $RESIZE_WIDTH x $RESIZE_HEIGHT )" | |||||
| vprint " Resizing to: $(uppercase $RESIZE_PAPER_TYPE) ( $RESIZE_WIDTH x $RESIZE_HEIGHT ) pts" | |||||
| # Change page size | # Change page size | ||||
| "$GSBIN" \ | "$GSBIN" \ | ||||
| @@ -267,7 +276,6 @@ pageResize() { | |||||
| } | } | ||||
| ################### PDF PAGE SIZE DETECTION #################### | ################### PDF PAGE SIZE DETECTION #################### | ||||
| # Parse a forced mode of operation | # Parse a forced mode of operation | ||||
| @@ -611,7 +619,8 @@ flsa flse halfletter hagaki) | |||||
| printPaperNames() { | printPaperNames() { | ||||
| isEmpty "$paperNames" && getPaperNames | isEmpty "$paperNames" && getPaperNames | ||||
| for i in "${!paperNames[@]}"; do | for i in "${!paperNames[@]}"; do | ||||
| [[ $i -ne 0 && $((i % 5)) -eq 0 ]] && echo "" | |||||
| [[ $i -eq 0 ]] && echo -n -e ' ' | |||||
| [[ $i -ne 0 && $((i % 5)) -eq 0 ]] && echo -n -e $'\n ' | |||||
| ppN="$(uppercase ${paperNames[i]})" | ppN="$(uppercase ${paperNames[i]})" | ||||
| printf "%-14s" "$ppN" | printf "%-14s" "$ppN" | ||||
| done | done | ||||
| @@ -677,8 +686,62 @@ printPaperTable() { | |||||
| parsePaperResize() { | parsePaperResize() { | ||||
| isEmpty "$1" && initError 'Invalid Paper Type: (empty)' $EXIT_INVALID_PAPER_SIZE | isEmpty "$1" && initError 'Invalid Paper Type: (empty)' $EXIT_INVALID_PAPER_SIZE | ||||
| local lowercasePaper="$(lowercase $1)" | local lowercasePaper="$(lowercase $1)" | ||||
| isPaperName "$lowercasePaper" || initError "Invalid Paper Type: $1" $EXIT_INVALID_PAPER_SIZE | |||||
| RESIZE_PAPER_TYPE="$lowercasePaper" | |||||
| if [[ "$1" = 'custom' ]]; then | |||||
| if isNotValidMeasure "$2" || ! isFloatBiggerThanZero "$3" || ! isFloatBiggerThanZero "$4"; then | |||||
| initError "Invalid Custom Paper Definition!"$'\n'"Use: -r 'custom <measurement> <width> <height>'"$'\n'"Measurements: mm, in, pts" $EXIT_INVALID_OPTION | |||||
| fi | |||||
| RESIZE_PAPER_TYPE="custom" | |||||
| CUSTOM_RESIZE_PAPER=$TRUE | |||||
| if isMilimeter "$2"; then | |||||
| RESIZE_WIDTH="$(milimetersToPoints "$3")" | |||||
| RESIZE_HEIGHT="$(milimetersToPoints "$4")" | |||||
| elif isInch "$2"; then | |||||
| RESIZE_WIDTH="$(inchesToPoints "$3")" | |||||
| RESIZE_HEIGHT="$(inchesToPoints "$4")" | |||||
| elif isPoint "$2"; then | |||||
| RESIZE_WIDTH="$3" | |||||
| RESIZE_HEIGHT="$4" | |||||
| else | |||||
| initError "Invalid Custom Paper Definition!"$'\n'"Use: -r 'custom <measurement> <width> <height>'"$'\n'"Measurements: mm, in, pts" $EXIT_INVALID_OPTION | |||||
| fi | |||||
| else | |||||
| isPaperName "$lowercasePaper" || initError "Invalid Paper Type: $1" $EXIT_INVALID_PAPER_SIZE | |||||
| RESIZE_PAPER_TYPE="$lowercasePaper" | |||||
| fi | |||||
| } | |||||
| # Returns $TRUE if $1 is a valid measurement for a custom paper, $FALSE otherwise | |||||
| isNotValidMeasure() { | |||||
| isMilimeter "$1" || isInch "$1" || isPoint "$1" && return $FALSE | |||||
| return $TRUE | |||||
| } | |||||
| # Returns $TRUE if $1 is a valid milimeter string, $FALSE otherwise | |||||
| isMilimeter() { | |||||
| [[ "$1" = 'mm' || "$1" = 'milimeters' || "$1" = 'milimeter' ]] && return $TRUE | |||||
| return $FALSE | |||||
| } | |||||
| # Returns $TRUE if $1 is a valid inch string, $FALSE otherwise | |||||
| isInch() { | |||||
| [[ "$1" = 'in' || "$1" = 'inch' || "$1" = 'inches' ]] && return $TRUE | |||||
| return $FALSE | |||||
| } | |||||
| # Returns $TRUE if $1 is a valid point string, $FALSE otherwise | |||||
| isPoint() { | |||||
| [[ "$1" = 'pt' || "$1" = 'pts' || "$1" = 'point' || "$1" = 'points' ]] && return $TRUE | |||||
| return $FALSE | |||||
| } | |||||
| # Returns $TRUE if a custom paper is being used, $FALSE otherwise | |||||
| isCustomPaper() { | |||||
| return $CUSTOM_RESIZE_PAPER | |||||
| } | |||||
| isNotCustomPaper() { | |||||
| isCustomPaper && return $FALSE | |||||
| return $TRUE | |||||
| } | } | ||||
| # Returns $TRUE if the scale was set manually, $FALSE if we are using automatic scaling | # Returns $TRUE if the scale was set manually, $FALSE if we are using automatic scaling | ||||
| @@ -747,10 +810,22 @@ uppercase() { | |||||
| done | done | ||||
| } | } | ||||
| # Prints the postscript points rounded equivalent from $1 mm | |||||
| milimetersToPoints() { | |||||
| local pts=$(echo "scale=6; $1 * 72 / 25.4" | "$BCBIN") | |||||
| printf '%.0f' "$pts" # Print rounded conversion | |||||
| } | |||||
| # Prints the postscript points rounded equivalent from $1 mm | |||||
| inchesToPoints() { | |||||
| local pts=$(echo "scale=6; $1 * 72" | "$BCBIN") | |||||
| printf '%.0f' "$pts" # Print rounded conversion | |||||
| } | |||||
| ########################## VALIDATORS ########################## | ########################## VALIDATORS ########################## | ||||
| # Returns $TRUE if $PGWIDTH OR $PGWIDTH are empty or NOT an Integer, false otherwise | |||||
| # Returns $TRUE if $PGWIDTH OR $PGWIDTH are empty or NOT an Integer, $FALSE otherwise | |||||
| pageSizeIsInvalid() { | pageSizeIsInvalid() { | ||||
| if isNotAnInteger "$PGWIDTH" || isNotAnInteger "$PGHEIGHT"; then | if isNotAnInteger "$PGWIDTH" || isNotAnInteger "$PGHEIGHT"; then | ||||
| return $TRUE | return $TRUE | ||||
| @@ -759,33 +834,33 @@ pageSizeIsInvalid() { | |||||
| } | } | ||||
| # Return $TRUE if adaptive mode is enabled, false otherwise | |||||
| # Return $TRUE if adaptive mode is enabled, $FALSE otherwise | |||||
| isAdaptiveMode() { | isAdaptiveMode() { | ||||
| return $ADAPTIVEMODE | return $ADAPTIVEMODE | ||||
| } | } | ||||
| # Return $TRUE if adaptive mode is disabled, false otherwise | |||||
| # Return $TRUE if adaptive mode is disabled, $FALSE otherwise | |||||
| isNotAdaptiveMode() { | isNotAdaptiveMode() { | ||||
| isAdaptiveMode && return $FALSE | isAdaptiveMode && return $FALSE | ||||
| return $TRUE | return $TRUE | ||||
| } | } | ||||
| # Return $TRUE if $1 is empty, false otherwise | |||||
| # Return $TRUE if $1 is empty, $FALSE otherwise | |||||
| isEmpty() { | isEmpty() { | ||||
| [[ -z "$1" ]] && return $TRUE | [[ -z "$1" ]] && return $TRUE | ||||
| return $FALSE | return $FALSE | ||||
| } | } | ||||
| # Return $TRUE if $1 is NOT empty, false otherwise | |||||
| # Return $TRUE if $1 is NOT empty, $FALSE otherwise | |||||
| isNotEmpty() { | isNotEmpty() { | ||||
| [[ -z "$1" ]] && return $FALSE | [[ -z "$1" ]] && return $FALSE | ||||
| return $TRUE | return $TRUE | ||||
| } | } | ||||
| # Returns $TRUE if $1 is an integer, $FALSE otherwise | |||||
| isAnInteger() { | isAnInteger() { | ||||
| case $1 in | case $1 in | ||||
| ''|*[!0-9]*) return $FALSE ;; | ''|*[!0-9]*) return $FALSE ;; | ||||
| @@ -793,7 +868,7 @@ isAnInteger() { | |||||
| esac | esac | ||||
| } | } | ||||
| # Returns $TRUE if $1 is NOT an integer, $FALSE otherwise | |||||
| isNotAnInteger() { | isNotAnInteger() { | ||||
| case $1 in | case $1 in | ||||
| ''|*[!0-9]*) return $TRUE ;; | ''|*[!0-9]*) return $TRUE ;; | ||||
| @@ -801,6 +876,17 @@ isNotAnInteger() { | |||||
| esac | esac | ||||
| } | } | ||||
| # Returns $TRUE if $1 is a floating point number (or an integer), $FALSE otherwise | |||||
| isFloat() { | |||||
| [[ -n "$1" && "$1" =~ ^-?[0-9]*([.][0-9]+)?$ ]] && return $TRUE | |||||
| return $FALSE | |||||
| } | |||||
| # Returns $TRUE if $1 is a floating point number bigger than zero, $FALSE otherwise | |||||
| isFloatBiggerThanZero() { | |||||
| isFloat "$1" && [[ (( $1 > 0 )) ]] && return $TRUE | |||||
| return $FALSE | |||||
| } | |||||
| # Returns $TRUE if $1 has a .pdf extension, false otherwsie | # Returns $TRUE if $1 has a .pdf extension, false otherwsie | ||||
| isPDF() { | isPDF() { | ||||
| @@ -892,30 +978,32 @@ Parameters: | |||||
| Eg. -s 0.8 for 80% of the original size | Eg. -s 0.8 for 80% of the original size | ||||
| -r <paper> Triggers the Resize Paper Mode | -r <paper> Triggers the Resize Paper Mode | ||||
| Resize PDF paper proportionally | Resize PDF paper proportionally | ||||
| Must be a valid Ghostscript paper name | |||||
| A valid paper name or a custom defined paper | |||||
| -f Disables the flip detection, paper will not be | |||||
| rotated to landscape when needed (resize-only) | |||||
| -p Prints Ghostscript paper info tables to screen | -p Prints Ghostscript paper info tables to screen | ||||
| Scaling Mode: | Scaling Mode: | ||||
| The default mode of operation is scaling mode with fixed paper | |||||
| size and scaling pre-set to $SCALE. By not using the resize mode | |||||
| you are using scaling mode. | |||||
| The default mode of operation is scaling mode with fixed paper | |||||
| size and scaling pre-set to $SCALE. By not using the resize mode | |||||
| you are using scaling mode. | |||||
| Resize Paper Mode: | Resize Paper Mode: | ||||
| Disables the default scaling factor! ($SCALE) | |||||
| Alternative mode of operation to change the PDF paper | |||||
| proportionally. Will fit-to-page. | |||||
| Disables the default scaling factor! ($SCALE) | |||||
| Alternative mode of operation to change the PDF paper | |||||
| proportionally. Will fit-to-page. | |||||
| Mixed Mode: | Mixed Mode: | ||||
| In mixed mode both the -s option and -r option must be specified. | |||||
| The PDF will be both scaled and have the paper type changed. | |||||
| In mixed mode both the -s option and -r option must be specified. | |||||
| The PDF will be first resized then scaled. | |||||
| Output filename: | Output filename: | ||||
| The output filename is optional. If no file name is passed | |||||
| the output file will have the same name/destination of the | |||||
| input file with added suffixes: | |||||
| .SCALED.pdf is added to scaled files | |||||
| .<PAPERSIZE>.pdf is added to resized files | |||||
| .<PAPERSIZE>.SCALED.pdf is added in mixed mode | |||||
| The output filename is optional. If no file name is passed | |||||
| the output file will have the same name/destination of the | |||||
| input file with added suffixes: | |||||
| .SCALED.pdf is added to scaled files | |||||
| .<PAPERSIZE>.pdf is added to resized files | |||||
| .<PAPERSIZE>.SCALED.pdf is added in mixed mode | |||||
| Page Detection Modes: | Page Detection Modes: | ||||
| a, adaptive Default mode, tries all the methods below | a, adaptive Default mode, tries all the methods below | ||||
| @@ -927,6 +1015,14 @@ Page Detection Modes: | |||||
| Valid Ghostscript Paper Names: | Valid Ghostscript Paper Names: | ||||
| $paperList | $paperList | ||||
| Custom Paper Size: | |||||
| Paper size can be set manually in Milimeters, Inches or Points. | |||||
| Use: $PDFSCALE_NAME -r 'custom <measurement> <width> <height>' | |||||
| Ex: $PDFSCALE_NAME -r 'custom mm 210 297' | |||||
| Measurements can be: mm, inch, pts. | |||||
| Custom paper definition MUST be quoted into a single parameter. | |||||
| Actual size is applied in points (mms and inches are transformed). | |||||
| Notes: | Notes: | ||||
| - Adaptive Page size detection will try different modes until | - Adaptive Page size detection will try different modes until | ||||
| it gets a page size. You can force a mode with -m 'mode'. | it gets a page size. You can force a mode with -m 'mode'. | ||||
| @@ -939,11 +1035,13 @@ Notes: | |||||
| Examples: | Examples: | ||||
| $PDFSCALE_NAME myPdfFile.pdf | $PDFSCALE_NAME myPdfFile.pdf | ||||
| $PDFSCALE_NAME myPdfFile.pdf myScaledPdf | |||||
| $PDFSCALE_NAME myPdfFile.pdf \"My Scaled Pdf\" | |||||
| $PDFSCALE_NAME -v -v myPdfFile.pdf | $PDFSCALE_NAME -v -v myPdfFile.pdf | ||||
| $PDFSCALE_NAME -s 0.85 myPdfFile.pdf myScaledPdf.pdf | |||||
| $PDFSCALE_NAME -s 0.85 myPdfFile.pdf My\\ Scaled\\ Pdf.pdf | |||||
| $PDFSCALE_NAME -m pdfinfo -s 0.80 -v myPdfFile.pdf | $PDFSCALE_NAME -m pdfinfo -s 0.80 -v myPdfFile.pdf | ||||
| $PDFSCALE_NAME -v -v -m i -s 0.7 myPdfFile.pdf | $PDFSCALE_NAME -v -v -m i -s 0.7 myPdfFile.pdf | ||||
| $PDFSCALE_NAME -r A4 myPdfFile.pdf | |||||
| $PDFSCALE_NAME -v -v -r \"custom mm 252 356\" -s 0.9 -f \"../input file.pdf\" \"../my new pdf\" | |||||
| $PDFSCALE_NAME -h | $PDFSCALE_NAME -h | ||||
| " | " | ||||
| } | } | ||||
| @@ -1001,6 +1099,7 @@ printError() { | |||||
| ########################## EXECUTION ########################### | ########################## EXECUTION ########################### | ||||
| initDeps | |||||
| getOptions "${@}" | getOptions "${@}" | ||||
| main | main | ||||
| exit $? | exit $? | ||||