Commits

Anonymous committed 6d80e45

``Sphinx.add_node()`` now takes optional visitor methods for the HTML,
LaTeX and text translators; this prevents having to manually patch
the classes.

  • Participants
  • Parent commits 0a71b9b

Comments (0)

Files changed (3)

 
 * The HTML builders have two additional attributes now that can be used
   to disable the anchor-link creation after headlines and definition
-  links.  EXPERIMENTAL
+  links.
+
+* ``Sphinx.add_node()`` now takes optional visitor methods for the HTML,
+  LaTeX and text translators; this prevents having to manually patch
+  the classes.
 
 * sphinx.doc.autodoc has a new event ``autodoc-process-signature`` that
   allows tuning function signature introspection.

doc/ext/appapi.rst

 
    Register an event called *name*.
 
-.. method:: Sphinx.add_node(node)
+.. method:: Sphinx.add_node(node, **kwds)
 
    Register a Docutils node class.  This is necessary for Docutils internals.
    It may also be used in the future to validate nodes in the parsed documents.
 
+   Node visitor functions for the Sphinx HTML, LaTeX and text writers can be
+   given as keyword arguments: the keyword must be one or more of ``'html'``,
+   ``'latex'``, ``'text'``, the value a 2-tuple of ``(visit, depart)`` methods.
+   ``depart`` can be ``None`` if the ``visit`` function raises
+   :exc:`docutils.nodes.SkipNode`.  Example::
+
+      class math(docutils.nodes.Element)
+   
+      def visit_math_html(self, node):
+          self.body.append(self.starttag(node, 'math'))
+      def depart_math_html(self, node):
+          self.body.append('</math>')
+   
+      app.add_node(math, html=(visit_math_html, depart_math_html))
+
+   Obviously, translators for which you don't specify visitor methods will choke
+   on the node when encountered in a document to translate.
+
+   .. versionchanged:: 0.5
+      Added the support for keyword arguments giving visit functions.
+
 .. method:: Sphinx.add_directive(name, cls, content, arguments, **options)
 
    Register a Docutils directive.  *name* must be the prospective directive

sphinx/application.py

             raise ExtensionError('Event %r already present' % name)
         self._events[name] = ''
 
-    def add_node(self, node):
+    def add_node(self, node, **kwds):
         nodes._add_node_class_names([node.__name__])
+        for key, val in kwds.iteritems():
+            try:
+                visit, depart = val
+            except ValueError:
+                raise ExtensionError('Value for key %r must be a (visit, depart) '
+                                     'function tuple' % key)
+            if key == 'html':
+                from sphinx.htmlwriter import HTMLTranslator as translator
+            elif key == 'latex':
+                from sphinx.latexwriter import LaTeXTranslator as translator
+            elif key == 'text':
+                from sphinx.textwriter import TextTranslator as translator
+            else:
+                # ignore invalid keys for compatibility
+                continue
+            setattr(translator, 'visit_'+node.__name__, visit)
+            if depart:
+                setattr(translator, 'depart_'+node.__name__, depart)
 
     def add_directive(self, name, func, content, arguments, **options):
         func.content = content