[Checkins] SVN: Sandbox/ulif/grok-reference-with-rest2/doc/grokref/ Refactored grokref2html. Moved translators.

Uli Fouquet uli at gnufix.de
Sun Jan 6 10:25:35 EST 2008


Log message for revision 82688:
  Refactored grokref2html. Moved translators.

Changed:
  A   Sandbox/ulif/grok-reference-with-rest2/doc/grokref/extensions/translators.py
  U   Sandbox/ulif/grok-reference-with-rest2/doc/grokref/grokref2html.py
  D   Sandbox/ulif/grok-reference-with-rest2/doc/grokref/translators.py

-=-
Added: Sandbox/ulif/grok-reference-with-rest2/doc/grokref/extensions/translators.py
===================================================================
--- Sandbox/ulif/grok-reference-with-rest2/doc/grokref/extensions/translators.py	                        (rev 0)
+++ Sandbox/ulif/grok-reference-with-rest2/doc/grokref/extensions/translators.py	2008-01-06 15:25:35 UTC (rev 82688)
@@ -0,0 +1,189 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Translators, that can handle extensions in HTML and LaTeX.
+"""
+from docutils import nodes
+from docutils.writers.html4css1 import HTMLTranslator as BaseTranslator
+
+class HTMLTranslator(object):
+    """A custom HTML translator.
+    """
+    def visit_desc(self, node):
+        self.body.append(self.starttag(node, 'dl', CLASS=node['desctype']))
+
+    def depart_desc(self, node):
+        self.body.append('</dl>\n\n')
+
+    def visit_desc_signature(self, node):
+        # the id is set automatically
+        self.body.append(self.starttag(node, 'dt'))
+        # anchor for per-desc interactive data
+        if (node.parent['desctype'] != 'describe' and node['ids']
+            and node['first']):
+            self.body.append('<!--#%s#-->' % node['ids'][0])
+        if node.parent['desctype'] in ('class', 'exception'):
+            self.body.append('%s ' % node.parent['desctype'])
+    def depart_desc_signature(self, node):
+        self.body.append('</dt>\n')
+
+    def visit_desc_classname(self, node):
+        print "NODE: ", dir(node)
+        self.body.append(self.starttag(node, 'tt', '', CLASS='descclassname'))
+    def depart_desc_classname(self, node):
+        self.body.append('</tt>')
+
+    def visit_desc_name(self, node):
+        self.body.append(self.starttag(node, 'tt', '', CLASS='descname'))
+    def depart_desc_name(self, node):
+        self.body.append('</tt>')
+
+    def visit_desc_parameterlist(self, node):
+        self.body.append('<big>(</big>')
+        self.first_param = 1
+    def depart_desc_parameterlist(self, node):
+        self.body.append('<big>)</big>')
+
+    def visit_desc_parameter(self, node):
+        if not self.first_param:
+            self.body.append(', ')
+        else:
+            self.first_param = 0
+        if not node.hasattr('noemph'):
+            self.body.append('<em>')
+    def depart_desc_parameter(self, node):
+        if not node.hasattr('noemph'):
+            self.body.append('</em>')
+    def visit_desc_optional(self, node):
+        self.body.append('<span class="optional">[</span>')
+    def depart_desc_optional(self, node):
+        self.body.append('<span class="optional">]</span>')
+
+    def visit_desc_content(self, node):
+        self.body.append(self.starttag(node, 'dd', ''))
+    def depart_desc_content(self, node):
+        self.body.append('</dd>')
+
+    def visit_refcount(self, node):
+        self.body.append(self.starttag(node, 'em', '', CLASS='refcount'))
+    def depart_refcount(self, node):
+        self.body.append('</em>')
+
+    def visit_versionmodified(self, node):
+        self.body.append(self.starttag(node, 'p'))
+        text = version_text[node['type']] % node['version']
+        if len(node):
+            text += ': '
+        else:
+            text += '.'
+        self.body.append('<span class="versionmodified">%s</span>' % text)
+    def depart_versionmodified(self, node):
+        self.body.append('</p>\n')
+
+    # overwritten -- we don't want source comments to show up in the HTML
+    def visit_comment(self, node):
+        raise nodes.SkipNode
+
+
+        # overwritten
+    def visit_admonition(self, node, name=''):
+        self.body.append(self.start_tag_with_title(
+            node, 'div', CLASS=('admonition ' + name)))
+        if name and name != 'seealso':
+            node.insert(0, nodes.title(name, self.language.labels[name]))
+        self.set_first_last(node)
+
+    def visit_seealso(self, node):
+        self.visit_admonition(node, 'seealso')
+    def depart_seealso(self, node):
+        self.depart_admonition(node)
+
+    # overwritten
+    def visit_title(self, node, move_ids=1):
+        # if we have a section we do our own processing in order
+        # to have ids in the hN-tags and not in additional a-tags
+        if isinstance(node.parent, nodes.section):
+            h_level = self.section_level + self.initial_header_level - 1
+            if node.parent.get('ids'):
+                attrs = {'ids': node.parent['ids']}
+            else:
+                attrs = {}
+            self.body.append(self.starttag(node, 'h%d' % h_level, '', **attrs))
+            self.context.append('</h%d>\n' % h_level)
+        else:
+            BaseTranslator.visit_title(self, node, move_ids)
+
+    # overwritten
+    def visit_literal_block(self, node):
+        #from .highlighting import highlight_block
+        #self.body.append(highlight_block(node.rawsource, self.highlightlang))
+        raise nodes.SkipNode
+
+    def visit_productionlist(self, node):
+        self.body.append(self.starttag(node, 'pre'))
+        names = []
+        for production in node:
+            names.append(production['tokenname'])
+        maxlen = max(len(name) for name in names)
+        for production in node:
+            if production['tokenname']:
+                self.body.append(self.starttag(production, 'strong', ''))
+                self.body.append(production['tokenname'].ljust(maxlen) +
+                                 '</strong> ::= ')
+                lastname = production['tokenname']
+            else:
+                self.body.append('%s     ' % (' '*len(lastname)))
+            production.walkabout(self)
+            self.body.append('\n')
+        self.body.append('</pre>\n')
+        raise nodes.SkipNode
+    def depart_productionlist(self, node):
+        pass
+
+    def visit_production(self, node):
+        pass
+    def depart_production(self, node):
+        pass
+
+    def visit_centered(self, node):
+        self.body.append(self.starttag(node, 'center') + '<strong>')
+    def depart_centered(self, node):
+        self.body.append('</strong></center>')
+
+    def visit_compact_paragraph(self, node):
+        pass
+    def depart_compact_paragraph(self, node):
+        pass
+
+    def visit_highlightlang(self, node):
+        self.highlightlang = node['lang']
+    def depart_highlightlang(self, node):
+        pass
+
+    def visit_toctree(self, node):
+        # this only happens when formatting a toc from env.tocs -- in this
+        # case we don't want to include the subtree
+        raise nodes.SkipNode
+
+    def visit_index(self, node):
+        raise nodes.SkipNode
+
+    #def unknown_visit(self, node):
+    #    print "UNKNOWN: ", node
+    #def unknown_departure(self, node):
+    #    print "UNKNOWN DEP: ", node
+
+    def visit_pending_xref(self, node):
+        #self.parent.append(nodes.literal(node['reftarget'], node['reftarget']))
+        raise nodes.SkipNode
+

Modified: Sandbox/ulif/grok-reference-with-rest2/doc/grokref/grokref2html.py
===================================================================
--- Sandbox/ulif/grok-reference-with-rest2/doc/grokref/grokref2html.py	2008-01-06 11:49:30 UTC (rev 82687)
+++ Sandbox/ulif/grok-reference-with-rest2/doc/grokref/grokref2html.py	2008-01-06 15:25:35 UTC (rev 82688)
@@ -13,26 +13,96 @@
 ##############################################################################
 """Create the grok reference in various output formats."""
 
-import os
-import sys
-import codecs
+import time
 
-import docutils.core
-#from docutils import nodes
-from docutils.writers.html4css1 import Writer
+from docutils import nodes
+from docutils.core import publish_cmdline, default_description
+from docutils.readers.standalone import Reader
+from docutils.transforms import Transform
+from docutils.transforms.universal import FilterMessages
+from docutils.parsers.rst import Parser
 
-from grokref.translators import HTMLTranslator
-from grokref.extensions import addnodes, roles, directives
+from docutils.writers.s5_html import Writer as S5Writer
+from docutils.writers.s5_html import S5HTMLTranslator as S5BaseTranslator
 
-#from zope.app.renderer.rest import ZopeTranslator
+from docutils.writers.latex2e import Writer as LaTeX2eWriter
 
-class ReStructuredTextToHTMLRenderer:
-    """Convert from Restructured Text to HTML."""
+from extensions import directives, roles
+from extensions.translators import HTMLTranslator
 
-    def __init__(self, content):
-        self.content = content
 
-    def render(self):
+class AdditionalSubstitutions(Transform):
+    default_priority = 210
+    def apply(self):
+        config = self.document.settings.reference_settings
+        for ref in self.document.traverse(nodes.substitution_reference):
+            refname = ref['refname']
+            text = config.get(refname, None)
+            ref.replace_self(nodes.Text(text, text))
+        return
+
+class ReferenceReader(Reader):
+    def get_transforms(self):
+        tf = Reader.get_transforms(self)
+        return tf + [AdditionalSubstitutions, FilterMessages]
+
+
+class ReferenceParser(Parser):
+    pass
+
+class ReferenceTranslatorS5(S5BaseTranslator, HTMLTranslator):
+    def __init__(self, *args, **kwds):
+        S5BaseTranslator.__init__(self, *args, **kwds)
+        self.highlightlang = 'python'
+
+    def unknown_visit(self, node):
+        print "UNKNOWN: ", node
+    def unknown_departure(self, node):
+        pass
+
+class ReferenceS5Writer(S5Writer):
+    def __init__(self, *args, **kw):
+        S5Writer.__init__(self)
+        self.translator_class = ReferenceTranslatorS5
+
+
+class ReferenceLaTeX2eWriter(LaTeX2eWriter):
+    pass
+
+
+class ReferenceProducer(object):
+    """
+    """
+
+    settings = {
+        'filename': None,
+        'today': '01/01/1970',
+        'version': 'None',
+        'release': 'unknown'
+        }
+
+    description = ('Generates reference documents from standalone '
+                   'reStructuredText sources.  ' + default_description)        
+
+    def __init__(self, filename=None):
+        self.reader = ReferenceReader()
+        self.parser = ReferenceParser()
+        self.writer = ReferenceS5Writer()
+        # Values from the `settings` directory can be used as
+        # substituted values in documents.  For example it is possible
+        # to use |foo| and this term will be substituted by a value
+        # defined in self.settings, called `foo`.  If such a key does
+        # not exist, a warning will be generated.  This requires a
+        # reader of type 'ReferenceReader'.
+        self.settings = {
+            'filename': filename,
+            'today': time.strftime('%B %d, %Y'),
+            'version': 'foo',
+            'release': 'bar'
+            }
+
+    def publish(self):
+        """Generate the reference."""
         settings_overrides = {
             'halt_level': 6,
             'input_encoding': 'utf8',
@@ -40,59 +110,19 @@
             'initial_header_level': 2,
             # don't try to include the stylesheet (docutils gets hiccups)
             'stylesheet_path': '',
+            'reference_settings' : self.settings,
         }
-
-        #docutils.nodes._add_node_class_names('desc')
-        writer = Writer()
-        #print docutils.nodes
-        #writer.translator_class = ZopeTranslator
-        writer.translator_class = HTMLTranslator
-        html = docutils.core.publish_string(
-                        self.content,
-                        writer=writer,
-                        settings_overrides=settings_overrides,)
-        html = codecs.decode(html, 'utf_8')
-        return html
-
-
-class ReSTFile(object):
-    source_text = None
-    file_path = None
-
-    def __init__(self, filename=None):
-        self.source_text = codecs.open(filename, "r", 'utf-8').read()
-        self.file_path = filename
-
-    def getHTML(self):
-        return ReStructuredTextToHTMLRenderer(self.source_text).render()
+        publish_cmdline(
+            reader=self.reader,
+            writer=self.writer,
+            parser=self.parser,
+            description=self.description,
+            settings_overrides=settings_overrides
+            )
         
 
-def getRestFiles(filepath):
-    if os.path.isdir(filepath):
-        return [os.path.join(filepath, filename)
-                for filename in os.listdir(filepath)
-                if filename.endswith('.rst')]
-    return [filepath]
+def main():
+    reference = ReferenceProducer().publish()
 
-def main(argv=None):
-    if argv is None:
-        argv = sys.argv[1:]
-    
-    if not len(argv):
-        print "Usage: %s REFDIR|FILE" % (sys.argv[0])
-        sys.exit(1)
-
-    if not os.path.isdir(argv[0]) and not os.path.isfile(argv[0]):
-        print "%s: No such file or directory" % (argv[0])
-        sys.exit(1)
-
-    rest_files = getRestFiles(argv[0])
-    print "files: ", rest_files
-
-    print "Content: "
-    for filename in rest_files:
-        print ReSTFile(filename).getHTML()
-
-    
 if __name__ == '__main__':
     main()

Deleted: Sandbox/ulif/grok-reference-with-rest2/doc/grokref/translators.py
===================================================================
--- Sandbox/ulif/grok-reference-with-rest2/doc/grokref/translators.py	2008-01-06 11:49:30 UTC (rev 82687)
+++ Sandbox/ulif/grok-reference-with-rest2/doc/grokref/translators.py	2008-01-06 15:25:35 UTC (rev 82688)
@@ -1,193 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2008 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Translators, that can handle extensions in HTML and LaTeX.
-"""
-from docutils import nodes
-from docutils.writers.html4css1 import HTMLTranslator as BaseTranslator
-
-class HTMLTranslator(BaseTranslator):
-    """A custom HTML translator.
-    """
-    def __init__(self, *args, **kwds):
-        BaseTranslator.__init__(self, *args, **kwds)
-        self.highlightlang = 'python'
-
-    def visit_desc(self, node):
-        self.body.append(self.starttag(node, 'dl', CLASS=node['desctype']))
-
-    def depart_desc(self, node):
-        self.body.append('</dl>\n\n')
-
-    def visit_desc_signature(self, node):
-        # the id is set automatically
-        self.body.append(self.starttag(node, 'dt'))
-        # anchor for per-desc interactive data
-        if (node.parent['desctype'] != 'describe' and node['ids']
-            and node['first']):
-            self.body.append('<!--#%s#-->' % node['ids'][0])
-        if node.parent['desctype'] in ('class', 'exception'):
-            self.body.append('%s ' % node.parent['desctype'])
-    def depart_desc_signature(self, node):
-        self.body.append('</dt>\n')
-
-    def visit_desc_classname(self, node):
-        print "NODE: ", dir(node)
-        self.body.append(self.starttag(node, 'tt', '', CLASS='descclassname'))
-    def depart_desc_classname(self, node):
-        self.body.append('</tt>')
-
-    def visit_desc_name(self, node):
-        self.body.append(self.starttag(node, 'tt', '', CLASS='descname'))
-    def depart_desc_name(self, node):
-        self.body.append('</tt>')
-
-    def visit_desc_parameterlist(self, node):
-        self.body.append('<big>(</big>')
-        self.first_param = 1
-    def depart_desc_parameterlist(self, node):
-        self.body.append('<big>)</big>')
-
-    def visit_desc_parameter(self, node):
-        if not self.first_param:
-            self.body.append(', ')
-        else:
-            self.first_param = 0
-        if not node.hasattr('noemph'):
-            self.body.append('<em>')
-    def depart_desc_parameter(self, node):
-        if not node.hasattr('noemph'):
-            self.body.append('</em>')
-    def visit_desc_optional(self, node):
-        self.body.append('<span class="optional">[</span>')
-    def depart_desc_optional(self, node):
-        self.body.append('<span class="optional">]</span>')
-
-    def visit_desc_content(self, node):
-        self.body.append(self.starttag(node, 'dd', ''))
-    def depart_desc_content(self, node):
-        self.body.append('</dd>')
-
-    def visit_refcount(self, node):
-        self.body.append(self.starttag(node, 'em', '', CLASS='refcount'))
-    def depart_refcount(self, node):
-        self.body.append('</em>')
-
-    def visit_versionmodified(self, node):
-        self.body.append(self.starttag(node, 'p'))
-        text = version_text[node['type']] % node['version']
-        if len(node):
-            text += ': '
-        else:
-            text += '.'
-        self.body.append('<span class="versionmodified">%s</span>' % text)
-    def depart_versionmodified(self, node):
-        self.body.append('</p>\n')
-
-    # overwritten -- we don't want source comments to show up in the HTML
-    def visit_comment(self, node):
-        raise nodes.SkipNode
-
-
-        # overwritten
-    def visit_admonition(self, node, name=''):
-        self.body.append(self.start_tag_with_title(
-            node, 'div', CLASS=('admonition ' + name)))
-        if name and name != 'seealso':
-            node.insert(0, nodes.title(name, self.language.labels[name]))
-        self.set_first_last(node)
-
-    def visit_seealso(self, node):
-        self.visit_admonition(node, 'seealso')
-    def depart_seealso(self, node):
-        self.depart_admonition(node)
-
-    # overwritten
-    def visit_title(self, node, move_ids=1):
-        # if we have a section we do our own processing in order
-        # to have ids in the hN-tags and not in additional a-tags
-        if isinstance(node.parent, nodes.section):
-            h_level = self.section_level + self.initial_header_level - 1
-            if node.parent.get('ids'):
-                attrs = {'ids': node.parent['ids']}
-            else:
-                attrs = {}
-            self.body.append(self.starttag(node, 'h%d' % h_level, '', **attrs))
-            self.context.append('</h%d>\n' % h_level)
-        else:
-            BaseTranslator.visit_title(self, node, move_ids)
-
-    # overwritten
-    def visit_literal_block(self, node):
-        #from .highlighting import highlight_block
-        #self.body.append(highlight_block(node.rawsource, self.highlightlang))
-        raise nodes.SkipNode
-
-    def visit_productionlist(self, node):
-        self.body.append(self.starttag(node, 'pre'))
-        names = []
-        for production in node:
-            names.append(production['tokenname'])
-        maxlen = max(len(name) for name in names)
-        for production in node:
-            if production['tokenname']:
-                self.body.append(self.starttag(production, 'strong', ''))
-                self.body.append(production['tokenname'].ljust(maxlen) +
-                                 '</strong> ::= ')
-                lastname = production['tokenname']
-            else:
-                self.body.append('%s     ' % (' '*len(lastname)))
-            production.walkabout(self)
-            self.body.append('\n')
-        self.body.append('</pre>\n')
-        raise nodes.SkipNode
-    def depart_productionlist(self, node):
-        pass
-
-    def visit_production(self, node):
-        pass
-    def depart_production(self, node):
-        pass
-
-    def visit_centered(self, node):
-        self.body.append(self.starttag(node, 'center') + '<strong>')
-    def depart_centered(self, node):
-        self.body.append('</strong></center>')
-
-    def visit_compact_paragraph(self, node):
-        pass
-    def depart_compact_paragraph(self, node):
-        pass
-
-    def visit_highlightlang(self, node):
-        self.highlightlang = node['lang']
-    def depart_highlightlang(self, node):
-        pass
-
-    def visit_toctree(self, node):
-        # this only happens when formatting a toc from env.tocs -- in this
-        # case we don't want to include the subtree
-        raise nodes.SkipNode
-
-    def visit_index(self, node):
-        raise nodes.SkipNode
-
-    #def unknown_visit(self, node):
-    #    print "UNKNOWN: ", node
-    #def unknown_departure(self, node):
-    #    print "UNKNOWN DEP: ", node
-
-    def visit_pending_xref(self, node):
-        #self.parent.append(nodes.literal(node['reftarget'], node['reftarget']))
-        raise nodes.SkipNode
-



More information about the Checkins mailing list