Skip to content

Instantly share code, notes, and snippets.

@frederik-elwert
Created November 27, 2020 10:47
Show Gist options
  • Save frederik-elwert/5d0fee06aad946c75ef03084a2684233 to your computer and use it in GitHub Desktop.
Save frederik-elwert/5d0fee06aad946c75ef03084a2684233 to your computer and use it in GitHub Desktop.
Script that performs mail merge using pandoc, jinja2, and pdftk.
#!/usr/bin/env python3
import sys
import argparse
import logging
import csv
import subprocess
import tempfile
from pathlib import Path
from jinja2 import Template
def merge(input_file, csv_file, output_file, extra_args):
template = Template(input_file.read_text())
tempdir = tempfile.TemporaryDirectory(
prefix='pandoc_merge_',
dir=input_file.parent)
tempdir_path = Path(tempdir.name)
logging.debug(f'Using temporary directory {tempdir_path}.')
output_files = []
with csv_file.open() as csvfile:
for i, data in enumerate(csv.DictReader(csvfile)):
content = template.render(**data)
tmpname = f'temp{i:05d}'
tmppath = (tempdir_path / tmpname).with_suffix(output_file.suffix)
output_files.append(tmppath)
cmd = ['pandoc', '-o', tmppath] + extra_args
subprocess.run(cmd, input=content, text=True, check=True)
subprocess.run(['pdftk'] + output_files + ['cat', 'output', output_file])
tempdir.cleanup()
def main():
# Parse commandline arguments
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument('-v', '--verbose', action='store_true')
arg_parser.add_argument('--csv', type=Path)
arg_parser.add_argument('-o', '--outfile', type=Path)
arg_parser.add_argument('input', type=Path)
args, extra_args = arg_parser.parse_known_args()
# Set up logging
if args.verbose:
level = logging.DEBUG
else:
level = logging.ERROR
logging.basicConfig(level=level)
# Return exit value
merge(args.input, args.csv, args.outfile, extra_args)
return 0
if __name__ == '__main__':
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment