我有一份PDF文档cards.pdf
,我想用4on1双面打印机设置进行打印。我使用GNU makefile来创建文档,这就是我在寻找解决方案的地方。
将在一个页面上打印四页以节省纸张(而实际上a6是我想要的纸张纸张),并且一些页面将打印在背面。但是,我也希望能够在切纸后翻页以找到正确的背面。我知道我需要按照这个顺序重新排列页面:
1 3 5 7 4 2 8 6
9 11 13 15 ...
我可以使用pdftk
来执行此操作,但存在问题:
cards.pdf
的页数未知。cards.pdf
的页数不一定是8的倍数。我正在寻找一种易于处理的GNU make解决方案来重新排列页面而不会使文档膨胀。
答案 0 :(得分:0)
以下makefile以一种非常糟糕的方式做我想要的事情。为方便起见,我在文档的开头添加了一个空白页面。
qpdf
用于获取cards.pdf
的页数。
规则PG_EIGHT
用于以正确的打印顺序扩展到8页的块。
# declare following rule with = only, no :=
PG_EIGHT = $$((8*$(1)+2)) $$((8*$(1)+4)) $$((8*$(1)+6)) $$((8*$(1)+8)) $$((8*$(1)+5)) $$((8*$(1)+3)) $$((8*$(1)+9)) $$((8*$(1)+7))
#
# use a shell escape to get the number of pages of the pdf file with:
# qpdf --show-npages ./cards.pdf
PG_MAX := $$(( $(shell qpdf --show-npages ./cards.pdf) -1 ))
#
#division discards remainder:
BLOCKS := $(shell seq 0 $$(($(PG_MAX) / 8 - 1)))
PRINT := $(foreach BLOCK,$(BLOCKS),$(call PG_EIGHT,$(BLOCK)))
#
# get the rest (remainder) of the pages with modulo division:
PG_RM := $(shell echo $(PG_MAX)%8 | bc)
# get last page of last BLOCK:
PG_MAX := $$(( $(PG_MAX) - $(PG_RM) ))
#
# do nothing if remainder is 0.
ifeq ($(PG_RM),1)
PRINT += $$(( $(PG_MAX) + 2))
else ifeq ($(PG_RM),2)
PRINT += $$(( $(PG_MAX) + 2)) 0 0 0 0 $$(( $(PG_MAX) + 3))
else ifeq ($(PG_RM),3)
PRINT += $$(( $(PG_MAX) + 2)) $$(( $(PG_MAX) + 4)) 0 0 0 $$(( $(PG_MAX) + 2))
else ifeq ($(PG_RM),4)
PRINT += $$(( $(PG_MAX) + 2)) $$(( $(PG_MAX) + 4)) 0 0 $$(( $(PG_MAX) + 5)) $$(( $(PG_MAX) + 3))
else ifeq ($(PG_RM),5)
PRINT += $$(( $(PG_MAX) + 2)) $$(( $(PG_MAX) + 4)) $$(( $(PG_MAX) + 6)) 0 $$(( $(PG_MAX) + 5)) $$(( $(PG_MAX) + 3))
else ifeq ($(PG_RM),6)
PRINT += $$(( $(PG_MAX) + 2)) $$(( $(PG_MAX) + 4)) $$(( $(PG_MAX) + 6)) 0 $$(( $(PG_MAX) + 5)) $$(( $(PG_MAX) + 3)) 0 $$(( $(PG_MAX) + 7))
else ifeq ($(PG_RM),7)
PRINT += $$(( $(PG_MAX) + 2)) $$(( $(PG_MAX) + 4)) $$(( $(PG_MAX) + 6)) $$(( $(PG_MAX) + 8)) $$(( $(PG_MAX) + 5)) $$(( $(PG_MAX) + 3)) 0 $$(( $(PG_MAX) + 7))
# remainder cannot be equal to 8.
endif
# fully evaluate the PRINT string:
PRINT := $(shell echo $(PRINT))
print.pdf: makefile cards.pdf
echo $(BLOCKS)
pdftk cards.pdf cat $(PRINT) output print.pdf
这段代码的可怕之处在于处理余数和频繁的shell转义。
我不明白为什么它会使文件大小膨胀。
答案 1 :(得分:0)
这是部分GNU make和部分C解决方案。我检查了400页的文件,没有膨胀。如果这是令人满意的,可以将C程序重写为shell脚本并嵌入到makefile中。
我的理解是问题在于为=IFERROR(INDEX(Sheet1!$K$2:$O$7,MATCH(Sheet2!$A2,Sheet1!$A:$A,0),MATCH(Sheet2!F$1,Sheet1!$F2:$J2,0)),"")
生成正确的页码序列。我写了一个小的(< 70lines)C程序,叫做print_order.c来生成那个序列。并且,我修改了pdftk
以使用它。
<强> print_order.c 强>
makefile
已修改#include <stdio.h>
#include <stdlib.h>
int pg_eight [] = {1, 3, 5, 7, 4, 2, 8, 6};
const char* blank_page = "B1";
void advance_pg_eight()
{
int j=0;
for(j=0; j < 8; j++)
pg_eight[j] += 8;
}
void print_pg_eight (long int npages)
{
int j=0;
static int nprinted = 0;
for (j=0; j < 8 && nprinted < npages; j++) {
if(pg_eight[j] > npages)
printf("%4s ", blank_page);
else
{
printf("%4d ", pg_eight[j]);
nprinted++;
}
}
}
long int get_npages(const char *first_arg)
{
char *endptr = "Hello";
long int npages = strtol(first_arg, &endptr, 10);
if (*endptr != '\0' || npages <= 0)
return 0;
return npages;
}
int main (int argc, char* argv[])
{
long int npages = 0;
int neights = 0, j=0;
if (argc < 2) {
fprintf(stderr, "%s: Insufficient number of arguments\n", argv[0]);
return 0;
}
npages = get_npages(argv[1]);
if (0 == npages) {
fprintf(stderr, "%s: Failed to parse number of pages (%s)\n", argv[0], argv[1]);
return 0;
}
neights = npages/8;
if (npages % 8 != 0)
neights++;
for(j = 0; j < neights; j++) {
print_pg_eight(npages);
advance_pg_eight();
printf("\n");
}
printf("\n");
}
makefile
91页的#
# use a shell escape to get the number of pages of the pdf file with:
# qpdf --show-npages ./cards.pdf
NPAGES := $(shell qpdf --show-npages ./cards.pdf)
#
PRINT := $(shell ./print_order $(NPAGES))
print.pdf: makefile cards.pdf blank.pdf print_order
pdftk B=blank.pdf cards.pdf cat $(PRINT) output print.pdf
print_order: print_order.c
示例输出:
print_order
1 3 5 7 4 2 8 6
9 11 13 15 12 10 16 14
17 19 21 23 20 18 24 22
25 27 29 31 28 26 32 30
33 35 37 39 36 34 40 38
41 43 45 47 44 42 48 46
49 51 53 55 52 50 56 54
57 59 61 63 60 58 64 62
65 67 69 71 68 66 72 70
73 75 77 79 76 74 80 78
81 83 85 87 84 82 88 86
89 91 B1 B1 B1 90
是第一页空白的pdf的第一页。
使用此解决方案:
B1
print_order.c
blank.pdf
cards.pdf
希望这有帮助。