diff --git a/data/homeostasis_25nov.xml b/data/homeostasis_25nov.xml index 78569881afb5b193104182522b69a1a7b0b1c06c..3472cbf4e064807e3ba49b28a9c27e7257e53d3a 100644 --- a/data/homeostasis_25nov.xml +++ b/data/homeostasis_25nov.xml @@ -104,7 +104,7 @@ <keyword action="" lang="esp"> seis </keyword> <keyword action="#end" lang="eng"> open network </keyword> </sequence> - <sequence ordre="variable" repetition="oui" action="constellation/all words become written in the space constellation when they are pronounced/ the repetition of the same a word amplifies the word/" lang="eng"> + <sequence ordre="variable" repetition="oui" action="constellation" lang="eng"> <keyword action="constellation" lang="eng"> clouds </keyword> <keyword action="constellation" lang="eng"> beautiful </keyword> <keyword action="constellation" lang="eng"> data </keyword> @@ -153,7 +153,7 @@ <keyword action="#end"> try with functional regulation </keyword> <keyword action="#end" lang="eng"> give me my data </keyword> </sequence> - <sequence ordre="variable" repetition="oui" action="constellation/all words become written in the space constellation when they are pronounced/ the repetition of the same a word amplifies the word/" lang="eng"> + <sequence ordre="variable" repetition="oui" action="constellation" lang="eng"> <keyword action="constellation" lang="eng"> possible </keyword> <keyword action="amplification1" lang="eng"> function </keyword> <keyword action="constellation" lang="eng"> erase the </keyword> @@ -392,7 +392,7 @@ <keyword action="#end"> and to want </keyword> <keyword action="#end" lang="eng"> give me my data </keyword> </sequence> - <sequence ordre="variable" repetition="oui" lang="esp" action="constellation/all words become written in the space constellation when they are pronounced/ the repetition of the same a word amplifies the word/interlined words in groups of 12 or divided by silence"> + <sequence ordre="variable" repetition="oui" lang="esp" action="constellation"> como decir lo que la nada entiende lo que el miedo esconde @@ -411,7 +411,7 @@ <keyword action="#end"> y querer </keyword> <keyword action="#end" lang="eng"> give me my data </keyword> </sequence> - <sequence ordre="variable" repetition="oui" lang="eng" action="constellation/all words become written in the space constellation when they are pronounced/ the repetition of the same a word amplifies the word/interlined words in groups of 12 or divided by silence"> + <sequence ordre="variable" repetition="oui" lang="eng" action="constellation"> try with upper motoneuron functions functions diff --git a/validate.py b/validate.py index d74f938a48a56520f067625ef5d2ea1da2362345..94afbcb79de1828eec2a902908ecf74629f908aa 100644 --- a/validate.py +++ b/validate.py @@ -3,6 +3,7 @@ import re seen_section_ids = {} seen_actions = {} +warnings = [] class VerifyException(Exception): def __init__(self, message, node): @@ -17,10 +18,10 @@ def is_int(text): return re.match(r'^\d+$', text) def has_blank(text): - return re.match(r'\s', text) + return re.search(r'\s', text) def verify_keyword(node): - global seen_actions + global seen_actions, warnings for key in node.attrib: if key not in ['action', 'lang']: raise VerifyException('attribute "%s" not allowed in <%s>' % (key, node.tag), node) @@ -28,10 +29,10 @@ def verify_keyword(node): if key not in node.attrib: raise VerifyException('node <%s> must contain attribute "%s"' % (node.tag, key), node) if node.get('action').strip() == '': - print 'WARNING: empty action for %s' % ET.tostring(node).strip() + warnings.append('WARNING: empty action for %s' % ET.tostring(node).strip()) #raise VerifyException('empty action', node) if has_blank(node.get('action')): - raise VerifyException('spaces not allowed in action "%s"', node) + raise VerifyException('spaces not allowed in action "%s"' % node.get('action'), node) seen_actions[node.get('action')] = True if node.get('lang') not in [None, 'eng', 'esp']: raise VerifyException('unsupported lang "%s"' % node.get('lang'), node) @@ -44,6 +45,8 @@ def verify_sequence(node): raise VerifyException('attribute "%s" not allowed in <%s>' % (key, node.tag), node) if node.get('lang') not in [None, 'eng', 'esp']: raise VerifyException('unsupported lang "%s"' % node.get('lang'), node) + if has_blank(node.get('action')): + raise VerifyException('spaces not allowed in action "%s"' % node.get('action'), node) for child in node: if child.tag == 'keyword': verify_keyword(child) @@ -58,6 +61,8 @@ def verify_section(node): for key in ['id']: if key not in node.attrib: raise VerifyException('node <%s> must contain attribute "%s"' % (node.tag, key), node) + if has_blank(node.get('action')): + raise VerifyException('spaces not allowed in action "%s"' % node.get('action'), node) if not is_int(node.get('id')): raise VerifyException('only integers allowed for section id "%s"' % node.get('id')) if node.get('id') in seen_section_ids: @@ -104,15 +109,20 @@ def verify_root(node): raise VerifyException('no text allowed directly after <%s>' % (node.tag), node) def validate_xml(filename): - global seen_section_ids, seen_actions + global seen_section_ids, seen_actions, warnings seen_section_ids = {} seen_actions = {} + warnings = [] try: root = ET.parse(filename).getroot() verify_root(root) except Exception as e: - return (False, str(e)) - return (True, 'successfuly validated "%s"\nfound %d sections, %d types of action' % (filename, len(seen_section_ids), len(seen_actions))) + if len(warnings) > 0: + warnings.append('--------------') + return (False, '\n'.join(warnings) + '\n' + str(e)) + if len(warnings) > 0: + warnings.append('--------------') + return (True, '\n'.join(warnings) + '\nsuccessfuly validated "%s"\nfound %d sections, %d types of action' % (filename, len(seen_section_ids), len(seen_actions))) if __name__ == '__main__': import sys diff --git a/xmledit.py b/xmledit.py index b35b99682700e7cfde238c15fc44ee977337ef15..3d6b73cd4947760b412c6a028ad1c9b7de257c51 100644 --- a/xmledit.py +++ b/xmledit.py @@ -17,12 +17,12 @@ class SourceView(Gtk.Window): def __init__(self, filename): super(SourceView, self).__init__() - self.filename = filename + self.filename = None self.connect("destroy", self.quit) - self.set_default_size(800,600) + self.set_default_size(1024, 768) self.set_border_width(10) - self.set_title('SourceView') + self.set_title('Homeostasis editor') tabs = Gtk.Notebook() self.tabs = tabs @@ -44,9 +44,13 @@ class SourceView(Gtk.Window): #vbox.pack_start(self.command, False, True, 5) hbox = Gtk.HBox() - revert_button = Gtk.Button('Revert') - revert_button.connect('clicked', self.load) - hbox.pack_start(revert_button, False, False, 5) + new_button = Gtk.Button('New') + new_button.connect('clicked', self.new) + hbox.pack_start(new_button, False, False, 5) + + load_button = Gtk.Button('Load') + load_button.connect('clicked', lambda *args: self.show_filechooser("load")) + hbox.pack_start(load_button, False, False, 5) validate_button = Gtk.Button('Validate') validate_button.connect('clicked', self.validate) @@ -60,37 +64,95 @@ class SourceView(Gtk.Window): save_button.connect('clicked', self.save) hbox.pack_start(save_button, False, False, 5) + saveas_button = Gtk.Button('Save as') + saveas_button.connect('clicked', lambda *args: self.show_filechooser("save")) + hbox.pack_start(saveas_button, False, False, 5) + vbox.pack_start(tabs, True, True, 5) vbox.pack_start(hbox, False, True, 5) - tabs.append_page(self.scrolled, Gtk.Label(filename)) + tabs.append_page(self.scrolled, Gtk.Label('xml filename')) tabs.append_page(self.command, Gtk.Label('Compilation result')) tabs.set_show_border(False) + self.set_filename(filename) + self.load() + self.add(vbox) self.show_all() - self.load() + self.command.add_text('READY') + + def new(self, *args): + self.source_buffer.set_text("""<homeostasis version="25-11-2014"> + <liste_section sequences="1" ordre="variable" repetition="oui" action="exclusive"> + <section id="2" action="example1"> + <sequence ordre="strict" repetition="non" action="" lang="esp"> + <keyword action="example2" lang="eng"> hello </keyword> + </sequence> + </section> + </liste_section> +</homeostasis>""") + self.set_filename('unsaved') + + def set_filename(self, filename): + self.filename = filename + self.tabs.set_tab_label(self.scrolled, Gtk.Label(os.path.basename(filename))) - def load(self, *args): - self.source_buffer.set_text(open(self.filename).read()) + def show_filechooser(self, dialog_type="load"): + if dialog_type == "load": + dialog = Gtk.FileChooserDialog("Please choose a file to load", self, Gtk.FileChooserAction.OPEN, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.OK)) + else: + dialog = Gtk.FileChooserDialog("Please set a file to save", self, Gtk.FileChooserAction.SAVE, (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_SAVE, Gtk.ResponseType.OK)) + filter_text = Gtk.FileFilter() + filter_text.set_name("XML files") + filter_text.add_mime_type("text/xml") + dialog.add_filter(filter_text) + dialog.set_current_folder('%s/data' % (os.path.dirname(__file__) or '.')) + + response = dialog.run() + if response == -5: + self.filename = dialog.get_filename() + print self.filename + self.set_filename(self.filename) + dialog.destroy() + if dialog_type == "load": + return self.load() + else: + return self.save() + dialog.destroy() - def save(self, *args): - self.command.clear() + def load(self, *args): try: - with open('data/edited.xml', 'w') as fp: - bounds = self.source_buffer.get_bounds() - fp.write(self.source_buffer.get_text(bounds[0], bounds[1], True)) + with open(self.filename) as fp: + self.source_buffer.set_text(fp.read()) except Exception as e: print e - self.command.add_text('FAILED to save as data/edited.xml') + self.command.add_text('FAILED to load "%s"' % self.filename) + return False + return True + + def save(self, *args): + if self.filename == 'unsaved': + return self.show_filechooser("save") + else: + self.command.clear() + try: + with open(self.filename, 'w') as fp: + bounds = self.source_buffer.get_bounds() + fp.write(self.source_buffer.get_text(bounds[0], bounds[1], True)) + except Exception as e: + print e + self.command.add_text('FAILED to save as "%s"' % self.filename) + return False + return True def validate(self, *args): self.command.clear() self.save() self.command.add_text('VALIDATE...') self.tabs.set_current_page(1) - result, message = validate.validate_xml('data/edited.xml') + result, message = validate.validate_xml(self.filename) self.command.add_text(message) if result: self.command.add_text('SUCCESS') @@ -101,10 +163,10 @@ class SourceView(Gtk.Window): def compile(self, *args): self.command.clear() self.tabs.set_current_page(1) - self.save() - self.validate() - self.command.add_text('COMPILE...') - self.command.run('./tools/compile.ben.sh data/edited.xml tools/model') + if self.save(): + if self.validate(): + self.command.add_text('COMPILE...') + self.command.run('./tools/compile.ben.sh "%s" tools/model' % self.filename) def quit(self, window): Gtk.main_quit()