]> git.donarmstrong.com Git - neurodebian.git/commitdiff
dirty but working version of quoting
authorYaroslav Halchenko <debian@onerussian.com>
Fri, 22 Oct 2010 02:37:23 +0000 (22:37 -0400)
committerYaroslav Halchenko <debian@onerussian.com>
Fri, 22 Oct 2010 02:37:23 +0000 (22:37 -0400)
tested with sphinx 0.6.6-3 and docutils 0.7-2

sphinx/ext/quote.py

index 1b1ae8e58e182c26b0113032a7d020159a844057..668b681183d273238e458d1a4fc8be6381864f2e 100644 (file)
    :license: BSD
 """
 
+import operator
+from random import sample
+
 from docutils import nodes
 from docutils.parsers.rst import directives, Directive
 from docutils.parsers.rst.directives import body
 
-from sphinx.locale import _
 from sphinx.environment import NoUri
 from sphinx.util.compat import Directive, make_admonition
 
 
-class quote_node(nodes.Admonition, nodes.Element): pass
-class quotelist(nodes.General, nodes.Element): pass
+class quote_node(nodes.Body, nodes.Element): pass
+class quotes(nodes.General, nodes.Element): pass
+
+def _info(msg):
+       # print "I: ", msg
+       pass
+
+def _prep_tags(options):
+       """Extract tags listed in a string"""
+       options['tags'] = set((x.strip()
+                                                  for x in
+                                                  options.get('tags', '').split(',')))
 
 class Quote(Directive):
     """
@@ -36,18 +48,26 @@ class Quote(Directive):
                'affiliation': directives.unchanged,
                'date': directives.unchanged,
                'group': directives.unchanged,
+               'tags': directives.unchanged,   # list of tags per quote
                'source': directives.unchanged}
 
     def run(self):
         state = self.state
         env = self.state.document.settings.env
         options = self.options
-
-        targetid = 'index-%s' % env.new_serialno('index')
+               if hasattr(env, 'new_serialno'):
+                       targetid = 'index-%s' % env.new_serialno('index')
+               else:
+                       targetid = "index-%s" % env.index_num
         targetnode = nodes.target('', '', ids=[targetid])
                targetnode['classes'] = ['epigraph']
 
-        node = state.block_quote(self.content, self.content_offset)
+        node = quote_node()
+               node += nodes.block_quote(
+                       '',
+                       nodes.paragraph('', '\n'.join(self.content), classes=['text']))
+               #state.nested_parse(self.content, self.content_offset, node)
+
         for element in node:
             if isinstance(element, nodes.block_quote):
                 element['classes'] += ['epigraph']
@@ -65,7 +85,11 @@ class Quote(Directive):
                                siglb += [nodes.inline('', '  '+options[el], classes=[el])]
                signode[0].extend(siglb)
                node[0].extend(signode)
-        return [targetnode] + node;
+               node.line = self.lineno
+               # tune up options
+               _prep_tags(self.options)
+               node.options = options
+        return [targetnode] + [node]
 
 
 
@@ -73,25 +97,27 @@ def process_quotes(app, doctree):
     # collect all quotes in the environment
     # this is not done in the directive itself because it some transformations
     # must have already been run, e.g. substitutions
+       _info("process_quotes")
+
     env = app.builder.env
     if not hasattr(env, 'quote_all_quotes'):
         env.quote_all_quotes = []
-    ## for node in doctree.traverse(quote_node):
-    ##     try:
-    ##         targetnode = node.parent[node.parent.index(node) - 1]
-    ##         if not isinstance(targetnode, nodes.target):
-    ##             raise IndexError
-    ##     except IndexError:
-    ##         targetnode = None
-    ##     env.quote_all_quotes.append({
-    ##         'docname': env.docname,
-    ##         'lineno': node.line,
-    ##         'quote': node.deepcopy(),
-    ##         'target': targetnode,
-    ##     })
-
-
-class QuoteList(Directive):
+    for node in doctree.traverse(quote_node):
+        try:
+            targetnode = node.parent[node.parent.index(node) - 1]
+            if not isinstance(targetnode, nodes.target):
+                raise IndexError
+        except IndexError:
+            targetnode = None
+        env.quote_all_quotes.append({
+            'docname': env.docname,
+            'lineno': node.line,
+            'quote': node, #.deepcopy(),
+            'target': targetnode,
+        })
+
+
+class Quotes(Directive):
     """
     A list of all quote entries.
     """
@@ -101,13 +127,22 @@ class QuoteList(Directive):
     optional_arguments = 0
     final_argument_whitespace = False
        option_spec = {
-               'entries': lambda a: directives.choice(a, ('all', 'random')),
-               'grouping': lambda a: directives.choice(a, ('month', 'group', None))}
+               'random': directives.positive_int, # how many to randomly output
+               'group': directives.unchanged,     # what group to show
+               'tags': directives.unchanged,   # list of tags to be matched
+               #'sections': lambda a: directives.choice(a, ('date', 'group'))
+               }
 
     def run(self):
-        # Simply insert an empty quotelist node which will be replaced later
+        # Simply insert an empty quotes node which will be replaced later
         # when process_quote_nodes is called
-        return [quotelist('')]
+               res = quotes('')
+               # tags which must be matched
+               if 'tags' in self.options:
+                       _prep_tags(self.options)
+               res.options = self.options
+               _info("Run Quotes %s" % res)
+        return [res]
 
 
 
@@ -116,59 +151,111 @@ def process_quote_nodes(app, doctree, fromdocname):
     ##     for node in doctree.traverse(quote_node):
     ##         node.parent.remove(node)
 
-    # Replace all quotelist nodes with a list of the collected quotes.
+    # Replace all quotes nodes with a list of the collected quotes.
     # Augment each quote with a backlink to the original location.
     env = app.builder.env
 
     if not hasattr(env, 'quote_all_quotes'):
         env.quote_all_quotes = []
 
-    for node in doctree.traverse(quotelist):
+       #_info("process_quote_nodes '%s' %i"
+       #         % (fromdocname, len(env.quote_all_quotes)))
+
+    for node in doctree.traverse(quotes):
         ## if not app.config['quote_include_quotes']:
         ##     node.replace_self([])
         ##     continue
 
         content = []
+               filters = []
+               loptions = node.options
+
+               # Filter by tags?
+               if 'tags' in loptions:
+                       ltags = loptions['tags']
+                       filters.append(
+                               lambda quote: set.issuperset(
+                                       quote.options['tags'], ltags))
+               # Filter by group?
+               if 'group' in loptions:
+                       loptions['group']
+                       filters.append(
+                               lambda quote:
+                               quote.options.get('group', '') == loptions['group'])
 
         for quote_info in env.quote_all_quotes:
-            para = nodes.paragraph(classes=['quote-source'])
-            filename = env.doc2path(quote_info['docname'], base=None)
-            description = _('(The <<original entry>> is located in '
-                            ' %s, line %d.)') % (filename, quote_info['lineno'])
-            desc1 = description[:description.find('<<')]
-            desc2 = description[description.find('>>')+2:]
-            para += nodes.Text(desc1, desc1)
-
-            # Create a reference
-            newnode = nodes.reference('', '', internal=True)
-            innernode = nodes.emphasis(_('original entry'), _('original entry'))
-            try:
-                newnode['refuri'] = app.builder.get_relative_uri(
-                    fromdocname, quote_info['docname'])
-                newnode['refuri'] += '#' + quote_info['target']['refid']
-            except NoUri:
-                # ignore if no URI can be determined, e.g. for LaTeX output
-                pass
-            newnode.append(innernode)
-            para += newnode
-            para += nodes.Text(desc2, desc2)
-            #para += nodes.Text("XXX", "YYY")
+            quote_entry = quote_info['quote']
+                       if not reduce(operator.__and__,
+                                                 [f(quote_entry) for f in filters],
+                                                 True):
+                               continue
+                       ## Commented out mechanism to back-reference original
+                       ## location
+                       ##
+            ## para = nodes.paragraph(classes=['quote-source'])
+            ## filename = env.doc2path(quote_info['docname'], base=None)
+            ## description = _('(The <<original entry>> is located in '
+            ##                 ' %s, line %d.)') % (filename, quote_info['lineno'])
+            ## desc1 = description[:description.find('<<')]
+            ## desc2 = description[description.find('>>')+2:]
+            ## para += nodes.Text(desc1, desc1)
+
+            ## # Create a reference
+            ## newnode = nodes.reference('', '', internal=True)
+            ## innernode = nodes.emphasis(_('original entry'), _('original entry'))
+            ## try:
+            ##     newnode['refuri'] = app.builder.get_relative_uri(
+            ##         fromdocname, quote_info['docname'])
+            ##     newnode['refuri'] += '#' + quote_info['target']['refid']
+            ## except NoUri:
+            ##     # ignore if no URI can be determined, e.g. for LaTeX output
+            ##     pass
+            ## newnode.append(innernode)
+            ## para += newnode
+            ## para += nodes.Text(desc2, desc2)
+            ## #para += nodes.Text("XXX", "YYY")
 
             # (Recursively) resolve references in the quote content
-            quote_entry = quote_info['quote']
             env.resolve_references(quote_entry, quote_info['docname'],
                                    app.builder)
 
-            # Insert into the quotelist
+            # Insert into the quotes
             content.append(quote_entry)
-            content.append(para)
-
+            ## content.append(para)
+
+               # Handle additional quotes options
+
+               # Select a limited number of random samples
+               if loptions.get('random', None):
+                       # Randomly select desired number of quotes
+                       content = sample(content, loptions['random'])
+
+               # Group items into sections and intersperse the list
+               # with section nodes
+               if loptions.get('sections', None):
+                       raise NotImplementedError
+                       term = loptions['sections']
+                       terms = [q.options.get(term, None) for q in content]
+                       terms = list(set([x for x in terms if x]))
+                       # Simply sort according to what to group on,
+                       # and then insert sections?
+                       #import pydb
+                       #pydb.debugger()
+                       section = nodes.section('')
+                       section.extend(nodes.title('', 'XXX'))
+                       section += content[:2]
+                       section.parent = content[0].parent
+                       content = [ section ]
+
+               # Substitute with the content
         node.replace_self(content)
 
 
+
 def purge_quotes(app, env, docname):
     if not hasattr(env, 'quote_all_quotes'):
         return
+       _info("purge_quotes")
     env.quote_all_quotes = [quote for quote in env.quote_all_quotes
                           if quote['docname'] != docname]
 
@@ -180,14 +267,14 @@ def setup(app):
        ## app.add_config_value('quotes_include_quotes', False, False)
        #import pydb
        #pydb.debugger()
-    app.add_node(quotelist)
+    app.add_node(quotes)
     app.add_node(quote_node,
                  html=(quotes_noop, quotes_noop),
                  latex=(quotes_noop, quotes_noop),
                  text=(quotes_noop, quotes_noop))
 
     app.add_directive('quote', Quote)
-    app.add_directive('quotelist', QuoteList)
+    app.add_directive('quotes', Quotes)
     app.connect('doctree-read', process_quotes)
     app.connect('doctree-resolved', process_quote_nodes)
     app.connect('env-purge-doc', purge_quotes)