#! /usr/bin/python import os as OS import re as RX import sys as SYS if SYS.version_info >= (3,): from io import StringIO xrange = range else: from cStringIO import StringIO PROG = OS.path.basename(SYS.argv[0]) USAGE = "usage: %s TEMPLATE INPUT TPLOUT OUTPUT" % PROG ## ## The TEMPLATE contains text containing placeholders of the form ## ## ={TAG:PAT} ## ## TAG is some string, and PAT is a Python regular expression. The TEMPLATE ## matches the INPUT if there is some way to replace each placeholder by a ## string matching its PAT such that the two are equal. ## ## The TPLOUT file is a copy of the TEMPLATE file, with each placeholder ## replaced by ={TAG}. If the TEMPLATE matches the INPUT, then the OUTPUT ## equals TPLOUT; otherwise, the program tries to replace as many portions of ## the INPUT which match placeholder PATs as it can, but it doesn't currently ## do an especially good job. if len(SYS.argv) != 5: SYS.stderr.write("%s\n" % USAGE) SYS.exit(2) _, tplfn, infn, toutfn, outfn = SYS.argv tfin = open(tplfn, "r"); tfout = open(toutfn, "w") fin = open(infn, "r"); fout = open(outfn, "w") R_PLCH = RX.compile(r""" = \{ ([^}:]+) : ((?: [^\\}]+ | \\.)*) \} """, RX.S | RX.X) while True: t = tfin.readline(); l = fin.readline() if not (t or l): break lit = []; tag = []; pat = []; pos = 0 for m in R_PLCH.finditer(t): lit.append(t[pos:m.start()]) tag.append(m.group(1)) pat.append(m.group(2)) pos = m.end() lit.append(t[pos:]) n = len(pat) skelsio = StringIO(); gensio = StringIO(); xctsio = StringIO() gensio.write("^"); xctsio.write("^") for i in xrange(n): q = RX.escape(lit[i]) skelsio.write("%s={%s}" % (lit[i], tag[i])) xctsio.write(q + pat[i]) gensio.write(q + "(.*)") q = RX.escape(lit[n]) skelsio.write(lit[n]); skel = skelsio.getvalue() xctsio.write(q); xctsio.write("$"); xct = xctsio.getvalue() gensio.write(q); gensio.write("$"); gen = gensio.getvalue() tfout.write(skel) if not l: continue if RX.match(xct, l): fout.write(skel); continue m = RX.match(gen, l) if not m: fout.write(l); continue sio = StringIO() for i in xrange(n): sio.write(lit[i]) if RX.match("^%s$" % pat[i], m.group(i + 1)): sio.write("={%s}" % tag[i]) else: sio.write("!{%s:%s}" % (tag[i], m.group(i + 1))) sio.write(lit[n]) fout.write(sio.getvalue()) tfin.close(); tfout.close() fin.close(); fout.close()