2012-11-15 13 views
8

Mam proste rozszerzenie Sphinx następująco:Rozszerzenie procesora dokumentacji Sphinx działa inaczej dla wyjścia HTML i LaTeX?

from docutils import nodes 
from docutils.parsers.rst import directives 
from sphinx.util.compat import Directive 

class testnode(nodes.Element): 
    def __init__(self, *args, **kwargs): 
     super(testnode, self).__init__(*args, **kwargs) 
     self['foo'] = '?' 

def visit_testnode_latex(self, node): 
    self.body.append('Test: %s' % node['foo']) 

def depart_testnode_latex(self, node): 
    pass 

def visit_testnode_html(self, node): 
    self.body.append('<p>Test: %s</p>' % node['foo']) 

def depart_testnode_html(self, node): 
    pass 

class TestDirective(Directive): 
    has_content = False 
    required_arguments = 0 
    optional_arguments = 0 
    final_argument_whitespace = False 
    option_spec = { 
     'foo': directives.unchanged, 
    } 

    def run(self): 
     node = testnode() 
     node['foo'] = self.options.get('foo') 
     return [node] 

def setup(app): 
    app.add_directive("testdirective", TestDirective) 
    app.add_node(testnode, 
       html=(visit_testnode_html, 
         depart_testnode_html), 
       latex=(visit_testnode_latex, 
         depart_testnode_latex)) 

otrzymać dokument zawierający wyjście

.. testdirective:: 
    :foo: bar 

HTML zawiera »Test: bar«ale wyjście LaTeX zawiera»Test:?« (The domyślna wartość). Sprawdziłem, czy node['foo'] ma poprawną wartość po przypisaniu w TestDirective.run(), ale nie wydaje się, aby się utrzymywał, dopóki nie uruchomi się program piszący LaTeX.

Co robię źle?

Odpowiedz

3

Po przejrzeniu skryptu LaTeX dla Sphinx znalazłem tutaj problem. Jest to sposób, w jaki ustawiasz wartość domyślną dla słowa kluczowego 'foo' w inicjalizatorze testnode.

Jest pewien punkt w programie piszącym LaTeX, że wykonuje on głębię całego drzewa dokumentu, aby wstawić go do innego drzewa. Deepcopy na węźle Element inicjuje nowy węzeł tej samej klasy i przekazuje wszystkie atrybuty i zawartość oryginalnego węzła za pośrednictwem konstruktora. Tak więc po skopiowaniu twojego testnode Twój konstruktor zastępuje oryginalny atrybut "foo", który jest przekazywany do konstruktora. Zamiast napisać go w ten sposób i to powinno działać:

class testnode(nodes.Element): 
    def __init__(self, *args, **kwargs): 
     super(testnode, self).__init__(*args, **kwargs) 
     if 'foo' not in self: 
      self['foo'] = '?' 

Zapobiegnie to domyślne z nadrzędnymi żadnego wyraźnego wartość atrybutu, który został przekazany do konstruktora. Istnieje kilka innych możliwości.

Powiązane problemy