]> git.donarmstrong.com Git - neurodebian.git/commitdiff
initial support for quotes -- just renders :quote: directives atm
authorYaroslav Halchenko <debian@onerussian.com>
Thu, 21 Oct 2010 20:42:19 +0000 (16:42 -0400)
committerYaroslav Halchenko <debian@onerussian.com>
Thu, 21 Oct 2010 20:42:19 +0000 (16:42 -0400)
sphinx/_static/neurodebian.css
sphinx/conf.py
sphinx/ext/__init__.py [new file with mode: 0644]
sphinx/ext/quote.py [new file with mode: 0644]

index 69086be643b395e5bbdb131e5948da2551057600..e1cebba4603eeaa3b40a596fe9fc4c6191a0dfff 100644 (file)
@@ -660,6 +660,42 @@ img.logo {
     border: 0;
 }
 
+
+/* Epigraphs */
+
+blockquote.epigraph {
+    padding: 0 1em 0 1em;
+    background-color: #f2f2f2;
+       border-top: 1px solid #ccc;
+       border-bottom: 1px solid #ccc;
+    font-style: italic;
+}
+
+blockquote.epigraph p {
+    margin: 0.2em 0 0.2em 0;
+}
+
+p.attribution {
+       padding: 0.2em 0 0 1em;
+       font-size: 80%;
+    font-style: normal;
+}
+
+p.attribution span.author {
+    margin: 0;
+    font-weight: bold;
+}
+
+p.attribution span.date {
+       font-size: 90%;
+}
+
+p.attribution span.affiliation, span.source {
+       font-size: 90%;
+       padding: 0 0 0 25px;
+       display: block;
+}
+
 /* :::: PRINT :::: */
 @media print {
     div.document,
index 698c32dcdf683a19618551baa0ebcf011cd9b469..f7d0378a610a79b35b32290787751d4b065cb39d 100644 (file)
@@ -41,7 +41,9 @@ def artworkdir():
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = []
+#extensions = []
+sys.path.append(os.path.abspath('.'))
+extensions = ['ext.quote']
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
diff --git a/sphinx/ext/__init__.py b/sphinx/ext/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/sphinx/ext/quote.py b/sphinx/ext/quote.py
new file mode 100644 (file)
index 0000000..1b1ae8e
--- /dev/null
@@ -0,0 +1,193 @@
+#emacs: -*- coding: utf-8; mode: python-mode; py-indent-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
+#ex: set sts=4 ts=4 sw=4 et:
+"""
+   ext.quote
+   ~~~~~~~~~
+
+   Compile the quotes
+
+   :copyright: Copyright 2010 Yaroslav O. Halchenko
+   :license: BSD
+"""
+
+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(Directive):
+    """
+    A quote entry, displayed (if configured) in the form of an admonition.
+    """
+
+    has_content = True
+    required_arguments = 0
+    optional_arguments = 0
+    final_argument_whitespace = False
+       option_spec = {
+               'author': directives.unchanged,
+               'affiliation': directives.unchanged,
+               'date': directives.unchanged,
+               'group': directives.unchanged,
+               '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')
+        targetnode = nodes.target('', '', ids=[targetid])
+               targetnode['classes'] = ['epigraph']
+
+        node = state.block_quote(self.content, self.content_offset)
+        for element in node:
+            if isinstance(element, nodes.block_quote):
+                element['classes'] += ['epigraph']
+
+               signode = [nodes.attribution('--', '--')]
+               # Embed all components within attributions
+               siglb = nodes.line_block('')
+               # Pre-format some
+               if 'date' in options:
+                       options['date'] = '[%(date)s]' % options
+               if 'source' in options:
+                       options['source'] = 'Source: %(source)s' % options
+               for el in ['author', 'date', 'affiliation', 'source']:
+                       if el in options:
+                               siglb += [nodes.inline('', '  '+options[el], classes=[el])]
+               signode[0].extend(siglb)
+               node[0].extend(signode)
+        return [targetnode] + node;
+
+
+
+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
+    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):
+    """
+    A list of all quote entries.
+    """
+
+    has_content = False
+    required_arguments = 0
+    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))}
+
+    def run(self):
+        # Simply insert an empty quotelist node which will be replaced later
+        # when process_quote_nodes is called
+        return [quotelist('')]
+
+
+
+def process_quote_nodes(app, doctree, fromdocname):
+    ## if not app.config['quote_include_quotes']:
+    ##     for node in doctree.traverse(quote_node):
+    ##         node.parent.remove(node)
+
+    # Replace all quotelist 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):
+        ## if not app.config['quote_include_quotes']:
+        ##     node.replace_self([])
+        ##     continue
+
+        content = []
+
+        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")
+
+            # (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
+            content.append(quote_entry)
+            content.append(para)
+
+        node.replace_self(content)
+
+
+def purge_quotes(app, env, docname):
+    if not hasattr(env, 'quote_all_quotes'):
+        return
+    env.quote_all_quotes = [quote for quote in env.quote_all_quotes
+                          if quote['docname'] != docname]
+
+
+def quotes_noop(self, node):
+       pass
+
+def setup(app):
+       ## app.add_config_value('quotes_include_quotes', False, False)
+       #import pydb
+       #pydb.debugger()
+    app.add_node(quotelist)
+    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.connect('doctree-read', process_quotes)
+    app.connect('doctree-resolved', process_quote_nodes)
+    app.connect('env-purge-doc', purge_quotes)