#!/usr/bin/env bash # HEADER #======================================================================= # # pdfprint -- Get a quick access to print format for PDF. # # SYNOPSIS # pdfprint [options] [infiles] # # DESCRIPTION # Shell script to get a quick access to print format for PDF. # # OPTIONS # -h|--help display this help and exit # -b|--booklet A[3-5] format as booklet on A[3-5] paper # -n|--nup [2,4] format as 2x1 or 2x2 on A4 paper # -d|--double format as 2x1 with 2 times the same page # -g|--gray to convert display as grayscale # [aA][3-5] define output page format # -m|--mode [screen|ebook|printer|prepress] # ghostscript mode, with image resolution as # - screen: 72 DPI # - ebook: 150 DPI # - printer: 300 DPI # - prepress: 300 DPI # -r|--resolution) [num] # compress images with resolution in range # of 72-1200 DPI # -s|--safe (default) format safe PDF for printer compatibility # -f|--flatten to render transparency to bitmap # -O|--overwrite overwrite PDF infiles # -o , --output # output PDF file (single) # # EXAMPLES # $ pdfprint ... # $ pdfprint -b A3 ... # $ pdfprint --booklet A4 ... # $ pdfprint -n 2 ... # $ pdfprint --nup 4 ... # # DEPENDENCIES # - gs - Ghostscript >= 9.06 # - pdfjam >=2.08 # # INSTALLATION # - copy file to "/home/$(whoami)/bin" # - make executable with "chmod +x pdfprint" # - add line "complete -f -X '!*.[pP][dD][fF]' pdfprint" # to "/home/$(whoami)/.bashrc" # # Copyright (C) 2019-2025 Nicolas Mesnier # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License version 3 or # above as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # #======================================================================= # END_OF_HEADER #----------------------------------------------------------------------- # *** read this header to display help and version #----------------------------------------------------------------------- BOH=$(head -200 ${0} | grep -n "^# HEADER" | cut -f1 -d:) EOH=$(head -200 ${0} | grep -n "^# END_OF_HEADER" | cut -f1 -d:) function Help(){ head -$(($EOH-1)) ${0} | tail -$(($EOH-$BOH-1)) \ | grep -e "^#$" -e "^# " | sed -e "s/^#=*//g" } #----------------------------------------------------------------------- # *** to get safe pdf #----------------------------------------------------------------------- OPTIONS="" MODE="/printer" PDFVERSION="1.4" __safe__(){ gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite \ -dCompatibilityLevel=${PDFVERSION} -dPDFSETTINGS=${MODE} \ -dEmbedAllFont=true -dSubsetFonts=true \ -dAutoRotatePages=/None ${OPTIONS} \ -sOutputFile=$2 $1 } # __NoRencodeJPEG__(){ # echo " -dAutoFilterColorImages=false \ # -dAutoFilterGrayImages=false \ # -dColorImageFilter=/FlateEncode \ # -dGrayImageFilter=/FlateEncode" # } #----------------------------------------------------------------------- # *** to set 2x1 pdf file (such as lpr -o number-up=2) #----------------------------------------------------------------------- __twoup__(){ pdfjam --nup 2x1 --paper a4paper --landscape --scale 1 \ --quiet $1 --outfile $2 } #----------------------------------------------------------------------- # *** to set 2x2 pdf file #----------------------------------------------------------------------- __fourup__(){ pdfjam --nup 2x2 --paper a4paper --landscape --frame true \ --noautoscale false --delta "1.2cm 0.5cm" --scale 0.95 \ --quiet $1 --outfile $2 } #----------------------------------------------------------------------- # *** to set 2x1 pdf file with 2 times the same page #----------------------------------------------------------------------- __double__(){ pdfjam --nup 2x1 --paper a4paper --landscape --scale 1 \ --quiet $1 $1 --outfile $2 } #----------------------------------------------------------------------- # *** compose A* booklet #----------------------------------------------------------------------- __booklet__(){ # # obsolete, see `pdfbook2` instead # pdfbook --short-edge --paper $(echo $paper | tr [A-Z] [a-z])paper \ # --quiet $1 --outfile $2 pdfjam --booklet true --paper $(echo $paper | tr [A-Z] [a-z])paper \ --landscape --signature 4 \ --preamble '\usepackage{everyshi} \makeatletter \EveryShipout{\ifodd\c@page\pdfpageattr{/Rotate 180}\fi} \makeatother ' --quiet $1 --outfile $2 } #======================================================================= # *** intialization *** #======================================================================= RunFunction="__safe__" suffix="_safe" overwrite=0 #======================================================================= # *** get options *** #======================================================================= outfile="" infiles=() OPTIONS="-dQUIET" while [[ ${1} ]]; do case "${1}" in -h|--help) Help exit 0 ;; -b|--booket) RunFunction="__booklet__" case "${2}" in A3) paper="A3";; A4) paper="A4";; A5) paper="A5";; *) paper="A4" echo "booklet format is A[3-5] -- set to A4";; esac suffix="_"$paper"booklet" shift ;; -n|--nup) case "${2}" in 2) nup=2; RunFunction="__twoup__";; 4) nup=4; RunFunction="__fourup__";; *) echo "Option -n|--nup needs 2 or 4 as argument." >&2 exit 1;; esac suffix="_"$nup"up" shift ;; -d|--double) RunFunction="__double__" suffix="_double" ;; -g|--gray) OPTIONS+=" -sColorConversionStrategy=Gray" OPTIONS+=" -dProcessColorModel=/DeviceGray" OPTIONS+=" -dOverrideICC" ;; -m|--mode) case "${2}" in screen|ebook|printer|prepress) MODE="/"${2} ;; *) echo "Mode must be part of {screen|ebook|printer|prepress}." >&2 exit 1;; esac shift ;; -r|--resolution) if [ ${2} -lt 72 -o ${2} -gt 1200 ];then echo "Resolution must be in range 72-1200 DPI." >&2 exit 1 else RESOLUTION=${2} fi OPTIONS+=" -dColorImageDownsampleType=/Bicubic" OPTIONS+=" -dColorImageResolution="${RESOLUTION} OPTIONS+=" -dGrayImageDownsampleType=/Bicubic" OPTIONS+=" -dGrayImageResolution="${RESOLUTION} OPTIONS+=" -dMonoImageDownsampleType=/Bicubic" OPTIONS+=" -dMonoImageResolution="${RESOLUTION} shift ;; a3|A3) OPTIONS+=" -sPAPERSIZE=a3 -dFIXEDMEDIA -dPDFFitPage" suffix="_A3" ;; a4|A4) OPTIONS+=" -sPAPERSIZE=a4 -dFIXEDMEDIA -dPDFFitPage" suffix="_A4" ;; a5|A5) OPTIONS+=" -sPAPERSIZE=a5 -dFIXEDMEDIA -dPDFFitPage" suffix="_A5" ;; -s|--safe) ;; -f|--flatten) PDFVERSION="1.3" ;; -o|--output) outfile=${2} shift ;; -O|--overwrite) overwrite=1 ;; *) if [ -f ${1} ];then infiles[${#infiles[@]}]=${1} else echo "File \"${1}\" does not exists." >&2 exit 1 fi ;; esac if ! shift; then echo 'Missing parameter argument.' >&2 exit 1 fi done #======================================================================= # *** actions *** #======================================================================= nfiles=${#infiles[@]} if [ $nfiles -ge 1 ];then for i in $(seq 0 $(($nfiles -1)) );do infile=${infiles[$i]} if [ "${infile#*.}" = "pdf" ];then if [ -z ${outfile} ];then outfile=$(basename ${infile} .pdf)${suffix}".pdf" fi if [ -f ${outfile} ]; then read -p " File \"${outfile}\" allready exists. Replace? y/[n] " rep case $rep in [Yy]* ) ;; * ) exit 1;; esac fi fi echo " *** Processing '${infile}' > '${outfile}'" if [ ${RunFunction} != "__safe__" ];then ${RunFunction} ${infile} /dev/stdout | __safe__ - ${outfile} else __safe__ ${infile} ${outfile} fi if [ ${overwrite} -eq 1 ]; then echo " *** rename '${outfile}' > '${infile}'" mv ${outfile} ${infile} fi done fi #====================================================================eof # vim: set tw=72 ts=4 sw=4 nu: