2

I have a script to generate visiting cards for the entire team from an svg template. It spits out a single pdf the size of a visiting card, like so:

+-----------------+
|      o  o       |
|      \__/       |
|                 |
+-----------------+

Now, for printing, I know 12 of these fit on one A4 page. If arranged like this:

+---+---+---+---+
|   |   |   |   |
|:) |:) |:) |:) |
|   |   |   |   |
+---+---+---+---+
|   |   |   |   |
|:) |:) |:) |:) |
|   |   |   |   |
+---+---+---+---+
|   |   |   |   |
|:) |:) |:) |:) |
|   |   |   |   |
+---+---+---+---+

So, I need a script to do this on the pdf level. Any clues what tools might do the trick?

2

Given the suggestions by Anthon, I went with this script. The main idea was to first export the pdf back to plain-svg, compose the svg and export it as pdf again. The A4 sizes are hard coded, but can be changed in the script.

#!/bin/bash

# If you modify/extend this script, it'd be cool if you post your improvements on
#      https://unix.stackexchange.com/q/177263/9495

# This is A4 size
TARGET_WIDTH=744.09003
TARGET_HEIGHT=1052.3622
ext=".a4_4x3.pdf"
draw_border="1" # set to 0 to deactivate borders

TEMP_DIR="$(mktemp -d)"

pdftk A="$1" cat Aeast output "$TEMP_DIR/rot.pdf"

inkscape --export-plain-svg="$TEMP_DIR/rot.plain.svg" "$TEMP_DIR/rot.pdf"

psvg="$(cat "$TEMP_DIR/rot.plain.svg" | tr '\t' ' ' | tr -d '\n' | sed 's/</\n</g; s/>/>\n/g' | grep '.')"

W="$(echo "$psvg" | sed -n 's/^.*width="\([0-9.]\+\)".*$/\1/p' | head -n 1)"
H="$(echo "$psvg" | sed -n 's/^.*height="\([0-9.]\+\)".*$/\1/p' | head -n 1)"

orig_g="$(echo "$psvg" | sed -n '/^<g/,$p' | sed '$,$d')"
if [ "$draw_border" = "1" ]; then
  main_g="$(echo '<rect style="stroke-width:1px; stroke:#000000; fill:#ffffff" width="'"$W"'" height="'"$H"'" />'; echo "$orig_g")"
else
  main_g="$orig_g"
fi
husk_open="$(echo "$psvg" | sed '/^<g/,$d' \
 | sed "s/width=\"$W\"/width=\"$TARGET_WIDTH\"/"\
 | sed "s/height=\"$H\"/height=\"$TARGET_HEIGHT\"/")"
husk_close="</svg>"

move_right () {
  echo "<g transform=\"translate($W,0)\">"
  cat
  echo "</g>"
}
move_down () {
  echo "<g transform=\"translate(0,$H)\">"
  cat
  echo "</g>"
}
mk_row () {
  echo "$1"
  echo "$1" | move_right
  echo "$1" | move_right | move_right
  echo "$1" | move_right | move_right | move_right
}
mk_all () {
  mk_row "$1"
  mk_row "$1" | move_down
  mk_row "$1" | move_down | move_down
}

margin_L="$(python -c "print ($TARGET_WIDTH - 4*$W)/2.")"
margin_H="$(python -c "print ($TARGET_HEIGHT - 3*$H)/2.")"

(
  echo "$husk_open"

  echo "<g transform=\"translate($margin_L,$margin_H)\">"
  mk_all "$main_g"
  echo "</g>"

  echo "$husk_close"
) | tr -d '\n' > "$TEMP_DIR/out.svg"

inkscape --export-pdf="$1$ext" "$TEMP_DIR/out.svg"

rm -r "$TEMP_DIR"
  • If this answer solves your issue please take a minute and click the check mark under the vote count to the left, this will signify to everyone that your issue's been resolved and is the way that thanks are expressed in the site. You can do so even (or especially) when it is your own answer. – Anthon Jan 5 '15 at 14:41
  • @Anthon: Yeah I know. But you have to wait a minimum of 6 hours on your own answer, so I cannot accept it yet (but will do so). – bitmask Jan 5 '15 at 14:42
  • Oh, I never came up with an answer to my own questions, good enough to accept. Hence I never noticed ;-) – Anthon Jan 5 '15 at 14:46
1

I don't know of any off-the-shelf 12-on-1 postscrript/pdf application and you cannot get this result with combining the more standard 2-on-1 or 4-on-1.

What you can do is combine pdf files on one page with pdftk and its background option. However it does not allow you to position the individual cards. It might be easiest to generate 12 A4 size visiting cards each with the rendering properly positioned (and rotated), with transparent background and then combine these. If you cannot do that, you should look into using ghostscript to do the rotation and transform, and combine the output.

This assumes you don't generate the PDF from an image (which will usually give lower quality, but makes it easier to combine the individual files on the image level)

  • Ugh, sorry for the name typo! – bitmask Jan 5 '15 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.