/* * $Id: pdfbook.c 916 2009-09-16 09:32:26Z eldering $ * * pdfbook.c Rearrange pages in a PDF file into signatures. * * Authors: Tigran Aivazian * Jaap Eldering * Roman Buchert * Pierre Francois * * Based on the algorithm from psutils/psbook.c, which was * written by Angus J. C. Duggan 1991-1995. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 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, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * */ #include #include #include #include #include #include #define TMP_INFILE_BASE "input" #define TMP_OUTFILE_BASE "output" #define DEF_PAPERSIZE "a4" char *program; static void usage(void) { fprintf(stderr, "Usage: %s [OPTION]... infile outfile\n" " or: %s [-q] [-p ] -o infile outfile\n" "Rearrange pages for printing as booklet.\n\n" "Options:\n" " -q suppress verbose output\n" " -d debug mode: do not cleanup temporary files\n" " -2 place 2 pages on 1 page of output\n" " -s group pages together in groups of size \n" " must be positive and divisible by 4\n" " -r reduce the last book to minimum required number of pages\n" " -p set the paper size to: a3, a4, a5, b3, b4, b5, letter, legal\n" " or executive (default is determined from infile, %s if unknown)\n" " -o pass directly to LaTeX pdfpages `includepdf' command\n" " see the pdfpages package documentation for possible options\n", program, program, DEF_PAPERSIZE); fflush(stderr); exit(1); } char *alloc_and_copy (char *str) { char *new_str; if ( (new_str = strdup(str)) == NULL ) { fprintf(stderr, "%s: error allocating memory\n", program); exit(1); } return (new_str); } int check_papersize (char *p) { if ((strlen(p) == 2) && ((*p == 'a') || (*p == 'b')) && ((p[1] >= '3') && (p[1] <= '5'))) { return (1); /* a3, a4, a5, b3, b4 or b5 */ } if ((strcmp(p, "letter") == 0) || (strcmp(p, "legal") == 0) || (strcmp(p, "executive") == 0)) { return (1); /* letter, legal or executive */ } return (0); /* invalid paper size */ } char *make_tempdir() { static char dirtemplate[L_tmpnam+10]; char *dirname; if ( (dirname = tempnam(NULL, "pdfbk")) == NULL ) { fprintf(stderr, "%s: error generating temporary directory\n", program); exit(1); } strcpy(dirtemplate, dirname); strcat(dirtemplate, "XXXXXX"); if ( (dirname = mkdtemp(dirtemplate)) == NULL ) { fprintf(stderr, "%s: error generating temporary directory\n", program); exit(1); } return dirname; } char *allocstr(char *format, ...) { va_list ap; char *str; char tmp[2]; int len, n; va_start(ap,format); len = vsnprintf(tmp,1,format,ap); va_end(ap); if ( (str = (char *) malloc(len+1))==NULL ) return NULL; va_start(ap,format); n = vsnprintf(str,len+1,format,ap); va_end(ap); if ( n==-1 || n>len ) { fprintf(stderr, "%s: error allocating memory\n", program); exit(1); } return str; } int main(int argc, char *argv[]) { char *infile = NULL; char *outfile = NULL; char *tmpdir; char *tmptexfile; char *tmpinfile; char *tmpoutfile; FILE *fp, *fout; int *actualpg; static char cmdline[1024]; int quiet = 0; int debug = 0; int nup = 0; int pdfcustom = 0; int signature = 0; int reducelastbook = 0; int npages = 0; int maxpage; int completebooks = 0; int restpages = 0; int restsignature = 0; char *pdfcustom_str = NULL; char *papersize_str = NULL; char origpapersize[32]; int i, c; program = argv[0]; tmpdir = make_tempdir(); while ( (c = getopt(argc, argv, "2qds:o:p:r")) != -1 ) { switch (c) { case 's': signature = atoi(optarg); if (signature < 1 || signature % 4) usage(); break; case 'r': reducelastbook = 1; break; case '2': nup = 1; break; case 'o': pdfcustom = 1; pdfcustom_str = alloc_and_copy(optarg); break; case 'p': papersize_str = alloc_and_copy(optarg); if (check_papersize(papersize_str) == 0) { fprintf(stderr, "%s: bad paper size `%s'\n", program, papersize_str); usage (); } break; case 'q': quiet = 1; break; case 'd': debug = 1; break; default: usage(); } } if ( optind /dev/null 2>&1 < /dev/null", tmpdir, tmptexfile); if (system(cmdline)) { fprintf(stderr, "%s: Failed to generate output, see \"%s/%s.log\" for details\n", program, tmpdir, TMP_OUTFILE_BASE); exit(1); } sprintf(cmdline, "cp '%s' '%s'", tmpoutfile, outfile); if (system(cmdline)) { fprintf(stderr, "%s: Failed to write \"%s\" file\n", program, outfile); exit(1); } if (!debug) { sprintf(cmdline, "rm -rf '%s'", tmpdir); system(cmdline); } return 0; }