-
Notifications
You must be signed in to change notification settings - Fork 0
/
a5toa4
executable file
·148 lines (136 loc) · 5.24 KB
/
a5toa4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/env bash
set +vx
# a5toa4 - Print an A5/Statement size document on A4/Letter for booklet folding
# Required: coreutils(cat mktemp) ghostscript(psselect pdf2ps ps2pdf)
# psutils(pstops/psnup)
Usage(){ # $1: code for exit
cat <<-EOS
a5toa4 - Print A5/Statement document on A4/Letter pages for booklet folding
Usage: a5toa4 [<Options>] <a5.pdf> [<a4.pdf>]
Options: -h/--help: Display this help text
-v/--verbose: Verbose output of processing steps
-l/--letter: Use Letter & Statement, not A4 & A5
-s/--split & -r/--reverse: See below
Print the resulting A4/Letter document on a single-sided printer by:
1. Printing all the even pages.
2. Reinserting the stack of printed pages in such a way that the blank
sides will now be used to print the rest of the pages in step 3.
3. Printing all the odd pages.
If -s/--split is given, the printing can be done by:
1. Printing the first half of the N pages, from 1 to N/2.
2. See step 2 above.
3. Printing the second half of the N pages, from N/2+1 to N.
If -r/--reverse is given, the order of printing in step 3 is reversed, as
appropriate for normal full-duplex printing (not the whole stack of
papers gets flipped, just individual pages automatically).
For more than 1 copy, be sure to select COLLATE before printing!
For printing on Letter size paper, select FIT TO PAGE before printing!
EOS
[[ $1 ]] && exit $1
}
# process commandline
verbose=0 split=0 reverse=0 in= out= stdout=/dev/null half=a5 full=a4
while (($#))
do
case $1 in
-l|--letter) half=statement full=letter ;;
-h|--help) Usage 0 ;;
-v|--verbose) verbose=1 stdout=/dev/stdout ;;
-s|--split) split=1 ;;
-r|--reverse) reverse=1 ;;
*) [[ $out ]] && echo "Too many arguments" && Usage 1
[[ $in ]] && out=$1 || in=$1
[[ ! -f $in ]] &&
echo "Filename of ${half^} sized pdf required, not a file: '$in'" &&
Usage 2
esac
shift
done
[[ -z $in ]] && echo "No filename for ${half^} sized pdf given" && Usage 3
[[ -z $out ]] &&
out=$(basename "$in") out=${out%.pdf} out=${out%.PDF} out+=_${full^}.pdf
missingcmd=
for cmd in psselect pdf2ps ps2pdf psnup
do type -P $cmd &>/dev/null || missingcmd+=" $cmd"
done
[[ $missingcmd ]] &&
echo "Missing commands:$missingcmd, install ghostscript/psutils" &&
exit 4
((verbose)) && echo "Convert ${half^} pdf to ps..."
tmp=$(mktemp -d) papersize=$(</etc/papersize)
[[ ! $full = $papersize ]] &&
restore='echo -n "Set " && echo $papersize |sudo tee /etc/papersize' &&
echo -n "Set " && echo $full |sudo tee /etc/papersize
trap "rm -r -- '$tmp'; $restore" EXIT QUIT
! pdf2ps "$in" "$tmp/a5.ps" && echo "Problem converting $in" && exit 5
# Get number of pages
cd "$tmp"
p=$(psselect -p- a5.ps 2>&1 >/dev/null) p=${p#*Wrote } p=${p%% *}
((!p)) && echo "No pages found in $in" && exit 6
# p: number pages in A5/Statement document; n: full number of A5/Statement-pages (multiple of 4)
((n=p,r=p%4)) && ((r=4-r,n+=r))
# s: number of A4/Letter-sheets; m: number of A4/Letter page sides
((s=n/4,m=n/2))
i=0
while ((i++<n))
do ((i>p)) && range+='_ ' || range+="$i "
done
# Normal full-duplex range: n,1 2,n-1 (-2,+2 +2,-2)
# Reverse full-duplex range: n,1 n/2,n/2+1 (-2,+2 -2,+2)
i=0 range=($range) nor= rev=
((na=n,nb=1,nc=2,nd=n-1,ra=n,rb=1,rc=n/2,rd=n/2+1))
while ((nb<m))
do # lower all indexes by 1 for zero-based array
nor+="${range[na-1]} ${range[nb-1]} ${range[nc-1]} ${range[nd-1]} "
rev+="${range[ra-1]} ${range[rb-1]} ${range[rc-1]} ${range[rd-1]} "
((na-=2,nb+=2,nc+=2,nd-=2,ra-=2,rb+=2,rc-=2,rd+=2))
done
nor=${nor% } rev=${rev% }
((reverse)) && r=$rev || r=$nor
if ((s>1 && split))
then # Split requested and more than 1 sheet
# Take the odd A4/Letter pages and then the even A4/Letter pages
i=0 odd= even= na=($nor) ra=($rev)
while ((i<n))
do
odd+="${na[i]} ${na[i+1]} "
even+="${na[i+2]} ${na[i+3]} "
reven+="${ra[i+2]} ${ra[i+3]} "
((i+=4))
done
snor=$odd${even% }
srev=$odd${reven% }
((reverse)) && r=$srev || r=$snor
fi
# Put the A5/Statement pages on A4/Letter
((verbose)) && echo "Convert ${half^} ps to ${full^}..."
r=${r// /,}
! psselect -p $r a5.ps a5c.ps &>"$stdout" &&
echo "Reordering failed" && exit 7
[[ $full = a4 ]] && size='-Pa5 -pa4' ||
size='-W5.5in -H8.5in -w8.5in -h11in'
! PAPERSIZE=$full psnup -2 $size a5c.ps a4.ps &>"$stdout" &&
echo "Conversion ${half^} to ${full^} failed" && exit 8
#pstops -pa4 "2:0L(21cm,0cm)+1L(21cm,14.85cm)" a5c.ps a4.ps
#pstops -w11in -h8.5in "2:0L(21cm,1cm)+1L(21cm,6in)" a5c.ps a4.ps
cd - >/dev/null
((verbose)) && echo "Convert ${full^} ps to pdf..."
! PAPERSIZE=$full ps2pdf "$tmp/a4.ps" "$out" &>"$stdout" &&
echo "Conversion ${full^} ps to pdf failed" && exit 9
if ((verbose))
then
echo "All done! Now print the booklet '$out' by:"
if ((split))
then
echo "- printing pages 1-$s"
echo "- reinserting the stack of sheets for printing the blank sides"
echo "- printing pages $((s+1))-$((s+s)) (REVERSE if needed by printer!)"
else
echo "printing the document with a full-duplex printer, or:"
echo "- printing the even pages"
echo "- reinserting the stack of sheets for printing the blank sides"
echo "- printing the odd pages (REVERSE if needed by printer!)"
fi
echo "For more than 1 copy, select COLLATE before printing!"
fi
exit 0