diff options
author | M Nasimul Haque <nasim.haque@gmail.com> | 2013-09-23 23:23:47 +0100 |
---|---|---|
committer | Tim Graham <timograham@gmail.com> | 2013-10-14 13:00:57 -0400 |
commit | d07d6ae1167f93f2e88b3743c070003a66a31b35 (patch) | |
tree | 7e492b8bed053b01f728a10702276895cf47c8a2 /docs/_ext/djangodocs.py | |
parent | e077224f4ad69a68ae58a373ef69941272d3656c (diff) | |
download | django-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.py | 134 |
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 |