Bash Script to scale and/or resize PDFs from the command line.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

1271 行
42 KiB

  1. #!/usr/bin/env bash
  2. # pdfScale.sh
  3. #
  4. # Scale PDF to specified percentage of original size.
  5. #
  6. # Gustavo Arnosti Neves - 2016 / 07 / 10
  7. # Latest Version - 2017 / 05 / 14
  8. #
  9. # This script: https://github.com/tavinus/pdfScale
  10. # Based on: http://ma.juii.net/blog/scale-page-content-of-pdf-files
  11. # And: https://gist.github.com/MichaelJCole/86e4968dbfc13256228a
  12. VERSION="2.0.0"
  13. ###################### EXTERNAL PROGRAMS #######################
  14. GSBIN="" # GhostScript Binary
  15. BCBIN="" # BC Math Binary
  16. IDBIN="" # Identify Binary
  17. PDFINFOBIN="" # PDF Info Binary
  18. MDLSBIN="" # MacOS mdls Binary
  19. ##################### ENVIRONMENT SET-UP #######################
  20. LC_MEASUREMENT="C" # To make sure our numbers have .decimals
  21. LC_ALL="C" # Some languages use , as decimal token
  22. LC_CTYPE="C"
  23. LC_NUMERIC="C"
  24. TRUE=0 # Silly stuff
  25. FALSE=1
  26. ########################### GLOBALS ############################
  27. SCALE="0.95" # scaling factor (0.95 = 95%, e.g.)
  28. VERBOSE=0 # verbosity Level
  29. PDFSCALE_NAME="$(basename $0)" # simplified name of this script
  30. OSNAME="$(uname 2>/dev/null)" # Check where we are running
  31. JUST_IDENTIFY=$FALSE # Flag to just show PDF info
  32. ADAPTIVEMODE=$TRUE # Automatically try to guess best mode
  33. AUTOMATIC_SCALING=$TRUE # Default scaling in $SCALE, override by resize mode
  34. MODE="" # Which page size detection to use
  35. RESIZE_PAPER_TYPE="" # Pre-defined paper to use
  36. CUSTOM_RESIZE_PAPER=$FALSE # If we are using a custom-defined paper
  37. FLIP_DETECTION=$TRUE # If we shoudl run the Flip-detection
  38. FLIP_FORCE=$FALSE # If we should force Flipping
  39. AUTO_ROTATION='/PageByPage' # GS cal auto-rotation setting
  40. PGWIDTH="" # Input PDF Page Width
  41. PGHEIGHT="" # Input PDF Page Height
  42. RESIZE_WIDTH="" # Resized PDF Page Width
  43. RESIZE_HEIGHT="" # Resized PDF Page Height
  44. ########################## EXIT FLAGS ##########################
  45. EXIT_SUCCESS=0
  46. EXIT_ERROR=1
  47. EXIT_INVALID_PAGE_SIZE_DETECTED=10
  48. EXIT_FILE_NOT_FOUND=20
  49. EXIT_INPUT_NOT_PDF=21
  50. EXIT_INVALID_OPTION=22
  51. EXIT_NO_INPUT_FILE=23
  52. EXIT_INVALID_SCALE=24
  53. EXIT_MISSING_DEPENDENCY=25
  54. EXIT_IMAGEMAGIK_NOT_FOUND=26
  55. EXIT_MAC_MDLS_NOT_FOUND=27
  56. EXIT_PDFINFO_NOT_FOUND=28
  57. EXIT_TEMP_FILE_EXISTS=40
  58. EXIT_INVALID_PAPER_SIZE=50
  59. ############################# MAIN #############################
  60. # Main function called at the end
  61. main() {
  62. checkDeps
  63. printPDFSizes
  64. vprint " Input File: $INFILEPDF"
  65. vprint " Output File: $OUTFILEPDF"
  66. getPageSize
  67. vPrintPageSizes ' Source'
  68. local finalRet=$EXIT_ERROR
  69. local tempFile=""
  70. local tempSuffix="$RANDOM$RANDOM""_TEMP_$RANDOM$RANDOM.pdf"
  71. if isMixedMode; then
  72. outputFile="$OUTFILEPDF" # backup outFile name
  73. tempFile="${OUTFILEPDF%.pdf}.$tempSuffix" # set a temp file name
  74. if isFile "$tempFile"; then
  75. printError $'Error! Temporary file name already exists!\n'"File: $tempFile"$'\nAborting execution to avoid overwriting the file.\nPlease Try again...'
  76. exit $EXIT_TEMP_FILE_EXISTS
  77. fi
  78. OUTFILEPDF="$tempFile" # set output to tmp file
  79. pageResize # resize to tmp file
  80. finalRet=$?
  81. INFILEPDF="$tempFile" # get tmp file as input
  82. OUTFILEPDF="$outputFile" # reset final target
  83. PGWIDTH=$RESIZE_WIDTH # we already know the new page size
  84. PGHEIGHT=$RESIZE_HEIGHT # from the last command (Resize)
  85. vPrintPageSizes ' New'
  86. vPrintScaleFactor
  87. pageScale # scale the resized pdf
  88. finalRet=$(($finalRet+$?))
  89. # remove tmp file
  90. rm "$tempFile" >/dev/null 2>&1 || printError "Error when removing temporary file: $tempFile"
  91. elif isResizeMode; then
  92. vPrintScaleFactor "Disabled (resize only)"
  93. pageResize
  94. finalRet=$?
  95. else
  96. local scaleMode=""
  97. isManualScaledMode && scaleMode='(manual)' || scaleMode='(auto)'
  98. vPrintScaleFactor "$SCALE $scaleMode"
  99. pageScale
  100. finalRet=$?
  101. fi
  102. if [[ finalRet -eq $EXIT_SUCCESS ]]; then
  103. vprint " Final Status: File created successfully"
  104. else
  105. vprint " Final Status: Errors were detected. Exit status: $finalRet"
  106. fi
  107. return $finalRet
  108. }
  109. # Prints PDF Info and exits with $EXIT_SUCCESS, but only if $JUST_IDENTIFY is $TRUE
  110. printPDFSizes() {
  111. if [[ $JUST_IDENTIFY -eq $TRUE ]]; then
  112. VERBOSE=0
  113. printVersion 3 " - Paper Sizes"
  114. getPageSize || initError "Could not get pagesize!"
  115. local paperType="$(getGSPaperName $PGWIDTH $PGHEIGHT)"
  116. isEmpty "$paperType" && paperType="NOT Detected"
  117. printf " File: %s\n" "$(basename "$INFILEPDF")"
  118. printf " Paper Type: %s\n" "$paperType"
  119. printf '%s\n' "------------+----WIDTH-+-HEIGHT-----------"
  120. printf " Points | %+8s | %-8s\n" "$PGWIDTH" "$PGHEIGHT"
  121. printf " Milimeters | %+8s | %-8s\n" "$(pointsToMilimeters $PGWIDTH)" "$(pointsToMilimeters $PGHEIGHT)"
  122. printf " Inches | %+8s | %-8s\n" "$(pointsToInches $PGWIDTH)" "$(pointsToInches $PGHEIGHT)"
  123. exit $EXIT_SUCCESS
  124. fi
  125. return $EXIT_SUCCESS
  126. }
  127. ###################### GHOSTSCRIPT CALLS #######################
  128. # Runs the ghostscript scaling script
  129. pageScale() {
  130. # Compute translation factors (to center page).
  131. XTRANS=$(echo "scale=6; 0.5*(1.0-$SCALE)/$SCALE*$PGWIDTH" | "$BCBIN")
  132. YTRANS=$(echo "scale=6; 0.5*(1.0-$SCALE)/$SCALE*$PGHEIGHT" | "$BCBIN")
  133. vprint " Translation X: $XTRANS"
  134. vprint " Translation Y: $YTRANS"
  135. local increase=$(echo "scale=0; (($SCALE - 1) * 100)/1" | "$BCBIN")
  136. vprint " Run Scaling: $increase %"
  137. # Scale page
  138. "$GSBIN" \
  139. -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dSAFER \
  140. -dCompatibilityLevel="1.5" -dPDFSETTINGS="/printer" \
  141. -dColorConversionStrategy=/LeaveColorUnchanged \
  142. -dSubsetFonts=true -dEmbedAllFonts=true \
  143. -dDEVICEWIDTHPOINTS=$PGWIDTH -dDEVICEHEIGHTPOINTS=$PGHEIGHT \
  144. -sOutputFile="$OUTFILEPDF" \
  145. -c "<</BeginPage{$SCALE $SCALE scale $XTRANS $YTRANS translate}>> setpagedevice" \
  146. -f "$INFILEPDF"
  147. return $?
  148. }
  149. # Runs the ghostscript paper resize script
  150. pageResize() {
  151. # Get new paper sizes if not custom paper
  152. isNotCustomPaper && getGSPaperSize "$RESIZE_PAPER_TYPE"
  153. vprint " Auto Rotate: $(basename $AUTO_ROTATION)"
  154. # Flip detect
  155. local tmpInverter=""
  156. if [[ $FLIP_DETECTION -eq $TRUE || $FLIP_FORCE -eq $TRUE ]]; then
  157. if [[ $PGWIDTH -gt $PGHEIGHT && $RESIZE_WIDTH -lt $RESIZE_HEIGHT ]] || [[ $FLIP_FORCE -eq $TRUE ]]; then
  158. [[ $FLIP_FORCE -eq $TRUE ]] && vprint " Flip Detect: Forced Mode!" || vprint " Flip Detect: Wrong orientation detected!"
  159. vprint " Inverting Width <-> Height"
  160. tmpInverter=$RESIZE_HEIGHT
  161. RESIZE_HEIGHT=$RESIZE_WIDTH
  162. RESIZE_WIDTH=$tmpInverter
  163. else
  164. vprint " Flip Detect: No change needed"
  165. fi
  166. else
  167. vprint " Flip Detect: Disabled"
  168. fi
  169. vprint " Run Resizing: $(uppercase "$RESIZE_PAPER_TYPE") ( "$RESIZE_WIDTH" x "$RESIZE_HEIGHT" ) pts"
  170. # Change page size
  171. "$GSBIN" \
  172. -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -dSAFER \
  173. -dCompatibilityLevel="1.5" -dPDFSETTINGS="/printer" \
  174. -dColorConversionStrategy=/LeaveColorUnchanged \
  175. -dSubsetFonts=true -dEmbedAllFonts=true \
  176. -dDEVICEWIDTHPOINTS=$RESIZE_WIDTH -dDEVICEHEIGHTPOINTS=$RESIZE_HEIGHT \
  177. -dAutoRotatePages=$AUTO_ROTATION \
  178. -dFIXEDMEDIA -dPDFFitPage \
  179. -sOutputFile="$OUTFILEPDF" \
  180. -f "$INFILEPDF"
  181. return $?
  182. }
  183. ########################## INITIALIZERS #########################
  184. # Loads external dependencies and checks for errors
  185. initDeps() {
  186. GSBIN="$(which gs 2>/dev/null)"
  187. BCBIN="$(which bc 2>/dev/null)"
  188. IDBIN=$(which identify 2>/dev/null)
  189. MDLSBIN="$(which mdls 2>/dev/null)"
  190. PDFINFOBIN="$(which pdfinfo 2>/dev/null)"
  191. vprint "Checking for ghostscript and bcmath"
  192. if notIsAvailable "$GSBIN"; then printDependency 'ghostscript'; fi
  193. if notIsAvailable "$BCBIN"; then printDependency 'bc'; fi
  194. }
  195. # Checks for dependencies errors, run after getting options
  196. checkDeps() {
  197. if [[ $MODE = "IDENTIFY" ]]; then
  198. vprint "Checking for imagemagick's identify"
  199. if notIsAvailable "$IDBIN"; then printDependency 'imagemagick'; fi
  200. fi
  201. if [[ $MODE = "PDFINFO" ]]; then
  202. vprint "Checking for pdfinfo"
  203. if notIsAvailable "$PDFINFOBIN"; then printDependency 'pdfinfo'; fi
  204. fi
  205. if [[ $MODE = "MDLS" ]]; then
  206. vprint "Checking for MacOS mdls"
  207. if notIsAvailable "$MDLSBIN"; then
  208. initError 'mdls executable was not found! Is this even MacOS?' $EXIT_MAC_MDLS_NOT_FOUND 'nobanner'
  209. fi
  210. fi
  211. }
  212. ######################### CLI OPTIONS ##########################
  213. # Parse options
  214. getOptions() {
  215. while getopts ":vhVis:m:r:pf:a:" o; do
  216. case "${o}" in
  217. v)
  218. ((VERBOSE++))
  219. ;;
  220. h)
  221. printHelp
  222. exit $EXIT_SUCCESS
  223. ;;
  224. V)
  225. printVersion
  226. exit $EXIT_SUCCESS
  227. ;;
  228. i)
  229. JUST_IDENTIFY=$TRUE
  230. ;;
  231. s)
  232. parseScale ${OPTARG}
  233. ;;
  234. m)
  235. parseMode ${OPTARG}
  236. ;;
  237. r)
  238. parsePaperResize ${OPTARG}
  239. ;;
  240. p)
  241. printPaperInfo
  242. exit $EXIT_SUCCESS
  243. ;;
  244. f)
  245. parseFlipDetectionMode ${OPTARG}
  246. ;;
  247. a)
  248. parseAutoRotationMode ${OPTARG}
  249. ;;
  250. *)
  251. initError "Invalid Option: -$OPTARG" $EXIT_INVALID_OPTION
  252. ;;
  253. esac
  254. done
  255. shift $((OPTIND-1))
  256. if [[ $JUST_IDENTIFY -eq $TRUE ]]; then
  257. VERBOSE=0
  258. fi
  259. # Validate input PDF file
  260. INFILEPDF="$1"
  261. isEmpty "$INFILEPDF" && initError "Input file is empty!" $EXIT_NO_INPUT_FILE
  262. isPDF "$INFILEPDF" || initError "Input file is not a PDF file: $INFILEPDF" $EXIT_INPUT_NOT_PDF
  263. isFile "$INFILEPDF" || initError "Input file not found: $INFILEPDF" $EXIT_FILE_NOT_FOUND
  264. printVersion 1 'verbose'
  265. if isMixedMode; then
  266. vprint " Mixed Tasks: Resize & Scale"
  267. isEmpty "$2" && OUTFILEPDF="${INFILEPDF%.pdf}.$(uppercase $RESIZE_PAPER_TYPE).SCALED.pdf"
  268. elif isResizeMode; then
  269. vprint " Single Task: Resize PDF Paper"
  270. isEmpty "$2" && OUTFILEPDF="${INFILEPDF%.pdf}.$(uppercase $RESIZE_PAPER_TYPE).pdf"
  271. else
  272. vprint " Single Task: Scale PDF Contents"
  273. isEmpty "$2" && OUTFILEPDF="${INFILEPDF%.pdf}.SCALED.pdf"
  274. fi
  275. isNotEmpty "$2" && OUTFILEPDF="${2%.pdf}.pdf"
  276. }
  277. # Parses and validates the scaling factor
  278. parseScale() {
  279. AUTOMATIC_SCALING=$FALSE
  280. if ! isFloatBiggerThanZero "$1"; then
  281. printError "Invalid factor: $1"
  282. printError "The factor must be a floating point number greater than 0"
  283. printError "Example: for 80% use 0.8"
  284. exit $EXIT_INVALID_SCALE
  285. fi
  286. SCALE="$1"
  287. }
  288. # Parse a forced mode of operation
  289. parseMode() {
  290. local param="$(lowercase $1)"
  291. case "${param}" in
  292. c|catgrep|'cat+grep')
  293. ADAPTIVEMODE=$FALSE
  294. MODE="CATGREP"
  295. return $TRUE
  296. ;;
  297. i|imagemagick|identify)
  298. ADAPTIVEMODE=$FALSE
  299. MODE="IDENTIFY"
  300. return $TRUE
  301. ;;
  302. m|mdls|quartz|mac)
  303. ADAPTIVEMODE=$FALSE
  304. MODE="MDLS"
  305. return $TRUE
  306. ;;
  307. p|pdfinfo)
  308. ADAPTIVEMODE=$FALSE
  309. MODE="PDFINFO"
  310. return $TRUE
  311. ;;
  312. *)
  313. ADAPTIVEMODE=$TRUE
  314. MODE=""
  315. if [[ "$param" != 'a' && "$param" != 'auto' && "$param" != 'automatic' && "$param" != 'adaptive' ]]; then
  316. printError "Error! Invalid PDF Size Detection Mode: \"$1\", using adaptive mode!"
  317. return $FALSE
  318. fi
  319. return $TRUE
  320. ;;
  321. esac
  322. return $FALSE
  323. }
  324. # Parses and validates the scaling factor
  325. parseFlipDetectionMode() {
  326. local param="$(lowercase $1)"
  327. case "${param}" in
  328. d|disable)
  329. FLIP_DETECTION=$FALSE
  330. FLIP_FORCE=$FALSE
  331. ;;
  332. f|force)
  333. FLIP_DETECTION=$FALSE
  334. FLIP_FORCE=$TRUE
  335. ;;
  336. *)
  337. [[ "$param" != 'a' && "$param" != 'auto' ]] && printError "Error! Invalid Flip Detection Mode: \"$1\", using automatic mode!"
  338. FLIP_DETECTION=$TRUE
  339. FLIP_FORCE=$FALSE
  340. ;;
  341. esac
  342. }
  343. # Parses and validates the scaling factor
  344. parseAutoRotationMode() {
  345. local param="$(lowercase $1)"
  346. case "${param}" in
  347. n|none)
  348. AUTO_ROTATION='/None'
  349. ;;
  350. a|all)
  351. AUTO_ROTATION='/All'
  352. ;;
  353. p|pagebypage|auto)
  354. AUTO_ROTATION='/PageByPage'
  355. ;;
  356. *)
  357. printError "Error! Invalid Auto Rotation Mode: $param, using default: $(basename $AUTO_ROTATION)"
  358. ;;
  359. esac
  360. }
  361. ################### PDF PAGE SIZE DETECTION ####################
  362. ################################################################
  363. # Detects operation mode and also runs the adaptive mode
  364. # PAGESIZE LOGIC
  365. # 1- Try to get Mediabox with CAT/GREP
  366. # 2- MacOS => try to use mdls
  367. # 3- Try to use pdfinfo
  368. # 4- Try to use identify (imagemagick)
  369. # 5- Fail
  370. ################################################################
  371. getPageSize() {
  372. if isNotAdaptiveMode; then
  373. vprint " Get Page Size: Adaptive Disabled"
  374. if [[ $MODE = "CATGREP" ]]; then
  375. vprint " Method: Cat + Grep"
  376. getPageSizeCatGrep
  377. elif [[ $MODE = "MDLS" ]]; then
  378. vprint " Method: Mac Quartz mdls"
  379. getPageSizeMdls
  380. elif [[ $MODE = "PDFINFO" ]]; then
  381. vprint " Method: PDFInfo"
  382. getPageSizePdfInfo
  383. elif [[ $MODE = "IDENTIFY" ]]; then
  384. vprint " Method: ImageMagick's Identify"
  385. getPageSizeImagemagick
  386. else
  387. printError "Error! Invalid Mode: $MODE"
  388. printError "Aborting execution..."
  389. exit $EXIT_INVALID_OPTION
  390. fi
  391. return $TRUE
  392. fi
  393. vprint " Get Page Size: Adaptive Enabled"
  394. vprint " Method: Cat + Grep"
  395. getPageSizeCatGrep
  396. if pageSizeIsInvalid && [[ $OSNAME = "Darwin" ]]; then
  397. vprint " Failed"
  398. vprint " Method: Mac Quartz mdls"
  399. getPageSizeMdls
  400. fi
  401. if pageSizeIsInvalid; then
  402. vprint " Failed"
  403. vprint " Method: PDFInfo"
  404. getPageSizePdfInfo
  405. fi
  406. if pageSizeIsInvalid; then
  407. vprint " Failed"
  408. vprint " Method: ImageMagick's Identify"
  409. getPageSizeImagemagick
  410. fi
  411. if pageSizeIsInvalid; then
  412. vprint " Failed"
  413. printError "Error when detecting PDF paper size!"
  414. printError "All methods of detection failed"
  415. printError "You may want to install pdfinfo or imagemagick"
  416. exit $EXIT_INVALID_PAGE_SIZE_DETECTED
  417. fi
  418. return $TRUE
  419. }
  420. # Gets page size using imagemagick's identify
  421. getPageSizeImagemagick() {
  422. # Sanity and Adaptive together
  423. if notIsFile "$IDBIN" && isNotAdaptiveMode; then
  424. notAdaptiveFailed "Make sure you installed ImageMagick and have identify on your \$PATH" "ImageMagick's Identify"
  425. elif notIsFile "$IDBIN" && isAdaptiveMode; then
  426. return $FALSE
  427. fi
  428. # get data from image magick
  429. local identify="$("$IDBIN" -format '%[fx:w] %[fx:h]BREAKME' "$INFILEPDF" 2>/dev/null)"
  430. if isEmpty "$identify" && isNotAdaptiveMode; then
  431. notAdaptiveFailed "ImageMagicks's Identify returned an empty string!"
  432. elif isEmpty "$identify" && isAdaptiveMode; then
  433. return $FALSE
  434. fi
  435. identify="${identify%%BREAKME*}" # get page size only for 1st page
  436. identify=($identify) # make it an array
  437. PGWIDTH=$(printf '%.0f' "${identify[0]}") # assign
  438. PGHEIGHT=$(printf '%.0f' "${identify[1]}") # assign
  439. return $TRUE
  440. }
  441. # Gets page size using Mac Quarts mdls
  442. getPageSizeMdls() {
  443. # Sanity and Adaptive together
  444. if notIsFile "$MDLSBIN" && isNotAdaptiveMode; then
  445. notAdaptiveFailed "Are you even trying this on a Mac?" "Mac Quartz mdls"
  446. elif notIsFile "$MDLSBIN" && isAdaptiveMode; then
  447. return $FALSE
  448. fi
  449. local identify="$("$MDLSBIN" -mdls -name kMDItemPageHeight -name kMDItemPageWidth "$INFILEPDF" 2>/dev/null)"
  450. if isEmpty "$identify" && isNotAdaptiveMode; then
  451. notAdaptiveFailed "Mac Quartz mdls returned an empty string!"
  452. elif isEmpty "$identify" && isAdaptiveMode; then
  453. return $FALSE
  454. fi
  455. identify=${identify//$'\t'/ } # change tab to space
  456. identify=($identify) # make it an array
  457. if [[ "${identify[5]}" = "(null)" || "${identify[2]}" = "(null)" ]] && isNotAdaptiveMode; then
  458. notAdaptiveFailed "There was no metadata to read from the file! Is Spotlight OFF?"
  459. elif [[ "${identify[5]}" = "(null)" || "${identify[2]}" = "(null)" ]] && isAdaptiveMode; then
  460. return $FALSE
  461. fi
  462. PGWIDTH=$(printf '%.0f' "${identify[5]}") # assign
  463. PGHEIGHT=$(printf '%.0f' "${identify[2]}") # assign
  464. return $TRUE
  465. }
  466. # Gets page size using Linux PdfInfo
  467. getPageSizePdfInfo() {
  468. # Sanity and Adaptive together
  469. if notIsFile "$PDFINFOBIN" && isNotAdaptiveMode; then
  470. notAdaptiveFailed "Do you have pdfinfo installed and available on your \$PATH?" "Linux pdfinfo"
  471. elif notIsFile "$PDFINFOBIN" && isAdaptiveMode; then
  472. return $FALSE
  473. fi
  474. # get data from image magick
  475. local identify="$("$PDFINFOBIN" "$INFILEPDF" 2>/dev/null | grep -i 'Page size:' )"
  476. if isEmpty "$identify" && isNotAdaptiveMode; then
  477. notAdaptiveFailed "Linux PdfInfo returned an empty string!"
  478. elif isEmpty "$identify" && isAdaptiveMode; then
  479. return $FALSE
  480. fi
  481. identify="${identify##*Page size:}" # remove stuff
  482. identify=($identify) # make it an array
  483. PGWIDTH=$(printf '%.0f' "${identify[0]}") # assign
  484. PGHEIGHT=$(printf '%.0f' "${identify[2]}") # assign
  485. return $TRUE
  486. }
  487. # Gets page size using cat and grep
  488. getPageSizeCatGrep() {
  489. # get MediaBox info from PDF file using cat and grep, these are all possible
  490. # /MediaBox [0 0 595 841]
  491. # /MediaBox [ 0 0 595.28 841.89]
  492. # /MediaBox[ 0 0 595.28 841.89 ]
  493. # Get MediaBox data if possible
  494. local mediaBox="$(cat "$INFILEPDF" | grep -a '/MediaBox' | head -n1)"
  495. mediaBox="${mediaBox##*/MediaBox}"
  496. # No page size data available
  497. if isEmpty "$mediaBox" && isNotAdaptiveMode; then
  498. notAdaptiveFailed "There is no MediaBox in the pdf document!"
  499. elif isEmpty "$mediaBox" && isAdaptiveMode; then
  500. return $FALSE
  501. fi
  502. # remove chars [ and ]
  503. mediaBox="${mediaBox//[}"
  504. mediaBox="${mediaBox//]}"
  505. mediaBox=($mediaBox) # make it an array
  506. mbCount=${#mediaBox[@]} # array size
  507. # sanity
  508. if [[ $mbCount -lt 4 ]]; then
  509. printError "Error when reading the page size!"
  510. printError "The page size information is invalid!"
  511. exit $EXIT_INVALID_PAGE_SIZE_DETECTED
  512. fi
  513. # we are done
  514. PGWIDTH=$(printf '%.0f' "${mediaBox[2]}") # Get Round Width
  515. PGHEIGHT=$(printf '%.0f' "${mediaBox[3]}") # Get Round Height
  516. return $TRUE
  517. }
  518. # Prints error message and exits execution
  519. notAdaptiveFailed() {
  520. local errProgram="$2"
  521. local errStr="$1"
  522. if isEmpty "$2"; then
  523. printError "Error when reading input file!"
  524. printError "Could not determine the page size!"
  525. else
  526. printError "Error! $2 was not found!"
  527. fi
  528. isNotEmpty "$errStr" && printError "$errStr"
  529. printError "Aborting! You may want to try the adaptive mode."
  530. exit $EXIT_INVALID_PAGE_SIZE_DETECTED
  531. }
  532. # Verbose print of the Width and Height (Source or New) to screen
  533. vPrintPageSizes() {
  534. vprint " $1 Width: $PGWIDTH postscript-points"
  535. vprint "$1 Height: $PGHEIGHT postscript-points"
  536. }
  537. #################### GHOSTSCRIPT PAPER INFO ####################
  538. # Loads GS paper info to memory
  539. getPaperInfo() {
  540. # name inchesW inchesH mmW mmH pointsW pointsH
  541. sizesUS="\
  542. 11x17 11.0 17.0 279 432 792 1224
  543. ledger 17.0 11.0 432 279 1224 792
  544. legal 8.5 14.0 216 356 612 1008
  545. letter 8.5 11.0 216 279 612 792
  546. lettersmall 8.5 11.0 216 279 612 792
  547. archE 36.0 48.0 914 1219 2592 3456
  548. archD 24.0 36.0 610 914 1728 2592
  549. archC 18.0 24.0 457 610 1296 1728
  550. archB 12.0 18.0 305 457 864 1296
  551. archA 9.0 12.0 229 305 648 864"
  552. sizesISO="\
  553. a0 33.1 46.8 841 1189 2384 3370
  554. a1 23.4 33.1 594 841 1684 2384
  555. a2 16.5 23.4 420 594 1191 1684
  556. a3 11.7 16.5 297 420 842 1191
  557. a4 8.3 11.7 210 297 595 842
  558. a4small 8.3 11.7 210 297 595 842
  559. a5 5.8 8.3 148 210 420 595
  560. a6 4.1 5.8 105 148 297 420
  561. a7 2.9 4.1 74 105 210 297
  562. a8 2.1 2.9 52 74 148 210
  563. a9 1.5 2.1 37 52 105 148
  564. a10 1.0 1.5 26 37 73 105
  565. isob0 39.4 55.7 1000 1414 2835 4008
  566. isob1 27.8 39.4 707 1000 2004 2835
  567. isob2 19.7 27.8 500 707 1417 2004
  568. isob3 13.9 19.7 353 500 1001 1417
  569. isob4 9.8 13.9 250 353 709 1001
  570. isob5 6.9 9.8 176 250 499 709
  571. isob6 4.9 6.9 125 176 354 499
  572. c0 36.1 51.1 917 1297 2599 3677
  573. c1 25.5 36.1 648 917 1837 2599
  574. c2 18.0 25.5 458 648 1298 1837
  575. c3 12.8 18.0 324 458 918 1298
  576. c4 9.0 12.8 229 324 649 918
  577. c5 6.4 9.0 162 229 459 649
  578. c6 4.5 6.4 114 162 323 459"
  579. sizesJIS="\
  580. jisb0 NA NA 1030 1456 2920 4127
  581. jisb1 NA NA 728 1030 2064 2920
  582. jisb2 NA NA 515 728 1460 2064
  583. jisb3 NA NA 364 515 1032 1460
  584. jisb4 NA NA 257 364 729 1032
  585. jisb5 NA NA 182 257 516 729
  586. jisb6 NA NA 128 182 363 516"
  587. sizesOther="\
  588. flsa 8.5 13.0 216 330 612 936
  589. flse 8.5 13.0 216 330 612 936
  590. halfletter 5.5 8.5 140 216 396 612
  591. hagaki 3.9 5.8 100 148 283 420"
  592. sizesAll="\
  593. $sizesUS
  594. $sizesISO
  595. $sizesJIS
  596. $sizesOther"
  597. }
  598. # Gets a paper size in points and sets it to RESIZE_WIDTH and RESIZE_HEIGHT
  599. getGSPaperSize() {
  600. isEmpty "$sizesall" && getPaperInfo
  601. while read l; do
  602. local cols=($l)
  603. if [[ "$1" == ${cols[0]} ]]; then
  604. RESIZE_WIDTH=${cols[5]}
  605. RESIZE_HEIGHT=${cols[6]}
  606. return $TRUE
  607. fi
  608. done <<< "$sizesAll"
  609. }
  610. # Gets a paper size in points and sets it to RESIZE_WIDTH and RESIZE_HEIGHT
  611. getGSPaperName() {
  612. local w="$(printf "%.0f" $1)"
  613. local h="$(printf "%.0f" $2)"
  614. isEmpty "$sizesall" && getPaperInfo
  615. # Because US Standard has inverted sizes, I need to scan 2 times
  616. # instead of just testing if width is bigger than height
  617. while read l; do
  618. local cols=($l)
  619. if [[ "$w" == ${cols[5]} && "$h" == ${cols[6]} ]]; then
  620. printf "%s Portrait" $(uppercase ${cols[0]})
  621. return $TRUE
  622. fi
  623. done <<< "$sizesAll"
  624. while read l; do
  625. local cols=($l)
  626. if [[ "$w" == ${cols[6]} && "$h" == ${cols[5]} ]]; then
  627. printf "%s Landscape" $(uppercase ${cols[0]})
  628. return $TRUE
  629. fi
  630. done <<< "$sizesAll"
  631. return $FALSE
  632. }
  633. # Loads an array with paper names to memory
  634. getPaperNames() {
  635. paperNames=(a0 a1 a2 a3 a4 a4small a5 a6 a7 a8 a9 a10 isob0 isob1 isob2 isob3 isob4 isob5 isob6 c0 c1 c2 c3 c4 c5 c6 \
  636. 11x17 ledger legal letter lettersmall archE archD archC archB archA \
  637. jisb0 jisb1 jisb2 jisb3 jisb4 jisb5 jisb6 \
  638. flsa flse halfletter hagaki)
  639. }
  640. # Prints uppercase paper names to screen (used in help)
  641. printPaperNames() {
  642. isEmpty "$paperNames" && getPaperNames
  643. for i in "${!paperNames[@]}"; do
  644. [[ $i -eq 0 ]] && echo -n -e ' '
  645. [[ $i -ne 0 && $((i % 5)) -eq 0 ]] && echo -n -e $'\n '
  646. ppN="$(uppercase ${paperNames[i]})"
  647. printf "%-14s" "$ppN"
  648. done
  649. echo ""
  650. }
  651. # Returns $TRUE if $! is a valid paper name, $FALSE otherwise
  652. isPaperName() {
  653. isEmpty "$1" && return $FALSE
  654. isEmpty "$paperNames" && getPaperNames
  655. for i in "${paperNames[@]}"; do
  656. [[ "$i" = "$1" ]] && return $TRUE
  657. done
  658. return $FALSE
  659. }
  660. # Prints all tables with ghostscript paper information
  661. printPaperInfo() {
  662. printVersion
  663. echo $'\n'"Valid Ghostscript Paper Sizes accepted"$'\n'
  664. getPaperInfo
  665. printPaperTable "ISO STANDARD" "$sizesISO"; echo
  666. printPaperTable "US STANDARD" "$sizesUS"; echo
  667. printPaperTable "JIS STANDARD *Aproximated Points" "$sizesJIS"; echo
  668. printPaperTable "OTHERS" "$sizesOther"; echo
  669. }
  670. # GS paper table helper, prints a full line
  671. printTableLine() {
  672. echo '+-----------------------------------------------------------------+'
  673. }
  674. # GS paper table helper, prints a line with dividers
  675. printTableDivider() {
  676. echo '+-----------------+-------+-------+-------+-------+-------+-------+'
  677. }
  678. # GS paper table helper, prints a table header
  679. printTableHeader() {
  680. echo '| Name | inchW | inchH | mm W | mm H | pts W | pts H |'
  681. }
  682. # GS paper table helper, prints a table title
  683. printTableTitle() {
  684. printf "| %-64s%s\n" "$1" '|'
  685. }
  686. # GS paper table printer, prints a table for a paper variable
  687. printPaperTable() {
  688. printTableLine
  689. printTableTitle "$1"
  690. printTableLine
  691. printTableHeader
  692. printTableDivider
  693. while read l; do
  694. local cols=($l)
  695. printf "| %-15s | %+5s | %+5s | %+5s | %+5s | %+5s | %+5s |\n" ${cols[*]};
  696. done <<< "$2"
  697. printTableDivider
  698. }
  699. # Validades the a paper resize CLI option and sets the paper to $RESIZE_PAPER_TYPE
  700. parsePaperResize() {
  701. isEmpty "$1" && initError 'Invalid Paper Type: (empty)' $EXIT_INVALID_PAPER_SIZE
  702. local lowercasePaper="$(lowercase $1)"
  703. if [[ "$1" = 'custom' ]]; then
  704. if isNotValidMeasure "$2" || ! isFloatBiggerThanZero "$3" || ! isFloatBiggerThanZero "$4"; then
  705. initError "Invalid Custom Paper Definition!"$'\n'"Use: -r 'custom <measurement> <width> <height>'"$'\n'"Measurements: mm, in, pts" $EXIT_INVALID_OPTION
  706. fi
  707. RESIZE_PAPER_TYPE="custom"
  708. CUSTOM_RESIZE_PAPER=$TRUE
  709. if isMilimeter "$2"; then
  710. RESIZE_WIDTH="$(milimetersToPoints "$3")"
  711. RESIZE_HEIGHT="$(milimetersToPoints "$4")"
  712. elif isInch "$2"; then
  713. RESIZE_WIDTH="$(inchesToPoints "$3")"
  714. RESIZE_HEIGHT="$(inchesToPoints "$4")"
  715. elif isPoint "$2"; then
  716. RESIZE_WIDTH="$3"
  717. RESIZE_HEIGHT="$4"
  718. else
  719. initError "Invalid Custom Paper Definition!"$'\n'"Use: -r 'custom <measurement> <width> <height>'"$'\n'"Measurements: mm, in, pts" $EXIT_INVALID_OPTION
  720. fi
  721. else
  722. isPaperName "$lowercasePaper" || initError "Invalid Paper Type: $1" $EXIT_INVALID_PAPER_SIZE
  723. RESIZE_PAPER_TYPE="$lowercasePaper"
  724. fi
  725. }
  726. # Returns $TRUE if $1 is a valid measurement for a custom paper, $FALSE otherwise
  727. isNotValidMeasure() {
  728. isMilimeter "$1" || isInch "$1" || isPoint "$1" && return $FALSE
  729. return $TRUE
  730. }
  731. # Returns $TRUE if $1 is a valid milimeter string, $FALSE otherwise
  732. isMilimeter() {
  733. [[ "$1" = 'mm' || "$1" = 'milimeters' || "$1" = 'milimeter' ]] && return $TRUE
  734. return $FALSE
  735. }
  736. # Returns $TRUE if $1 is a valid inch string, $FALSE otherwise
  737. isInch() {
  738. [[ "$1" = 'in' || "$1" = 'inch' || "$1" = 'inches' ]] && return $TRUE
  739. return $FALSE
  740. }
  741. # Returns $TRUE if $1 is a valid point string, $FALSE otherwise
  742. isPoint() {
  743. [[ "$1" = 'pt' || "$1" = 'pts' || "$1" = 'point' || "$1" = 'points' ]] && return $TRUE
  744. return $FALSE
  745. }
  746. # Returns $TRUE if a custom paper is being used, $FALSE otherwise
  747. isCustomPaper() {
  748. return $CUSTOM_RESIZE_PAPER
  749. }
  750. isNotCustomPaper() {
  751. isCustomPaper && return $FALSE
  752. return $TRUE
  753. }
  754. # Returns $TRUE if the scale was set manually, $FALSE if we are using automatic scaling
  755. isManualScaledMode() {
  756. [[ $AUTOMATIC_SCALING -eq $TRUE ]] && return $FALSE
  757. return $TRUE
  758. }
  759. # Returns true if we are resizing a paper (ignores scaling), false otherwise
  760. isResizeMode() {
  761. isEmpty $RESIZE_PAPER_TYPE && return $FALSE
  762. return $TRUE
  763. }
  764. # Returns true if we are resizing a paper and the scale was manually set
  765. isMixedMode() {
  766. isResizeMode && isManualScaledMode && return $TRUE
  767. return $FALSE
  768. }
  769. # Prints the lowercase char value for $1
  770. lowercaseChar() {
  771. case "$1" in
  772. [A-Z])
  773. n=$(printf "%d" "'$1")
  774. n=$((n+32))
  775. printf \\$(printf "%o" "$n")
  776. ;;
  777. *)
  778. printf "%s" "$1"
  779. ;;
  780. esac
  781. }
  782. # Prints the lowercase version of a string
  783. lowercase() {
  784. word="$@"
  785. for((i=0;i<${#word};i++))
  786. do
  787. ch="${word:$i:1}"
  788. lowercaseChar "$ch"
  789. done
  790. }
  791. # Prints the uppercase char value for $1
  792. uppercaseChar(){
  793. case "$1" in
  794. [a-z])
  795. n=$(printf "%d" "'$1")
  796. n=$((n-32))
  797. printf \\$(printf "%o" "$n")
  798. ;;
  799. *)
  800. printf "%s" "$1"
  801. ;;
  802. esac
  803. }
  804. # Prints the uppercase version of a string
  805. uppercase() {
  806. word="$@"
  807. for((i=0;i<${#word};i++))
  808. do
  809. ch="${word:$i:1}"
  810. uppercaseChar "$ch"
  811. done
  812. }
  813. # Prints the postscript points rounded equivalent from $1 mm
  814. milimetersToPoints() {
  815. local pts=$(echo "scale=8; $1 * 72 / 25.4" | "$BCBIN")
  816. printf '%.0f' "$pts" # Print rounded conversion
  817. }
  818. # Prints the postscript points rounded equivalent from $1 inches
  819. inchesToPoints() {
  820. local pts=$(echo "scale=8; $1 * 72" | "$BCBIN")
  821. printf '%.0f' "$pts" # Print rounded conversion
  822. }
  823. # Prints the mm equivalent from $1 postscript points
  824. pointsToMilimeters() {
  825. local pts=$(echo "scale=8; $1 / 72 * 25.4" | "$BCBIN")
  826. printf '%.0f' "$pts" # Print rounded conversion
  827. }
  828. # Prints the inches equivalent from $1 postscript points
  829. pointsToInches() {
  830. local pts=$(echo "scale=8; $1 / 72" | "$BCBIN")
  831. printf '%.2f' "$pts" # Print rounded conversion
  832. }
  833. ########################## VALIDATORS ##########################
  834. # Returns $TRUE if $PGWIDTH OR $PGWIDTH are empty or NOT an Integer, $FALSE otherwise
  835. pageSizeIsInvalid() {
  836. if isNotAnInteger "$PGWIDTH" || isNotAnInteger "$PGHEIGHT"; then
  837. return $TRUE
  838. fi
  839. return $FALSE
  840. }
  841. # Return $TRUE if adaptive mode is enabled, $FALSE otherwise
  842. isAdaptiveMode() {
  843. return $ADAPTIVEMODE
  844. }
  845. # Return $TRUE if adaptive mode is disabled, $FALSE otherwise
  846. isNotAdaptiveMode() {
  847. isAdaptiveMode && return $FALSE
  848. return $TRUE
  849. }
  850. # Return $TRUE if $1 is empty, $FALSE otherwise
  851. isEmpty() {
  852. [[ -z "$1" ]] && return $TRUE
  853. return $FALSE
  854. }
  855. # Return $TRUE if $1 is NOT empty, $FALSE otherwise
  856. isNotEmpty() {
  857. [[ -z "$1" ]] && return $FALSE
  858. return $TRUE
  859. }
  860. # Returns $TRUE if $1 is an integer, $FALSE otherwise
  861. isAnInteger() {
  862. case $1 in
  863. ''|*[!0-9]*) return $FALSE ;;
  864. *) return $TRUE ;;
  865. esac
  866. }
  867. # Returns $TRUE if $1 is NOT an integer, $FALSE otherwise
  868. isNotAnInteger() {
  869. case $1 in
  870. ''|*[!0-9]*) return $TRUE ;;
  871. *) return $FALSE ;;
  872. esac
  873. }
  874. # Returns $TRUE if $1 is a floating point number (or an integer), $FALSE otherwise
  875. isFloat() {
  876. [[ -n "$1" && "$1" =~ ^-?[0-9]*([.][0-9]+)?$ ]] && return $TRUE
  877. return $FALSE
  878. }
  879. # Returns $TRUE if $1 is a floating point number bigger than zero, $FALSE otherwise
  880. isFloatBiggerThanZero() {
  881. isFloat "$1" && [[ (( $1 > 0 )) ]] && return $TRUE
  882. return $FALSE
  883. }
  884. # Returns $TRUE if $1 has a .pdf extension, false otherwsie
  885. isPDF() {
  886. [[ "$1" =~ ^..*\.pdf$ ]] && return $TRUE
  887. return $FALSE
  888. }
  889. # Returns $TRUE if $1 is a file, false otherwsie
  890. isFile() {
  891. [[ -f "$1" ]] && return $TRUE
  892. return $FALSE
  893. }
  894. # Returns $TRUE if $1 is NOT a file, false otherwsie
  895. notIsFile() {
  896. [[ -f "$1" ]] && return $FALSE
  897. return $TRUE
  898. }
  899. # Returns $TRUE if $1 is executable, false otherwsie
  900. isExecutable() {
  901. [[ -x "$1" ]] && return $TRUE
  902. return $FALSE
  903. }
  904. # Returns $TRUE if $1 is NOT executable, false otherwsie
  905. notIsExecutable() {
  906. [[ -x "$1" ]] && return $FALSE
  907. return $TRUE
  908. }
  909. # Returns $TRUE if $1 is a file and executable, false otherwsie
  910. isAvailable() {
  911. if isFile "$1" && isExecutable "$1"; then
  912. return $TRUE
  913. fi
  914. return $FALSE
  915. }
  916. # Returns $TRUE if $1 is NOT a file or NOT executable, false otherwsie
  917. notIsAvailable() {
  918. if notIsFile "$1" || notIsExecutable "$1"; then
  919. return $TRUE
  920. fi
  921. return $FALSE
  922. }
  923. ###################### PRINTING TO SCREEN ######################
  924. # Prints version
  925. printVersion() {
  926. local vStr=""
  927. [[ "$2" = 'verbose' ]] && vStr=" - Verbose Execution"
  928. local strBanner="$PDFSCALE_NAME v$VERSION$vStr"
  929. if [[ $1 -eq 2 ]]; then
  930. printError "$strBanner"
  931. elif [[ $1 -eq 3 ]]; then
  932. local extra="$(isNotEmpty "$2" && echo "$2")"
  933. echo "$strBanner$extra"
  934. else
  935. vprint "$strBanner"
  936. fi
  937. }
  938. # Prints the scale factor to screen, or custom message
  939. vPrintScaleFactor() {
  940. local scaleMsg="$SCALE"
  941. isNotEmpty "$1" && scaleMsg="$1"
  942. vprint " Scale Factor: $scaleMsg"
  943. }
  944. # Prints help info
  945. printHelp() {
  946. printVersion 3
  947. local paperList="$(printPaperNames)"
  948. echo "
  949. Usage: $PDFSCALE_NAME <inFile.pdf>
  950. $PDFSCALE_NAME -i <inFile.pdf>
  951. $PDFSCALE_NAME [-v] [-s <factor>] [-m <page-detection>] <inFile.pdf> [outfile.pdf]
  952. $PDFSCALE_NAME [-v] [-r <paper>] [-f <flip-detection>] [-a <auto-rotation>] <inFile.pdf> [outfile.pdf]
  953. $PDFSCALE_NAME -p
  954. $PDFSCALE_NAME -h
  955. $PDFSCALE_NAME -V
  956. Parameters:
  957. -v Verbose mode, prints extra information
  958. Use twice for timestamp
  959. -h Print this help to screen and exits
  960. -V Prints version to screen and exits
  961. -m <mode> Page size Detection mode
  962. May disable the Adaptive Mode
  963. -i <file> Prints <file> Page Size information to screen and exits
  964. -s <factor> Changes the scaling factor or forces scaling
  965. Defaults: $SCALE / no scaling (resize mode)
  966. MUST be a number bigger than zero
  967. Eg. -s 0.8 for 80% of the original size
  968. -r <paper> Triggers the Resize Paper Mode
  969. Resize PDF paper proportionally
  970. Uses a valid paper name or a custom defined paper
  971. -f <mode> Flip Detection Mode, defaults to 'auto'.
  972. Inverts Width <-> Height of a Resized PDF.
  973. Modes: a, auto - automatic detection, default
  974. f, force - forces flip W <-> H
  975. d, disable - disables flipping
  976. -a <mode> GS Auto-Rotation Setting, defaults to 'PageByPage'.
  977. Setting for GS -dAutoRotatePages.
  978. Modes: p, pagebypage - auto-rotates pages individually
  979. a, all - rotates all pages (or none) depending
  980. on a kind of \"majority decision\"
  981. n, none - retains orientation of each page
  982. -p Prints Ghostscript paper info tables to screen
  983. Scaling Mode:
  984. The default mode of operation is scaling mode with fixed paper
  985. size and scaling pre-set to $SCALE. By not using the resize mode
  986. you are using scaling mode. Flip-Detection and Auto-Rotation are
  987. disabled in Scaling mode.
  988. Resize Paper Mode:
  989. Disables the default scaling factor! ($SCALE)
  990. Changes the PDF Paper Size in points. Will fit-to-page.
  991. Mixed Mode:
  992. In mixed mode both the -s option and -r option must be specified.
  993. The PDF will be first resized then scaled.
  994. Output filename:
  995. The output filename is optional. If no file name is passed
  996. the output file will have the same name/destination of the
  997. input file with added suffixes:
  998. .SCALED.pdf is added to scaled files
  999. .<PAPERSIZE>.pdf is added to resized files
  1000. .<PAPERSIZE>.SCALED.pdf is added in mixed mode
  1001. Page Size Detection Modes:
  1002. a, adaptive Default mode, tries all the methods below
  1003. c, cat+grep Forces the use of the cat + grep method
  1004. m, mdls Forces the use of MacOS Quartz mdls
  1005. p, pdfinfo Forces the use of PDFInfo
  1006. i, identify Forces the use of ImageMagick's Identify
  1007. Valid Paper Names: (case-insensitive)
  1008. $paperList
  1009. Custom Paper Size:
  1010. Paper size can be set manually in Milimeters, Inches or Points.
  1011. Use: $PDFSCALE_NAME -r 'custom <measurement> <width> <height>'
  1012. Ex: $PDFSCALE_NAME -r 'custom mm 300 300'
  1013. Measurements can be: mm, inch, pts.
  1014. Custom paper definition MUST be quoted into a single parameter.
  1015. Actual size is applied in points (mms and inches are transformed).
  1016. Additional Notes:
  1017. - Adaptive Page size detection will try different modes until
  1018. it gets a page size. You can force a mode with -m 'mode'.
  1019. - Options must be passed before the file names to be parsed.
  1020. - Having the extension .pdf on the output file name is optional,
  1021. it will be added if not present.
  1022. - File and folder names with spaces should be quoted or escaped.
  1023. - The scaling is centered and using a scale bigger than 1 may
  1024. result on cropping parts of the pdf.
  1025. - Most of the options are case-insensitive, Ex: -m PdFinFo
  1026. Examples:
  1027. $PDFSCALE_NAME myPdfFile.pdf
  1028. $PDFSCALE_NAME -i '/home/My Folder/My PDF File.pdf'
  1029. $PDFSCALE_NAME myPdfFile.pdf \"My Scaled Pdf\"
  1030. $PDFSCALE_NAME -v -v myPdfFile.pdf
  1031. $PDFSCALE_NAME -s 0.85 myPdfFile.pdf My\\ Scaled\\ Pdf.pdf
  1032. $PDFSCALE_NAME -m pdfinfo -s 0.80 -v myPdfFile.pdf
  1033. $PDFSCALE_NAME -v -v -m i -s 0.7 myPdfFile.pdf
  1034. $PDFSCALE_NAME -r A4 myPdfFile.pdf
  1035. $PDFSCALE_NAME -v -v -r \"custom mm 252 356\" -s 0.9 -f \"../input file.pdf\" \"../my new pdf\"
  1036. $PDFSCALE_NAME -h
  1037. "
  1038. }
  1039. # Prints usage info
  1040. usage() {
  1041. [[ "$2" != 'nobanner' ]] && printVersion 2
  1042. isNotEmpty "$1" && printError "$1"
  1043. printError "Usage: $PDFSCALE_NAME [-v] [-s <factor>] [-m <mode>] <inFile.pdf> [outfile.pdf]"
  1044. printError "Try: $PDFSCALE_NAME -h # for help"
  1045. }
  1046. # Prints Verbose information
  1047. vprint() {
  1048. [[ $VERBOSE -eq 0 ]] && return $TRUE
  1049. timestamp=""
  1050. [[ $VERBOSE -gt 1 ]] && timestamp="$(date +%Y-%m-%d:%H:%M:%S) | "
  1051. echo "$timestamp$1"
  1052. }
  1053. # Prints dependency information and aborts execution
  1054. printDependency() {
  1055. #printVersion 2
  1056. local brewName="$1"
  1057. [[ "$1" = 'pdfinfo' && "$OSNAME" = "Darwin" ]] && brewName="xpdf"
  1058. printError $'\n'"ERROR! You need to install the package '$1'"$'\n'
  1059. printError "Linux apt-get.: sudo apt-get install $1"
  1060. printError "Linux yum.....: sudo yum install $1"
  1061. printError "MacOS homebrew: brew install $brewName"
  1062. printError $'\n'"Aborting..."
  1063. exit $EXIT_MISSING_DEPENDENCY
  1064. }
  1065. # Prints initialization errors and aborts execution
  1066. initError() {
  1067. local errStr="$1"
  1068. local exitStat=$2
  1069. isEmpty "$exitStat" && exitStat=$EXIT_ERROR
  1070. usage "ERROR! $errStr" "$3"
  1071. exit $exitStat
  1072. }
  1073. # Prints to stderr
  1074. printError() {
  1075. echo >&2 "$@"
  1076. }
  1077. ########################## EXECUTION ###########################
  1078. initDeps
  1079. getOptions "${@}"
  1080. main
  1081. exit $?