您好,我可以轻松地使用 mpage 将多个单面纸压缩在一个页面上。然而,我发现对双面纸做同样的事情很棘手。在本例中,我正在打印徽章。假设我的输入是
Badge01Front.pdf
Badge01Back.pdf
Badge02Front.pdf
Badge02Back.pdf
Badge03Front.pdf
...
如何将多个徽章合并到一张纸上,以便如果我将纸张切成徽章,我会在第一个徽章的一侧获得 Badge01Front,在另一侧获得 Badge01Back? (等等)。仅供参考,我可能使用 SVG 而不是 PDF,但这应该不会改变太多,因为它们很容易转换。
我已经写过一堆基本上可以做到这一点的脚本,但它们既复杂又脆弱。有没有一种干净的方法可以做到这一点?
答案1
这是一个有条理的方法:首先假设后面的文件名可以简单地从前面的文件名派生出来。然后将前面的文件数填充为每页数的倍数;我nup
从一个非常古老的同名程序中调用了它。使用 bash 创建所有前面文件名的索引数组
files
,并在末尾用虚拟占位符文件填充。一次处理一张表:将nup
文件名提取到sheet
数组中。将它们添加到一个final
数组中,该数组将按正确的顺序包含所有文件名。将工作表文件名转换为后版本文件名,跳过虚拟文件名。
计算每张纸的行数,nup/width
其中宽度是页面上的项目数。对于每一行,计算该行中项目的开始和结束索引,并从工作表的副本中以相反的顺序更新这些项目。将结果添加到final
数组中。
这应该会使下面的 bash 脚本更加清晰。我假设我的前面的文件被称为f01.ps
等等,后面的文件b01.ps
, 带有dummy.ps
.为了清楚和简洁起见,我没有对变量加双引号,因为我知道我的文件名。
nup=8
width=2
let numrows=nup/width
declare -a files final
files=(f*.ps)
dopad(){
while numfiles=${#files[@]}
let x=numfiles/nup*nup
[ $x != $numfiles ]
do files+=(dummy.ps)
done
}
doallsheets(){
declare -a sheet
let numsheets=numfiles/nup
for sheetnum in $(seq $numsheets)
do let offset=(sheetnum-1)*nup
for i in $(seq $nup)
do sheet+=(${files[$offset+$i-1]})
done
dosheet
unset sheet
done
}
dosheet(){
final+=(${sheet[@]})
convertnames
swaprows
final+=(${sheet[@]})
}
convertnames(){
for i in $(seq $nup)
do if [ ${sheet[$i-1]} != dummy.ps ]
then back=${sheet[$i-1]}
sheet[$i-1]=${back/f/b}
fi
done
}
swaprows(){
declare -a sheetcopy=(${sheet[@]})
for row in $(seq $numrows)
do let start=(row-1)*width
let end=row*width-1
swap
done
}
swap(){
for i in $(seq $width)
do sheet[$start+$i-1]=${sheetcopy[$end-$i+1]}
done
}
dopad
doallsheets
mpage -$nup -k -c -bA4 -l -a -P- -L5 -W40 -H ${final[@]} >out.ps
我用以下生成的一些 PostScript 文件对此进行了测试enscript
:
create(){
echo "$1" | enscript -fCourier30 -FCourierBold30 -p- | eps2eps - - >"${2?}"
}
startup(){
for i in $(seq -f '%02.0f' 11)
do create "item $i front" f$i.ps
create "item $i back" b$i.ps
done
create "dummy" dummy.ps
}
startup