Friday, December 20, 2013

Command Line Mail Merge For Wedding Invitations With Perl

Recently I've been occupied making wedding invitations, so I haven't really done anything too technical, but during this task I did come across a nice little command line trick that could come in handy.

I like to lay out documents like wedding invitations in Libre Impress, it's basically the open source answer to PowerPoint.  You might think it's weird to do layout like this in a presentation program, but it's simple and it allows me to exactly control text and graphics and how they're positioned on the page.  The one drawback this method has is that I can't find a way to import a guest list into a template and generate a final document, basically a mail merge, but there is a pretty easy work around using the command line.

The invitations I want are really basic.  They're text only and approximately one third the size of an A4 page.  They do however need to be personalised, which makes things a little harder but not impossible.  The first step is to complete one invitation and use a generic place holder for the name of the guest.  Use something that won't appear somewhere else in the file.  I'm using the string GuestName. This invitation is then copied to fit 3 onto the page.  You then duplicate this page as many times as you need to so that there are enough invitations in the file.

For this process to work the file needs to be saved in the flat open document format, fodp.  The format is xml based and is easily read, but you need to use the flat version that's uncompressed.  That way the place holder string, GuestName, is in the file in plain text.

Wedding Invitation
Template Invitation
I've mocked up a quick invitation to demonstrate the process.  I've put a few Easter eggs in the invitation mainly just to amuse myself.

Wedding Invitation
Template Invitation

The next thing you need is a guest list.  A simple text file will suffice.  For this I've created a file that contains three people.  Each person is on a separate line.

guests.txt

Alice
Bob
Eve

What's needed now is a way to replace the place holder string GuestName with names from the guests file.  Each time a string GuestName is found it needs to be replaced with a different guest from the guests file.  It turns out that following perl command is ideal for this.

perl -pe 's/GuestName/chomp($r=<STDIN>);$r/ge' Template.fodp < Guests.txt > Invitations.fodp

I'm still learning how it all works but I'll try and explain the command.

the e option allows the command to be entered on the command line
the p option loops over the command and prints the result
the s command is used to replace the string GuestName with chomp($r=<STDIN>);$r
chomp($r=<STDIN>);$r reads a line from the standard input, the Guest.txt file, and removes the newline character at the end.
the g option means do a global search and replace
the e option indicates to evaluate the replace expression

This is the result.  The place holder has been replaced with the name of the guest.

Wedding Invitation
Final Invitation
I can then use the Invitations.fodp file to generate a pdf and then print out the invitations.  There's one thing to point out though.  Just because a GuestName string is first on the page it doesn't mean it's first in the file.  So the input order may not be maintained exactly, it can be done, but you just need to be aware of it.  For me the order doesn't matter so I'm not concerned about it.

No comments:

Post a Comment