76 help="execute YSLT script YSLTSCRIPT") |
73 help="execute YSLT script YSLTSCRIPT") |
77 optParser.add_option("-Y", "--xml2yml", action="store_true", default=False, |
74 optParser.add_option("-Y", "--xml2yml", action="store_true", default=False, |
78 help="convert XML to normalized YML code") |
75 help="convert XML to normalized YML code") |
79 optParser.add_option("-V", "--version", action="callback", callback=printInfo, help="show version info and exit") |
76 optParser.add_option("-V", "--version", action="callback", callback=printInfo, help="show version info and exit") |
80 (options, args) = optParser.parse_args() |
77 (options, args) = optParser.parse_args() |
81 |
78 |
82 if options.old_syntax: |
79 if options.old_syntax: |
83 oldSyntax() |
80 oldSyntax() |
84 |
81 |
85 if options.trace: |
82 if options.trace: |
86 backend.enable_tracing = True |
83 backend.enable_tracing = True |
87 |
84 |
88 if options.emitlinenumbers: |
85 if options.emitlinenumbers: |
89 backend.emitlinenumbers = True |
86 backend.emitlinenumbers = True |
90 |
87 |
91 if options.includePathText: |
88 if options.includePathText: |
92 backend.includePath = options.includePathText.split(':') |
89 backend.includePath = options.includePathText.split(':') |
93 |
90 |
94 backend.encoding = options.encoding |
91 backend.encoding = options.encoding |
95 |
92 |
96 dirs = os.environ.get('YML_PATH', '.').split(':') |
93 dirs = os.environ.get('YML_PATH', '.').split(':') |
97 backend.includePath.extend(dirs) |
94 backend.includePath.extend(dirs) |
98 |
95 |
99 if options.xml2yml: |
96 if options.xml2yml: |
100 for directory in backend.includePath: |
97 for directory in backend.includePath: |
101 try: |
98 try: |
102 name = directory + "/xml2yml.ysl2" |
99 name = directory + "/xml2yml.ysl2" |
103 f = open(name, "r") |
100 f = open(name, "r") |
104 f.close() |
101 f.close() |
105 break |
102 break |
106 except: |
103 except: |
107 pass |
104 pass |
108 |
105 |
109 options.yslt = name |
106 options.yslt = name |
110 options.xml = True |
107 options.xml = True |
111 |
108 |
112 if (options.xslt and options.yslt) or (options.xslt and options.xpath) or (options.yslt and options.xpath): |
109 if (options.xslt and options.yslt) or (options.xslt and options.xpath) or (options.yslt and options.xpath): |
113 sys.stderr.write("Cannot combine --xpath, --xslt and --yslt params\n") |
110 sys.stderr.write("Cannot combine --xpath, --xslt and --yslt params\n") |
114 sys.exit(1) |
111 sys.exit(1) |
115 |
112 |
116 try: |
113 try: |
117 ymlC = ymlCStyle() |
114 ymlC = ymlCStyle() |
118 |
115 |
119 rtext = u"" |
116 rtext = "" |
120 |
117 |
121 if not options.emptyinput: |
118 if not options.emptyinput: |
122 files = fileinput.input(args, mode="rU", openhook=fileinput.hook_encoded(options.encoding)) |
119 files = fileinput.input(args, mode="rU", openhook=fileinput.hook_encoded(options.encoding)) |
123 |
120 |
124 if options.xml: |
121 if options.xml: |
125 rtext = "" |
122 rtext = "" |
126 for line in files: |
123 for line in files: |
127 rtext += line |
124 rtext += line |
128 else: |
125 else: |
130 if options.parseonly: |
127 if options.parseonly: |
131 print(result) |
128 print(result) |
132 sys.exit(0) |
129 sys.exit(0) |
133 else: |
130 else: |
134 rtext = backend.finish(result) |
131 rtext = backend.finish(result) |
135 |
132 |
136 if not rtext: |
133 if not rtext: |
137 rtext = u"<empty/>" |
134 rtext = "<empty/>" |
138 |
135 |
139 def ymldebug(context, text): |
136 def ymldebug(context, text): |
140 if options.trace: |
137 if options.trace: |
141 sys.stderr.write("Debug: " + codecs.encode(u(text), options.encoding) + "\n") |
138 sys.stderr.write("Debug: " + codecs.encode(u(text), options.encoding) + "\n") |
142 return "" |
139 return "" |
143 |
140 |
144 def ymlassert(context, value, msg): |
141 def ymlassert(context, value, msg): |
145 if options.trace: |
142 if options.trace: |
146 if not value: |
143 if not value: |
147 raise YMLAssert(msg) |
144 raise YMLAssert(msg) |
148 return "" |
145 return "" |
149 |
146 |
150 ymlns = etree.FunctionNamespace("http://fdik.org/yml") |
147 ymlns = etree.FunctionNamespace("http://fdik.org/yml") |
151 ymlns.prefix = "yml" |
148 ymlns.prefix = "yml" |
152 ymlns['debug'] = ymldebug |
149 ymlns['debug'] = ymldebug |
153 ymlns['assert'] = ymlassert |
150 ymlns['assert'] = ymlassert |
154 |
151 |
155 if options.xpath: |
152 if options.xpath: |
156 tree = etree.fromstring(rtext) |
153 tree = etree.fromstring(rtext) |
157 ltree = tree.xpath(codecs.decode(options.xpath, options.encoding)) |
154 ltree = tree.xpath(codecs.decode(options.xpath, options.encoding)) |
158 rtext = u"" |
155 rtext = "" |
159 try: |
156 try: |
160 for rtree in ltree: |
157 for rtree in ltree: |
161 rtext += etree.tostring(rtree, pretty_print=options.pretty, encoding=unicode) |
158 rtext += etree.tostring(rtree, pretty_print=options.pretty, encoding=unicode) |
162 except: |
159 except: |
163 rtext = ltree |
160 rtext = ltree |
164 |
161 |
165 elif options.yslt or options.xslt: |
162 elif options.yslt or options.xslt: |
166 params = {} |
163 params = {} |
167 |
164 |
168 if options.yslt: |
165 if options.yslt: |
169 backend.clearAll() |
166 backend.clearAll() |
170 yscript = fileinput.input(options.yslt, mode="rU", openhook=fileinput.hook_encoded(options.encoding)) |
167 yscript = fileinput.input(options.yslt, mode="rU", openhook=fileinput.hook_encoded(options.encoding)) |
171 yresult = parse(ymlC, yscript, True, comment) |
168 yresult = parse(ymlC, yscript, True, comment) |
172 ytext = backend.finish(yresult) |
169 ytext = backend.finish(yresult) |
173 else: |
170 else: |
174 yscript = fileinput.input(options.xslt, mode="rU") |
171 yscript = fileinput.input(options.xslt, mode="rU") |
175 ytext = "" |
172 ytext = "" |
176 for line in yscript: |
173 for line in yscript: |
177 ytext += line |
174 ytext += line |
178 |
175 |
179 doc = etree.fromstring(rtext) |
176 doc = etree.fromstring(rtext) |
180 |
177 |
181 xsltree = etree.XML(ytext, base_url=os.path.abspath(yscript.filename())) |
178 xsltree = etree.XML(ytext, base_url=os.path.abspath(yscript.filename())) |
182 transform = etree.XSLT(xsltree) |
179 transform = etree.XSLT(xsltree) |
183 |
180 |
184 if options.params: |
181 if options.params: |
185 params = eval(options.params) |
182 params = eval(options.params) |
186 for key, value in params.iteritems(): |
183 for key, value in params.iteritems(): |
187 if type(value) != unicode: |
184 if type(value) is not str: |
188 params[key] = u(value) |
185 params[key] = u(value) |
189 if options.stringparams: |
186 if options.stringparams: |
190 for key, value in eval(options.stringparams).iteritems(): |
187 for key, value in eval(options.stringparams).iteritems(): |
191 params[key] = u"'" + u(value) + u"'" |
188 params[key] = "'" + u(value) + "'" |
192 |
189 |
193 rresult = transform(doc, **params) |
190 rresult = transform(doc, **params) |
194 # lxml is somewhat buggy |
191 # lxml is somewhat buggy |
195 try: |
192 try: |
196 rtext = u(rresult) |
193 rtext = u(rresult) |
197 except: |
194 except: |
198 rtext = etree.tostring(rresult, encoding=unicode) |
195 rtext = etree.tostring(rresult, encoding=unicode) |
199 if not rtext: |
196 if not rtext: |
200 rtext = codecs.decode(str(rresult), "utf-8") |
197 rtext = codecs.decode(str(rresult), "utf-8") |
201 |
198 |
202 if options.normalization != "none": |
199 if options.normalization != "none": |
203 rtext = unicodedata.normalize(options.normalization, rtext) |
200 rtext = unicodedata.normalize(options.normalization, rtext) |
204 |
201 |
205 if options.pretty: |
202 if options.pretty: |
206 plaintext = etree.tostring(etree.fromstring(rtext), pretty_print=True, xml_declaration=True, encoding=options.encoding) |
203 plaintext = etree.tostring(etree.fromstring(rtext), pretty_print=True, xml_declaration=True, encoding=options.encoding) |
207 else: |
204 else: |
208 if isinstance(rtext, unicode): |
205 if isinstance(rtext, str): |
209 plaintext = codecs.encode(rtext, options.encoding) |
206 plaintext = codecs.encode(rtext, options.encoding) |
210 else: |
207 else: |
211 plaintext = str(rtext) |
208 plaintext = rtext |
212 |
209 |
213 try: |
210 try: |
214 if plaintext[-1] == "\n": |
211 if plaintext[-1] == "\n": |
215 plaintext = plaintext[:-1] |
212 plaintext = plaintext[:-1] |
216 except: pass |
213 except: pass |
217 |
214 |
218 if options.outputFile and options.outputFile != "-": |
215 if options.outputFile and options.outputFile != "-": |
219 outfile = open(options.outputFile, "w") |
216 outfile = open(options.outputFile, "wb") |
220 outfile.write(plaintext) |
217 outfile.write(plaintext) |
221 outfile.close() |
218 outfile.close() |
222 else: |
219 else: |
223 print(plaintext) |
220 sys.stdout.buffer.write(plaintext) |
224 |
221 if not options.pretty: |
|
222 print() |
|
223 |
225 except KeyboardInterrupt: |
224 except KeyboardInterrupt: |
226 w("\n") |
225 w("\n") |
227 sys.exit(1) |
226 sys.exit(1) |
228 except YMLAssert as msg: |
227 except YMLAssert as msg: |
229 w(u"YML Assertion failed: " + u(msg) + u"\n") |
228 w("YML Assertion failed: " + u(msg) + "\n") |
230 sys.exit(2) |
229 sys.exit(2) |
231 except KeyError as msg: |
230 except KeyError as msg: |
232 w(u"not found: " + u(msg) + u"\n") |
231 w("not found: " + u(msg) + "\n") |
233 sys.exit(4) |
232 sys.exit(4) |
234 except LookupError as msg: |
233 except LookupError as msg: |
235 w(u"not found: " + u(msg) + u"\n") |
234 w("not found: " + u(msg) + "\n") |
236 sys.exit(4) |
235 sys.exit(4) |
237 except etree.XMLSyntaxError as e: |
236 except etree.XMLSyntaxError as e: |
238 log = e.error_log.filter_from_level(etree.ErrorLevels.FATAL) |
237 log = e.error_log.filter_from_level(etree.ErrorLevels.FATAL) |
239 for entry in log: |
238 for entry in log: |
240 w(u"XML error: " + u(entry.message) + u"\n") |
239 w("XML error: " + u(entry.message) + "\n") |
241 sys.exit(5) |
240 sys.exit(5) |
242 except Exception as msg: |
241 except Exception as msg: |
243 w(msg) |
242 w(msg) |
244 sys.exit(5) |
243 sys.exit(5) |
245 |
244 |