chiark / gitweb /
@@@ fltfmt wip
[mLib] / t / template-canonify
CommitLineData
e63124bc
MW
1#! /usr/bin/python
2
3import os as OS
4import re as RX
5import sys as SYS
6if SYS.version_info >= (3,):
7 from io import StringIO
8 xrange = range
9else:
10 from cStringIO import StringIO
11
12PROG = OS.path.basename(SYS.argv[0])
13USAGE = "usage: %s TEMPLATE INPUT TPLOUT OUTPUT" % PROG
14##
15## The TEMPLATE contains text containing placeholders of the form
16##
17## ={TAG:PAT}
18##
19## TAG is some string, and PAT is a Python regular expression. The TEMPLATE
20## matches the INPUT if there is some way to replace each placeholder by a
21## string matching its PAT such that the two are equal.
22##
23## The TPLOUT file is a copy of the TEMPLATE file, with each placeholder
24## replaced by ={TAG}. If the TEMPLATE matches the INPUT, then the OUTPUT
25## equals TPLOUT; otherwise, the program tries to replace as many portions of
26## the INPUT which match placeholder PATs as it can, but it doesn't currently
27## do an especially good job.
28
29if len(SYS.argv) != 5:
30 SYS.stderr.write("%s\n" % USAGE)
31 SYS.exit(2)
32_, tplfn, infn, toutfn, outfn = SYS.argv
33
34tfin = open(tplfn, "r"); tfout = open(toutfn, "w")
35fin = open(infn, "r"); fout = open(outfn, "w")
36
37R_PLCH = RX.compile(r"""
38 = \{ ([^}:]+) : ((?: [^\\}]+ | \\.)*) \}
39""", RX.S | RX.X)
40
41while True:
42 t = tfin.readline(); l = fin.readline()
43 if not (t or l): break
44
45 lit = []; tag = []; pat = []; pos = 0
46 for m in R_PLCH.finditer(t):
47 lit.append(t[pos:m.start()])
48 tag.append(m.group(1))
49 pat.append(m.group(2))
50 pos = m.end()
51 lit.append(t[pos:])
52 n = len(pat)
53
54 skelsio = StringIO(); gensio = StringIO(); xctsio = StringIO()
55 gensio.write("^"); xctsio.write("^")
56 for i in xrange(n):
57 q = RX.escape(lit[i])
58 skelsio.write("%s={%s}" % (lit[i], tag[i]))
59 xctsio.write(q + pat[i])
60 gensio.write(q + "(.*)")
c81c35df 61 q = RX.escape(lit[n])
e63124bc
MW
62 skelsio.write(lit[n]); skel = skelsio.getvalue()
63 xctsio.write(q); xctsio.write("$"); xct = xctsio.getvalue()
64 gensio.write(q); gensio.write("$"); gen = gensio.getvalue()
65
66 tfout.write(skel)
67 if not l: continue
68
69 if RX.match(xct, l): fout.write(skel); continue
70
71 m = RX.match(gen, l)
72 if not m: fout.write(l); continue
73 sio = StringIO()
74 for i in xrange(n):
75 sio.write(lit[i])
76 if RX.match("^%s$" % pat[i], m.group(i + 1)): sio.write("={%s}" % tag[i])
77 else: sio.write("!{%s:%s}" % (tag[i], m.group(i + 1)))
78 sio.write(lit[n])
79 fout.write(sio.getvalue())
80
81tfin.close(); tfout.close()
82fin.close(); fout.close()