summaryrefslogtreecommitdiff
path: root/docs/_ext/djangodocs.py
diff options
context:
space:
mode:
authorM Nasimul Haque <nasim.haque@gmail.com>2013-09-23 23:23:47 +0100
committerTim Graham <timograham@gmail.com>2013-10-14 13:00:57 -0400
commitd07d6ae1167f93f2e88b3743c070003a66a31b35 (patch)
tree7e492b8bed053b01f728a10702276895cf47c8a2 /docs/_ext/djangodocs.py
parente077224f4ad69a68ae58a373ef69941272d3656c (diff)
downloaddjango-d07d6ae1167f93f2e88b3743c070003a66a31b35.tar.gz
Fixed #20910 -- Added a "snippet" sphinx directive to allow prefixing a filename.
Thanks Marc Tamlyn for the suggestion.
Diffstat (limited to 'docs/_ext/djangodocs.py')
-rw-r--r--docs/_ext/djangodocs.py134
1 files changed, 134 insertions, 0 deletions
diff --git a/docs/_ext/djangodocs.py b/docs/_ext/djangodocs.py
index e7e316f58b..1c1ed53672 100644
--- a/docs/_ext/djangodocs.py
+++ b/docs/_ext/djangodocs.py
@@ -5,11 +5,15 @@ import json
import os
import re
+from docutils import nodes
+from docutils.parsers.rst import directives
+
from sphinx import addnodes, __version__ as sphinx_ver
from sphinx.builders.html import StandaloneHTMLBuilder
from sphinx.writers.html import SmartyPantsHTMLTranslator
from sphinx.util.console import bold
from sphinx.util.compat import Directive
+from sphinx.util.nodes import set_source_info
# RE for option descriptions without a '--' prefix
simple_option_desc_re = re.compile(
@@ -53,6 +57,136 @@ def setup(app):
app.add_directive('versionchanged', VersionDirective)
app.add_builder(DjangoStandaloneHTMLBuilder)
+ # register the snippet directive
+ app.add_directive('snippet', SnippetWithFilename)
+ # register a node for snippet directive so that the xml parser
+ # knows how to handle the enter/exit parsing event
+ app.add_node(snippet_with_filename,
+ html=(visit_snippet, depart_snippet_literal),
+ latex=(visit_snippet_latex, depart_snippet_latex),
+ man=(visit_snippet_literal, depart_snippet_literal),
+ text=(visit_snippet_literal, depart_snippet_literal),
+ texinfo=(visit_snippet_literal, depart_snippet_literal))
+
+
+class snippet_with_filename(nodes.literal_block):
+ """
+ Subclass the literal_block to override the visit/depart event handlers
+ """
+ pass
+
+
+def visit_snippet_literal(self, node):
+ """
+ default literal block handler
+ """
+ self.visit_literal_block(node)
+
+
+def depart_snippet_literal(self, node):
+ """
+ default literal block handler
+ """
+ self.depart_literal_block(node)
+
+
+def visit_snippet(self, node):
+ """
+ HTML document generator visit handler
+ """
+ lang = self.highlightlang
+ linenos = node.rawsource.count('\n') >= self.highlightlinenothreshold - 1
+ fname = node['filename']
+ highlight_args = node.get('highlight_args', {})
+ if node.has_key('language'):
+ # code-block directives
+ lang = node['language']
+ highlight_args['force'] = True
+ if node.has_key('linenos'):
+ linenos = node['linenos']
+
+ def warner(msg):
+ self.builder.warn(msg, (self.builder.current_docname, node.line))
+
+ highlighted = self.highlighter.highlight_block(node.rawsource, lang,
+ warn=warner,
+ linenos=linenos,
+ **highlight_args)
+ starttag = self.starttag(node, 'div', suffix='',
+ CLASS='highlight-%s' % lang)
+ self.body.append(starttag)
+ self.body.append('<div class="snippet-filename">%s</div>\n''' % (fname,))
+ self.body.append(highlighted)
+ self.body.append('</div>\n')
+ raise nodes.SkipNode
+
+
+def visit_snippet_latex(self, node):
+ """
+ Latex document generator visit handler
+ """
+ self.verbatim = ''
+
+
+def depart_snippet_latex(self, node):
+ """
+ Latex document generator depart handler.
+ """
+ code = self.verbatim.rstrip('\n')
+ lang = self.hlsettingstack[-1][0]
+ linenos = code.count('\n') >= self.hlsettingstack[-1][1] - 1
+ fname = node['filename']
+ highlight_args = node.get('highlight_args', {})
+ if 'language' in node:
+ # code-block directives
+ lang = node['language']
+ highlight_args['force'] = True
+ if 'linenos' in node:
+ linenos = node['linenos']
+
+ def warner(msg):
+ self.builder.warn(msg, (self.curfilestack[-1], node.line))
+
+ hlcode = self.highlighter.highlight_block(code, lang, warn=warner,
+ linenos=linenos,
+ **highlight_args)
+
+ self.body.append('\n{\\colorbox[rgb]{0.9,0.9,0.9}'
+ '{\\makebox[\\textwidth][l]'
+ '{\\small\\texttt{%s}}}}\n' % (fname,))
+
+ if self.table:
+ hlcode = hlcode.replace('\\begin{Verbatim}',
+ '\\begin{OriginalVerbatim}')
+ self.table.has_problematic = True
+ self.table.has_verbatim = True
+
+ hlcode = hlcode.rstrip()[:-14] # strip \end{Verbatim}
+ hlcode = hlcode.rstrip() + '\n'
+ self.body.append('\n' + hlcode + '\\end{%sVerbatim}\n' %
+ (self.table and 'Original' or ''))
+ self.verbatim = None
+
+
+class SnippetWithFilename(Directive):
+ """
+ The 'snippet' directive that allows to add the filename (optional)
+ of a code snippet in the document. This is modeled after CodeBlock.
+ """
+ has_content = True
+ optional_arguments = 1
+ option_spec = {'filename': directives.unchanged_required}
+
+ def run(self):
+ code = u'\n'.join(self.content)
+
+ literal = snippet_with_filename(code, code)
+ if self.arguments:
+ literal['language'] = self.arguments[0]
+ literal['filename'] = self.options['filename']
+ set_source_info(self, literal)
+ return [literal]
+
class VersionDirective(Directive):
has_content = True