#!/usr/bin/env python
"""
Sort the library file like KiCad does, to minimize diffs
"""
import os
import re
import sys
import pprint
def get_groups_in_order(lines):
order = ['#', 'DEF', 'F0' , 'F1', 'F2', 'F3', 'DRAW',
'A', 'S', 'T', 'P', 'X',
'ENDDRAW', 'ENDDEF',
]
for this in order:
yield([x for x in lines if x.startswith(this)])
def sort_chunk(lines):
res = []
for this in get_groups_in_order(lines):
if not this:
continue
if this[0].startswith('#'):
res += this
else:
# secondary sort of elements in a group
sortfun = None
if this[0].startswith('T'):
sortfun = lambda x: (x.split(' ')[8]) # text
if this[0].startswith('X'):
sortfun = lambda x: (x.split(' ')[2]) # pin
if this[0].startswith('S'):
sortfun = lambda x: (int(x.split(' ')[1]),
int(x.split(' ')[2]),
int(x.split(' ')[3]),
int(x.split(' ')[4]),
)
if this[0].startswith('P'):
sortfun = lambda x: (int(x.split(' ')[1]),
int(x.split(' ')[5]),
int(x.split(' ')[6]),
int(x.split(' ')[7]),
int(x.split(' ')[8]),
)
if this[0].startswith('A'):
sortfun = lambda x: (int(x.split(' ')[1]),
int(x.split(' ')[2]),
)
if sortfun:
try:
this = sorted(this, key=sortfun)
except ValueError:
pass
#if this[0].startswith('P'):
# # XXX HACK WHILE DEVELOPING TO MINIMIZE DIFF
# for t in range(len(this)):
# if not this[t][-3:] in [' N\n', ' f\n', ' F\n'):
# this[t] = this[t][:-1] + ' N\n'
res += this
return res
def chunk_file(fd):
res = []
for this in fd.readlines():
res += [this]
if this.startswith('ENDDEF'):
if res[0] != '#\n':
res = ['#\n'] + res
name = res[1].split(' ')[1][:-1]
sorted_lines = sort_chunk(res)
yield(name, ''.join(sorted_lines))
res = []
def sort_symbols(fn_in, fn_out, refdes):
in_ = open(fn_in)
out = open(fn_out, 'w')
fn = os.path.basename(fn_in)
print('Remapping symbols in in {}'.format(fn))
header = in_.readline() + in_.readline()
symbols = {}
for k, v in sorted(chunk_file(in_)):
symbols[k] = v
out.write(header)
for k in sorted(symbols.keys()):
out.write(symbols[k])
out.write('#\n#End Library\n')
return True
def main(libs):
refdes = {}
for this in sorted(libs):
if sort_symbols(this, this + '.tmp', refdes):
os.rename(this + '.tmp', this)
return True
if __name__ == '__main__':
try:
if len(sys.argv) == 0:
sys.stderr.write('Syntax: sort-symbols.py *.lib\n')
sys.exit(1)
libs = [x for x in sys.argv if x.endswith('.lib')]
res = main(libs)
if res:
sys.exit(0)
sys.exit(1)
except KeyboardInterrupt:
pass