#!/bin/python3 # PLUG - "PlacehoLder Un- and Generator" import sys import re def usage(): print( '''{0} -d : define placeholder -u : ungenerate placeholder (collapse) -g : generate placeholder (expand) -f : specify I/O file -h : print help and exit Options are evaluated in the order they are found and can be repeated. If multiple files are specified, actions apply to all of them. \"@all\" is a special pseudo placeholder with the meaning \'every placeholder\'. NOTE: do not forget to specify your file before the desired actions.'''.format(sys.argv[0])) placeholders = {} placeholder = '#placeholder<{0}>' phl_col = placeholder + ' COLLAPSED' phl_exp_beg = placeholder + ' BEGIN' phl_exp_end = placeholder + ' END' re_phl_col = re.compile('''^(.*){0}.*'''.format(phl_col.format('''(\w+)''')), re.M) re_phl_exp_beg = re.compile('''^(.*){0}.*'''.format(phl_exp_beg.format('''(\w+)''')), re.M) re_phl_exp_end = re.compile('''^.*{0}.*'''.format(phl_exp_end.format('''(\w+)''')), re.M) def gen(s, phl): ret = '' l = 0 is_all = (phl == '@all') for m in re_phl_col.finditer(s): if((not is_all) and m.group(2) != phl): continue ret += s[l : m.start(0)] ret += m.group(1) + phl_exp_beg.format(phl) + '\n' ret += placeholders[phl] ret += '\n' + m.group(1) + phl_exp_end.format(phl) l = m.end(0) ret += s[l:] return ret def ungen(s, phl): ret = '' l = 0 is_all = (phl == '@all') for m in re_phl_exp_beg.finditer(s): if((not is_all) and m.group(2) != phl): continue ret += s[l : m.start(0)] ret += m.group(1) + phl_col.format(phl) l = m.end(0) for me in re_phl_exp_end.finditer(s[m.end(0):]): if(me.group(1) != phl): continue l = m.end(0) + me.end(0) break ret += s[l:] return ret def get_param(argv, i, opt): try: param = argv[i] except: print('Missing parameter to flag \'{0}\'.'.format(opt)) exit(2) return param def plug(argv): sfiles = [] i = -1 while i < len(argv)-1: i = i + 1 # 0 param opt if argv[i] == '-h': usage() exit(0) # 2 param opt if argv[i] == '-d': try: placeholders[argv[i+1]] = argv[i+2] i = i + 2 except: print('Unterminated definition (-d).') exit(3) continue # 1 param opt i = i + 1 if argv[i-1] == '-u': for sf in sfiles: with open(sf, 'r') as f: s = ungen(f.read(), get_param(argv, i, '-u')) with open(sf, 'w') as f: f.write(s) continue if argv[i-1] == '-g': for sf in sfiles: with open(sf, 'r') as f: s = gen(f.read(), get_param(argv, i, '-g')) with open(sf, 'w') as f: f.write(s) continue if argv[i-1] == '-f': sfiles.append(get_param(argv, i, '-f')) continue print("Unrecognized flag '{0}'.".format(argv[i])) usage() exit(1) return 0 if __name__ == '__main__': raise SystemExit(plug(sys.argv[1:]))