comparison mez_xml.py @ 0:3679d2d8443a

Import from CVS and goto mez_xml-0.4
author Thinker K.F. Li <thinker@branda.to>
date Wed, 13 Feb 2008 22:33:51 +0800
parents
children d310e097c6de
comparison
equal deleted inserted replaced
-1:000000000000 0:3679d2d8443a
1 from xml.dom.minidom import parse
2 import re
3
4 reo_attr_rep = re.compile('\\$\\{([a-zA-Z_][a-zA-Z0-9_]*)\\}')
5 reserved_keywords = {'commit': None, 'gen_doc': None}
6
7 def clz_name(fn):
8 from os import path
9 return path.basename(fn).split('.')[0]
10
11 def _check_reserved(name):
12 if name.startswith('_') or reserved_keywords.has_key(name):
13 raise NameError, '%s is a reserved keyword' % (name,)
14 pass
15
16 class mez_xml(object):
17 def __init__(self):
18 super(mez_xml, self).__init__()
19 pass
20
21 def template_head(self):
22 self.output_cmd_line('from mez_xml.tools import nez_web')
23 self.output_cmd_line('')
24 self.output_cmd_line('class %s(nez_web):' % (self.cname,))
25 self.dig()
26 self.output_cmd_line('def __init__(self, ofo):')
27 self.dig()
28 self.output_cmd_line('super(%s, self).__init__()' % (self.cname,))
29 self.output_cmd_line('self.ofo = ofo')
30 self.output_cmd_line('pass')
31 self.back()
32 self.output_cmd_line('')
33 pass
34
35 def template_tail(self):
36 self.output_cmd_line('pass')
37 self.back()
38 self.output_cmd_line('')
39 pass
40
41 def subtree_start(self, cname):
42 self.output_cmd_line('def %s(self, pdata, cdata):' % (cname))
43 self.dig()
44 self.output_cmd_line('def temp(data):')
45 self.dig()
46 self.frag_start()
47 pass
48
49 def subtree_stop(self, cname):
50 self.frag_stop()
51 self.output_cmd_line('pass')
52 self.back()
53 self.output_cmd_line('self._feed_subtree(temp, pdata, cdata)')
54 self.output_cmd_line('pass')
55 self.back()
56 self.output_cmd_line('')
57 pass
58
59 def _expand_vars(self, data, _tp):
60 mo = reo_attr_rep.search(data)
61 pos = 0
62 while mo:
63 if pos != mo.start():
64 self.output(data[pos:mo.start()])
65 pass
66 self.frag_stop()
67 name = mo.group(1)
68 subnames = name.split('.')
69 first = subnames[0]
70 self.output_cmd_line('odata = data.setdefault(\'%s\', {})' % (first))
71 for subname in subnames[1:]:
72 self.output_cmd_line('odata = odata.setdefault(\'%s\', {})' % (subname))
73 pass
74 self.output_cmd_line('self.ofo.write(self._esc_%s(odata))' % (_tp))
75 self.frag_start()
76 pos = mo.end()
77 for subname in subnames:
78 _check_reserved(subname)
79 pass
80 #if not self.all_names.has_key(name):
81 #if not self.all_attrnames.has_key(name):
82 # self.travel_q.append((name, None))
83 # self.all_attrnames[name] = None
84 # pass
85 #pass
86 #else:
87 #raise NameError, '%s is redefined' % (name,)
88 mo = reo_attr_rep.search(data, pos)
89 pass
90 self.output(data[pos:])
91 pass
92
93 def _expand_comm(self, data):
94 self._expand_vars(data, 'comm')
95 pass
96
97 def _expand_param(self, data):
98 self._expand_vars(data, 'param')
99 pass
100
101 def _expand_text(self, data,):
102 self._expand_vars(data, 'text')
103 pass
104
105 def _expand_cdata(self, data):
106 self._expand_vars(data, 'cdata')
107 pass
108
109 def gen_attrs(self, attrs):
110 for i in range(attrs.length):
111 attr = attrs.item(i)
112 self.output(' ' + attr.name)
113 val = attr.nodeValue
114 if val:
115 self.output('="')
116 self._expand_param(val)
117 self.output('"')
118 pass
119 pass
120 pass
121
122 def tag_start(self, no):
123 from xml.dom import Node
124 nt = no.nodeType
125 if nt == Node.CDATA_SECTION_NODE:
126 self.output('<![CDATA[')
127 self._expand_cdata(no.data)
128 self.output(']]>')
129 elif nt == Node.COMMENT_NODE:
130 self.output('<!--')
131 self._expand_comm(no.data);
132 self.output('-->')
133 elif nt == Node.TEXT_NODE:
134 self._expand_text(no.data);
135 elif nt == Node.ELEMENT_NODE:
136 self.output('<' + no.tagName)
137 self.gen_attrs(no.attributes)
138 self.output('>')
139 pass
140
141 def tag_stop(self, no):
142 from xml.dom import Node
143 nt = no.nodeType
144 if nt == Node.ELEMENT_NODE:
145 self.output('</%s>' % (no.tagName,))
146 pass
147 pass
148
149 def frag_start(self):
150 self.output_cmd('self.ofo.write(\'\'\'')
151 pass
152
153 def frag_stop(self):
154 self.output_raw('\'\'\')\n')
155 pass
156
157 def call_subtree(self, no):
158 name = no.getAttribute('ezid')
159 self.frag_stop()
160 subnames = name.split('.')
161 first = subnames[0]
162 self.output_cmd_line('cdata = data.setdefault(\'%s\', {})' % (first))
163 for subname in subnames[1:]:
164 self.output_cmd_line('cdata = cdata.setdefault(\'%s\', {})' % (subname))
165 pass
166 last = subnames[-1]
167 self.output_cmd_line('self.%s(data, cdata)' % (last))
168 self.frag_start()
169 pass
170
171 def gen_node_template(self, name, node):
172 from xml.dom import Node
173 fw_q = [node]
174
175 def trackback(no):
176 while no != node and no.parentNode and not no.nextSibling:
177 no = no.parentNode
178 self.tag_stop(no)
179 pass
180 pass
181
182 first = True
183 while fw_q:
184 no = fw_q.pop()
185 if (not first) and no.nodeType == Node.ELEMENT_NODE and no.hasAttributes() and no.hasAttribute('ezid'):
186 name = no.getAttribute('ezid').split('.')[-1]
187 _check_reserved(name)
188 if not self.all_names.has_key(name) and not self.all_attrnames.has_key(name):
189 self.travel_q.append((name, no))
190 self.all_names[name] = None
191 else:
192 raise NameError, '%s is redefined' % (name,)
193 self.call_subtree(no)
194 trackback(no)
195 else:
196 self.tag_start(no)
197 if not no.hasChildNodes():
198 self.tag_stop(no)
199 trackback(no)
200 else:
201 children = [no.childNodes.item(i) for i in range(no.childNodes.length)]
202 children.reverse()
203 fw_q.extend(children)
204 pass
205 pass
206 first = False
207 pass
208 pass
209
210 def dig(self):
211 self.indent = self.indent + 4
212 pass
213
214 def back(self):
215 self.indent = self.indent - 4
216 pass
217
218 def output_cmd(self, msg):
219 self.ofo.write(' ' * self.indent)
220 self.ofo.write(msg)
221 pass
222
223 def output_cmd_line(self, msg):
224 self.ofo.write(' ' * self.indent)
225 self.ofo.write(msg)
226 self.ofo.write('\n')
227 pass
228
229 def output_raw(self, msg):
230 self.ofo.write(msg)
231 pass
232
233 def output(self, msg):
234 parts = msg.split('\\')
235 if len(parts) > 0:
236 msg = '\\\\'.join(parts)
237 pass
238 if len(msg) > 0 and msg[-1] == '\'':
239 msg = msg[:-1] + '\\\''
240 pass
241 parts = msg.split('\'\'\'')
242 if len(parts) > 1:
243 msg = '\\\'\\\'\\\''.join(parts)
244 pass
245 self.ofo.write(msg)
246 pass
247
248 def start(self, fn, ifo, ofo):
249 self.ofo = ofo
250 self.indent = 0
251
252 cname = clz_name(fn)
253 dom = parse(ifo)
254 self.travel_q = [('_root', dom)]
255 self.cname = cname
256 self.all_names = {}
257 self.all_attrnames = {}
258
259 self.travel_tree()
260 pass
261
262 def travel_tree(self):
263 self.template_head()
264
265 travel_q = self.travel_q
266 while travel_q:
267 name, node = travel_q[0]
268 self.subtree_start(name)
269 del travel_q[0]
270 if node:
271 self.gen_node_template(name, node)
272 pass
273 self.subtree_stop(name)
274 pass
275
276 self.template_tail()
277 pass
278 pass
279
280 if __name__ == '__main__':
281 import sys
282 import locale
283
284 if len(sys.argv) != 2:
285 sys.exit(1)
286 pass
287
288 class fakefile(object):
289 pass
290
291 fn = sys.argv[1]
292 fo = file(fn, 'r')
293 encoding = locale.getpreferredencoding()
294 stdout = fakefile()
295 oldwrite = sys.stdout.write
296 stdout.write = lambda x: oldwrite(x.encode(encoding))
297
298 if encoding != 'ascii':
299 print >> stdout, '# -*- coding: %s' % (encoding,)
300 pass
301
302 mex = mez_xml()
303 mex.start(fn, fo, stdout)
304 pass