1from docutils import writers 2from docutils import nodes 3 4class LitreTranslator(nodes.GenericNodeVisitor): 5 6 def __init__(self, document, config): 7 nodes.GenericNodeVisitor.__init__(self,document) 8 self._config = config 9 10 def default_visit(self, node): 11 pass 12 # print '**visiting:', repr(node) 13 14 def default_departure(self, node): 15 pass 16 # print '**departing:', repr(node) 17 18 def visit_raw(self, node): 19 if node.has_key('format'): 20 key = node['format'].lower() 21 if key == 'litre': 22 # This is probably very evil ;-) 23 #if node.has_key('source'): 24 # node.file = node.attributes['source'] 25 26 self._handle_code(node, node.astext()) 27 28 raise nodes.SkipNode 29 30 def visit_comment(self, node): 31 code = node.astext() 32 if code[0] == '@': 33 self._handle_code(node, code[1:].strip()) 34 35 def _handle_code(self, node, code): 36 start_line = node.line or 0 37 start_line -= code.count('\n') + 2 # docutils bug workaround? 38 try: 39 self._execute(compile( start_line*'\n' + code, str(node.source), 'exec')) 40 except: 41 print '\n------- begin offending Python source -------' 42 print code 43 print '------- end offending Python source -------' 44 raise 45 46 def _execute(self, code): 47 """Override this to set up local variable context for code before 48 invoking it 49 """ 50 eval(code) 51 52class Writer(writers.Writer): 53 translator = LitreTranslator 54 _config = None 55 56 def translate(self): 57 visitor = self.translator(self.document, self._config) 58 self.document.walkabout(visitor) 59 self.output = visitor.astext() 60 61 62