Skip to content

Instantly share code, notes, and snippets.

@rpls
Created November 24, 2014 21:07
Show Gist options
  • Save rpls/014102ea8adb600ce3c3 to your computer and use it in GitHub Desktop.
Save rpls/014102ea8adb600ce3c3 to your computer and use it in GitHub Desktop.
A small script to send colored- and bw-pages to seperate printers.
#!/usr/bin/env python
# coding: utf-8
import argparse
import itertools
import re
import subprocess
def run_coverage(filename, gs):
"""
Run ghostscript to determine the color-coverage of each page.
"""
output = subprocess.check_output('{} -o - -sDEVICE=inkcov {}'.format(gs, filename).split())
# Scan through the output, match the pagenumber and color-components.
output = re.findall('^Page ([0-9]+)\n (0\.\d+) (0\.\d+) (0\.\d+) (0\.\d+).+$',
output, re.MULTILINE)
pages = []
for page in output:
# Page number
p = int(page[0])
c, m, y, k = (float(col) for col in page[1:])
# Colored pages have non-zero color components.
colored = c > 0 or m > 0 or y > 0
# Appends page-number and boolean flag.
pages.append((p, colored))
return pages
def lp_commands(filename, pages, bwprinter, colprinter, lp):
"""
Determine appropriate lp commands to print the page. This will sort the
pages and group adjacent colored/uncolored pages together.
"""
# Sort by pagenumber.
pages = sorted(pages, key=lambda x: x[0])
commands = []
for colored, pages in itertools.groupby(pages, lambda x: x[1]):
# The join later requires strings. Also pages is now an iterator, not a list.
pages = list(str(page[0]) for page in pages)
commands.append('{lp} -d {printer} -P {pages} {filename}'.format(
lp=lp,
printer=colprinter if colored else bwprinter,
pages=','.join(pages),
filename=filename
))
return commands
def parse_arguments():
"""
Parse arguments.
"""
parser = argparse.ArgumentParser(description='Generate lp printing script, ' +
'separating colorless and colored pages.')
parser.add_argument('-d', help='Destination printer for grayscale pages.',
type=str, required=True, metavar='DESTBW')
parser.add_argument('--col', help='Destination printer for colored pages.' +
'\nDefault is B/W printer with "_color" suffix.',
type=str, metavar='DESTCOL')
parser.add_argument('--ghostscript', help='Path to the ghostscript binary',
type=str, default='gs', metavar='GS')
parser.add_argument('--lp', help='Path to the lp binary',
type=str, default='lp')
parser.add_argument('--dry-run', help='Don\'t run lp, just print the commands',
action='store_true', dest='dryrun')
parser.add_argument('inputfile', help='The PDF input file',
type=str, nargs=1)
parser.set_defaults(dryrun=False)
return parser.parse_args()
def main():
args = parse_arguments()
filename = args.inputfile[0]
bwprinter = args.d
if args.col is not None:
colprinter = args.col
else:
colprinter = bwprinter + '_color'
pages = run_coverage(filename, args.ghostscript)
commands = lp_commands(filename, pages, bwprinter, colprinter, args.lp)
if args.dryrun:
for cmd in commands:
print(cmd)
else:
subprocess.check_call(cmd.split())
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment