from docutils import writers from docutils import nodes class LitreTranslator(nodes.GenericNodeVisitor): def __init__(self, document, config): nodes.GenericNodeVisitor.__init__(self,document) self._config = config def default_visit(self, node): pass # print '**visiting:', repr(node) def default_departure(self, node): pass # print '**departing:', repr(node) def visit_raw(self, node): if node.has_key('format'): key = node['format'].lower() if key == 'litre': # This is probably very evil ;-) #if node.has_key('source'): # node.file = node.attributes['source'] self._handle_code(node, node.astext()) raise nodes.SkipNode def visit_comment(self, node): code = node.astext() if code[0] == '@': self._handle_code(node, code[1:].strip()) def _handle_code(self, node, code): start_line = node.line or 0 start_line -= code.count('\n') + 2 # docutils bug workaround? try: self._execute(compile( start_line*'\n' + code, str(node.source), 'exec')) except: print '\n------- begin offending Python source -------' print code print '------- end offending Python source -------' raise def _execute(self, code): """Override this to set up local variable context for code before invoking it """ eval(code) class Writer(writers.Writer): translator = LitreTranslator _config = None def translate(self): visitor = self.translator(self.document, self._config) self.document.walkabout(visitor) self.output = visitor.astext()