App Engine Python SDK version 1.7.4 (2)
[gae.git] / python / lib / django_1_4 / docs / _ext / djangodocs.py
blob3cf00a38e1c59c6ae2cf8172e363868dd0bc5382
1 """
2 Sphinx plugins for Django documentation.
3 """
4 import os
5 import re
7 from docutils import nodes, transforms
8 try:
9 import json
10 except ImportError:
11 try:
12 import simplejson as json
13 except ImportError:
14 try:
15 from django.utils import simplejson as json
16 except ImportError:
17 json = None
19 from sphinx import addnodes, roles, __version__ as sphinx_ver
20 from sphinx.builders.html import StandaloneHTMLBuilder
21 from sphinx.writers.html import SmartyPantsHTMLTranslator
22 from sphinx.util.console import bold
23 from sphinx.util.compat import Directive
25 # RE for option descriptions without a '--' prefix
26 simple_option_desc_re = re.compile(
27 r'([-_a-zA-Z0-9]+)(\s*.*?)(?=,\s+(?:/|-|--)|$)')
29 def setup(app):
30 app.add_crossref_type(
31 directivename = "setting",
32 rolename = "setting",
33 indextemplate = "pair: %s; setting",
35 app.add_crossref_type(
36 directivename = "templatetag",
37 rolename = "ttag",
38 indextemplate = "pair: %s; template tag"
40 app.add_crossref_type(
41 directivename = "templatefilter",
42 rolename = "tfilter",
43 indextemplate = "pair: %s; template filter"
45 app.add_crossref_type(
46 directivename = "fieldlookup",
47 rolename = "lookup",
48 indextemplate = "pair: %s; field lookup type",
50 app.add_description_unit(
51 directivename = "django-admin",
52 rolename = "djadmin",
53 indextemplate = "pair: %s; django-admin command",
54 parse_node = parse_django_admin_node,
56 app.add_description_unit(
57 directivename = "django-admin-option",
58 rolename = "djadminopt",
59 indextemplate = "pair: %s; django-admin command-line option",
60 parse_node = parse_django_adminopt_node,
62 app.add_config_value('django_next_version', '0.0', True)
63 app.add_directive('versionadded', VersionDirective)
64 app.add_directive('versionchanged', VersionDirective)
65 app.add_builder(DjangoStandaloneHTMLBuilder)
68 class VersionDirective(Directive):
69 has_content = True
70 required_arguments = 1
71 optional_arguments = 1
72 final_argument_whitespace = True
73 option_spec = {}
75 def run(self):
76 env = self.state.document.settings.env
77 arg0 = self.arguments[0]
78 is_nextversion = env.config.django_next_version == arg0
79 ret = []
80 node = addnodes.versionmodified()
81 ret.append(node)
82 if not is_nextversion:
83 if len(self.arguments) == 1:
84 linktext = 'Please see the release notes </releases/%s>' % (arg0)
85 xrefs = roles.XRefRole()('doc', linktext, linktext, self.lineno, self.state)
86 node.extend(xrefs[0])
87 node['version'] = arg0
88 else:
89 node['version'] = "Development version"
90 node['type'] = self.name
91 if len(self.arguments) == 2:
92 inodes, messages = self.state.inline_text(self.arguments[1], self.lineno+1)
93 node.extend(inodes)
94 if self.content:
95 self.state.nested_parse(self.content, self.content_offset, node)
96 ret = ret + messages
97 env.note_versionchange(node['type'], node['version'], node, self.lineno)
98 return ret
101 class DjangoHTMLTranslator(SmartyPantsHTMLTranslator):
103 Django-specific reST to HTML tweaks.
106 # Don't use border=1, which docutils does by default.
107 def visit_table(self, node):
108 self._table_row_index = 0 # Needed by Sphinx
109 self.body.append(self.starttag(node, 'table', CLASS='docutils'))
111 # <big>? Really?
112 def visit_desc_parameterlist(self, node):
113 self.body.append('(')
114 self.first_param = 1
115 self.param_separator = node.child_text_separator
117 def depart_desc_parameterlist(self, node):
118 self.body.append(')')
120 if sphinx_ver < '1.0.8':
122 # Don't apply smartypants to literal blocks
124 def visit_literal_block(self, node):
125 self.no_smarty += 1
126 SmartyPantsHTMLTranslator.visit_literal_block(self, node)
128 def depart_literal_block(self, node):
129 SmartyPantsHTMLTranslator.depart_literal_block(self, node)
130 self.no_smarty -= 1
133 # Turn the "new in version" stuff (versionadded/versionchanged) into a
134 # better callout -- the Sphinx default is just a little span,
135 # which is a bit less obvious that I'd like.
137 # FIXME: these messages are all hardcoded in English. We need to change
138 # that to accomodate other language docs, but I can't work out how to make
139 # that work.
141 version_text = {
142 'deprecated': 'Deprecated in Django %s',
143 'versionchanged': 'Changed in Django %s',
144 'versionadded': 'New in Django %s',
147 def visit_versionmodified(self, node):
148 self.body.append(
149 self.starttag(node, 'div', CLASS=node['type'])
151 title = "%s%s" % (
152 self.version_text[node['type']] % node['version'],
153 len(node) and ":" or "."
155 self.body.append('<span class="title">%s</span> ' % title)
157 def depart_versionmodified(self, node):
158 self.body.append("</div>\n")
160 # Give each section a unique ID -- nice for custom CSS hooks
161 def visit_section(self, node):
162 old_ids = node.get('ids', [])
163 node['ids'] = ['s-' + i for i in old_ids]
164 node['ids'].extend(old_ids)
165 SmartyPantsHTMLTranslator.visit_section(self, node)
166 node['ids'] = old_ids
168 def parse_django_admin_node(env, sig, signode):
169 command = sig.split(' ')[0]
170 env._django_curr_admin_command = command
171 title = "django-admin.py %s" % sig
172 signode += addnodes.desc_name(title, title)
173 return sig
175 def parse_django_adminopt_node(env, sig, signode):
176 """A copy of sphinx.directives.CmdoptionDesc.parse_signature()"""
177 from sphinx.domains.std import option_desc_re
178 count = 0
179 firstname = ''
180 for m in option_desc_re.finditer(sig):
181 optname, args = m.groups()
182 if count:
183 signode += addnodes.desc_addname(', ', ', ')
184 signode += addnodes.desc_name(optname, optname)
185 signode += addnodes.desc_addname(args, args)
186 if not count:
187 firstname = optname
188 count += 1
189 if not count:
190 for m in simple_option_desc_re.finditer(sig):
191 optname, args = m.groups()
192 if count:
193 signode += addnodes.desc_addname(', ', ', ')
194 signode += addnodes.desc_name(optname, optname)
195 signode += addnodes.desc_addname(args, args)
196 if not count:
197 firstname = optname
198 count += 1
199 if not firstname:
200 raise ValueError
201 return firstname
204 class DjangoStandaloneHTMLBuilder(StandaloneHTMLBuilder):
206 Subclass to add some extra things we need.
209 name = 'djangohtml'
211 def finish(self):
212 super(DjangoStandaloneHTMLBuilder, self).finish()
213 if json is None:
214 self.warn("cannot create templatebuiltins.js due to missing simplejson dependency")
215 return
216 self.info(bold("writing templatebuiltins.js..."))
217 xrefs = self.env.domaindata["std"]["objects"]
218 templatebuiltins = {
219 "ttags": [n for ((t, n), (l, a)) in xrefs.items()
220 if t == "templatetag" and l == "ref/templates/builtins"],
221 "tfilters": [n for ((t, n), (l, a)) in xrefs.items()
222 if t == "templatefilter" and l == "ref/templates/builtins"],
224 outfilename = os.path.join(self.outdir, "templatebuiltins.js")
225 f = open(outfilename, 'wb')
226 f.write('var django_template_builtins = ')
227 json.dump(templatebuiltins, f)
228 f.write(';\n')
229 f.close();