6 paperjam - a PDF document processor
10 *paperjam* 'options' 'commands' 'input' 'output'
14 PaperJam is a tool for transform PDF files. It can re-order pages, scale
15 and rotate them, put multiple pages on a single sheet, draw cropmarks,
16 and many other tricks.
18 PaperJam takes an input file, splits it to a list of pages, applies a sequence
19 of commands on this list, and finally writes the results to an output file.
21 For each page, PaperJam tracks two sets of dimensions: the width and height
22 of the 'physical page' (paper), and the 'image box', which is a rectangle on the
23 physical page containing all useful contents. Initially, the physical
24 page is equal to the *CropBox* of the PDF page and the image box to its
25 *ArtBox* (which is optional and it defaults to the *CropBox*). Further
26 commands can modify these dimensions.
31 Recalculate image box of each page to enclose the contents really
32 drawn on the page. This is done by asking GhostScript to render each
36 Show debugging messages. Increases verbosity when given multiple times.
39 Do not perform automatic transforms. Currently, only one such transform
40 is implemented: rotation of pages based on the *Rotate* property of
44 Show help on options and commands.
48 PaperJam takes a list of commands separated by spaces, like this:
50 paperjam 'common scaleto("a4") nup(2, hspace=5mm)' in.pdf out.pdf
52 Each command starts with its identifier (a sequence of alphanumeric characters,
53 underscores, and dashes, which begins with a letter). Then come arguments enclosed
54 in parentheses. All arguments can be written as 'name'='value' (where the name is
55 an identifier). For some of them, the name can be omitted and the meaning
56 follows from the position in the argument list (hence these are called
57 'positional' arguments).
59 There are several types of arguments:
62 Ordinary decimal numbers, possibly fractional.
65 Numbers with a unit of length. We support these units:
66 mm, cm, dm, m, in (inch), pt (printers' point, that is 1/72 in).
69 Strings written in double quotes. If you want to include the double
70 quote character or a backslash in the string, precede it with a backslash.
71 For convenience, the double quotes can be omitted if the string value
72 satisfies the syntax of an identifier. In case of positional arguments,
73 the identifier must not match the name of any argument. Please avoid
74 using this shortcut in scripts, because they could be easily broken
75 by parameters introduced in newer versions of PaperJam.
78 Boolean value: either 0 (false) or 1 (true). If only the name is given (with no value
79 and no equal sign), the switch is set to true.
83 Several commands apply other commands on a subset of pages. This is usually
84 described by a 'pipeline' like:
86 { 1: rotate(90), 2: flip(h) flip(v) }
88 { 1 2, 11..20, 30..21 }
90 The pipeline is enclosed in curly braces. It consists of one or more 'stages'
91 separated by commas. Each stage has one or more 'page selectors' (page numbers
92 or ranges) and an optional list of commands to apply on these pages (separated
93 from the selectors by a colon).
95 When a range is written backwards (the first page number is greater than the
96 second one), the pages are processed in reverse order.
100 When a paper format is expected, it is given either by its width and height
101 (the corresponding arguments are usually called *w* and *h*), or by the standard
102 name of the format (called *paper*). PaperJam currently uses the libpaper library
103 for parsing the names. You can call +paperconf -a+ to get the list of known names.
107 Many commands take a specification of margins on all sides of an image.
108 You can set either a common value for all margins, or two values for vertical
109 and horizontal margins, or separate values for all margins. You can also
110 combine these ways: for example you can set a horizontal, top, and bottom
113 More formally, there are 7 arguments controlling margins: common,
114 horizontal, vertical, left, right, top, and bottom. Horizontal and vertical
115 default to common, left and right default to horizontal, top and bottom default
120 Multiple commands involve positioning an image on a larger page. The image
121 is placed according to a two-letter position specification (usually an argument
122 called *pos*). The first letter specifies vertical placement: *t* for top,
123 *c* for center, *b* for bottom. The second one horizontal placement: *l* for left,
124 *c* for center, *r* for right.
128 PaperJam knows the following commands and arguments. Positional arguments
129 have their names enclosed in square brackets.
133 Add blank page(s) after each page.
136 The number of blank pages to add. Defaults to 1.
138 *[paper=]*'string', *w=*'dimen', *h=*'dimen'::
139 Paper size of the blank pages (see Paper formats above).
143 Applies commands on a sub-set of pages:
145 apply { 1: rotate(90), 2: flip(h) }
147 Takes a pipeline. For each input page, it finds the pipeline stage
148 matching the page index (its position in the input document, starting with 1)
149 and applies the commands in the stage on the page. If no stage matches,
150 the page is left unchanged. If multiple stages match, the first one wins.
154 Prepares booklets (also known as signatures) for book binding.
155 With no argument, it re-orders pages in the document, so that a subsequent
156 *nup(2)* produces the correct booklet layout: two pages on one sheet
157 and when the document is printed double-sided and folded in half,
158 you have a booklet. If the number of input pages is not divisible by 4,
159 blank pages are added.
162 Split the document in parts per 'n' pages and produce a separate
163 booklet from each part. The 'n' must be divisible by 4.
167 Suppress page contents drawn outside the image box.
170 Let the image bleed this far outside the image box.
171 (Technically, it sets the crop box to the image box enlarged
172 at all sides by this amount.)
176 Use a common page size and image box for all pages. More specifically,
177 the new page width and height are set to the maximum of all page widths
178 and heights and the new image box to the minimal rectangle containing all
183 Draw cropping marks around the image box.
187 *box* for a rectangle around the image box,
188 *cross* for crosses in the corners of the box,
189 *in* for two arms of a cross in each corner, pointing inwards,
190 *out* for two arms pointing outwards,
191 *bg* for drawing a filled rectangle under the box.
194 Pen width for drawing cropmarks (for all styles except bg).
198 Cropmark arm length (for cross, in, out).
202 Draw cropmarks around image box enlarged by this distance
206 Cropmark color, given as RRGGBB in hexadecimal.
207 Default: +000000+ (black).
211 Draw debugging information on each page: a red rectangle around the page,
212 a green rectangle around the image box.
216 Expand paper around the image. Recalculates paper size and the position
217 of the image on the paper, so that the distance between each edge of the
218 image box and the corresponding edge of the paper increases by the given
222 Adjust all margins by the same amount. Defaults to 0.
224 *h=*'dimen', *v=*'dimen', *l=*'dimen', *r=*'dimen', *t=*'dimen', *b=*'dimen'::
225 Adjust horizontal, vertical, left, right, top, and bottom margins.
226 See Margins above to see how these arguments interact with each other.
230 If a paper size is given, scale and translate the image to fit on the
231 paper (with given margins). If no paper is given, set the paper size
232 and the position of the image according to the margins.
234 If the paper and the image have different aspect ratios, the *pos*
235 argument controls the position of the image on the paper.
237 *[paper=]*'string', *w=*'dimen', *h=*'dimen'::
238 Paper format, or paper width and height (see Paper formats above
242 Specify position of the image on the paper (see Positioning above).
245 *margin=*'dimen', *hmargin=*'dimen', *vmargin=*'dimen', *lmargin=*'dimen', *rmargin=*'dimen', *tmargin=*'dimen', *bmargin=*'dimen'::
246 Set margins (see Margins above). Defaults to 0.
250 Flip pages horizontally or vertically.
260 Define a new image box by dimensions of margins around it. More technically,
261 the new image box is calculated from the page box by shrinking it by the appropriate
265 Set all margins at once.
267 *h=*'dimen', *v=*'dimen', *l=*'dimen', *r=*'dimen', *t=*'dimen', *b=*'dimen'::
268 Set margins (see Margins above). Defaults to *size*.
272 Merge all pages to one by placing them one over another. (The first page is drawn
277 Act on n-tuples of pages.
278 The document is split to n-tuples (the partial n-tuple at the end is padded with
279 blank pages, whose size matches the first page of the n-tuple).
280 A pipeline is then run separately for each n-tuple, selecting pages from the tuple
281 and applying commands on them.
283 More specifically, the stages of the pipeline are processed from the left to the
284 right. Each stage forms a temporary document by taking the selected pages from the n-tuple
285 (numbered from 1 to n). Then it applies the commands on this document and appends the
286 result to the end of the output of the whole modulo.
288 Negative page numbers can be also used, which adresses pages in the "mirror-image
289 tuple". Page number -'i' in tuple 'j' corresponds to page 'i' in the 'j'-th tuple
290 from the end of the document.
294 *[n=]*'int' (mandatory)::
295 Number of pages in a single tuple.
298 Process only the first half of n-tuples. This is often used in conjunction
299 with negative page numbers.
301 For example, the following command rotates every other page:
303 modulo(2) { 1, 2: rotate(180) }
305 While this command skips every other page:
311 Shift contents on the page. Paper size does not change, the image box moves.
313 *[x=]*'dimen', *[y=]*'dimen'::
314 Move everything right/up by the given distance.
322 Combine multiple pages to one (n-up printing). Allows detailed control over the
323 parameters, but if only a subset of the parameters is given (in the most trivial case,
324 just the number of pages to put on a single sheet), the remaining parameters are
325 adjusted to maximize coverage of the sheet.
327 For example, when the input document is typeset on A4 paper,
328 +nup(2)+ rotates pages by 90 degrees, scales them to 70.7% size,
329 and puts them side-by-side. On the same input, +nup(4)+ produces
330 the same as +nup(2,2)+, that is a two-by-two grid of pages scaled
333 Technically, nup first splits the input document to n-tuples of pages
334 (padding the last incomplete n-tuple with blank pages of the size of the
335 first page of that n-tuple). For each n-tuple, it creates an output page,
336 splits it to a grid-like arrangement of tiles, and scales and/or rotates
337 each page to fit in its tile.
340 If *m* is also given, *n* is the number of rows of the grid of tiles.
341 Without *m*, the total number of tiles on a page.
344 The number of columns of the grid of tiles.
347 Tile filling order: *rows* (default) fills rows from the top to the bottom,
348 inside each row from the left to the right; *cols* fills columns from
349 the left to the right, inside each column from the top to the bottom;
350 *tile* copies the same page to all tiles.
353 Crop input pages to their image box. (By default, *nup* places the input
354 papers in tiles. With this option, it places the image boxes in tiles,
355 effectively cutting away original margins.)
358 By default, *nup* adjusts all input pages to a common paper size and
359 image box size (like the *common* command does). This switch disables
363 Specify if the pages should be rotated. Default: choose automatically.
366 Scaling factor. Default: choose automatically.
368 *[paper=]*'string', *w=*'dimen', *h=*'dimen'::
369 Paper size (see Paper formats above).
371 *margin=*'dimen', *hmargin=*'dimen', *vmargin=*'dimen', *lmargin=*'dimen', *rmargin=*'dimen', *tmargin=*'dimen', *bmargin=*'dimen'::
372 Margins around the tile grid (see Margins above). Defaults to 0.
375 Position of the tile grid on the page (see Positioning above).
376 This applies when the *scale* is fixed, or if the aspect ratio of the
377 paper (after subtracting margins) does not match the aspect ratio of
378 the tile grid. Defaults to *cc*.
380 *cmark=*'string', *cpen=*'dimen', *clen=*'dimen', *coffset=*'dimen', *ccolor=*'string'::
381 Draw cropmarks around each tile. See *crop* for the meaning of arguments.
384 Position of original pages inside tiles (see Positioning above).
385 This applies when different pages have different sizes.
388 *space=*'dimen', *hspace=*'dimen', *vspace=*'dimen'::
389 Insert extra spaces between adjacent tiles in the grid (in both directions,
390 horizontally, vertically). This is useful together with *crop*.
394 Place image on a given paper. Sets a new paper size and translates the image box
395 according to the given position.
397 *[paper=]*'string', *w=*'dimen', *h=*'dimen'::
398 Paper size (see Paper formats above).
401 Position of the image on the paper (see Positioning above). Default: *cc*.
405 Rotate the page clockwise by multiples of 90 degrees.
408 Rotation angle. Must be a multiple of 90 degrees.
412 Scale the page by a given factor.
414 *[x=]*'number', *[y=]*'number'::
415 Set horizontal and vertical scaling factor. If only one is given,
416 it is used in both directions.
420 Scale the entire page to a given size.
422 *[paper=]*'string', *w=*'dimen', *h=*'dimen'::
423 Paper size (see Paper formats above).
426 Position of the old paper on the new one (see Positioning above). Default: *cc*.
427 This applies if the aspect ratios of both papers do not match.
431 Selects a subset of pages and optionally applies commands on them.
433 The select command gets a pipeline. It processes the pipeline stages from the left to the
434 right. For each stage, it assembles a temporary document containing the selected pages,
435 applies the stage's commands on it, and appends the resulting document to the output of
436 the whole select command.
438 For example, the following command selects pages 1, 10 to 19, and 20 to 29 in reverse order.
439 The rest of the document is discarded.
441 select { 1 10..19 29..20 }
443 This has the same effect:
445 select { 1, 10..19, 29..20 }
447 This selects two pages and rotates them differently:
449 select { 1: rotate(90), 2: rotate(-90) }
451 The following examples show that the formation of temporary documents can make
452 a difference sometimes:
454 select { 1..10 common, 21..30 common }
455 select { 1..10 21..30 common }
456 select { 1..10 21..30 } common
457 select { 1..10, 21..30 } common
459 The first command forms two temporary documents and applies common to each of them separately
460 (therefore pages 1 to 10 will have one common size and pages 21 to 30 another). The remaining
461 three commands give the same result. The second command forms a single temporary document with 20 pages
462 and applies common to all of it at once. The third command forms a single temporary document,
463 which immediately becomes the result of select, to which the final common is applied. And the fourth
464 command forms two temporary documents, concatenates them to the result of select, and finally applies
469 Slices the image to several smaller pages. Each page receives a part of the original
470 image, gluing the parts together produces the original image.
472 *[paper=]*'string', *w=*'dimen', *h=*'dimen'::
473 Paper size of the produced pages (see Paper formats above).
476 Position of the original image on a "canvas" obtained by gluing
477 together non-margin parts of the produced pages (see Positioning above).
480 *margin=*'dimen', *hmargin=*'dimen', *vmargin=*'dimen', *lmargin=*'dimen', *rmargin=*'dimen', *tmargin=*'dimen', *bmargin=*'dimen'::
481 Set margins of the produced pages (see Margins above). Defaults to 0.
484 Let the parts of the image bleed this far outside their boxes.
488 PaperJam was written by Martin Mares.
489 It can be distributed and used under the terms of the GNU
490 General Public License version 2 or any later version.
494 I conceived the idea of a document processor like PaperJam when struggling with pre-press
495 formatting in the early 2000s. At that time, the basic ideas behind the language were born,
496 but everything was deeply rooted in the then standard PostScript world. After some years,
497 I managed to convince a student of mine Ales Snuparek to implement my ideas as his bachelor's project.
498 He wrote the program PsPdfTool for transforming both PostScript and PDF documents, which turned
499 out to be terribly useful.
501 In the 2010s, limitations of the old design became clear and many PDF documents were using
502 features not known to PsPdfTool (most prominently object streams). After several years of
503 pondering, I became fond of the QPDF library and wrote PaperJam as a modern successor of