Changeset 391 for python/trunk/Doc/tools/sphinxext/pyspecific.py
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Doc/tools/sphinxext/pyspecific.py
r2 r391 6 6 Sphinx extension with Python doc-specific markup. 7 7 8 :copyright: 2008 , 2009by Georg Brandl.8 :copyright: 2008-2013 by Georg Brandl. 9 9 :license: Python license. 10 10 """ 11 11 12 12 ISSUE_URI = 'http://bugs.python.org/issue%s' 13 SOURCE_URI = 'http://hg.python.org/cpython/file/2.7/%s' 13 14 14 15 from docutils import nodes, utils 16 17 import sphinx 18 from sphinx.util.nodes import split_explicit_title 19 from sphinx.writers.html import HTMLTranslator 20 from sphinx.writers.latex import LaTeXTranslator 21 from sphinx.locale import versionlabels 15 22 16 23 # monkey-patch reST parser to disable alphabetic and roman enumerated lists … … 21 28 Body.enum.converters['upperroman'] = lambda x: None 22 29 23 # monkey-patch HTML translator to give versionmodified paragraphs a class 24 def new_visit_versionmodified(self, node): 25 self.body.append(self.starttag(node, 'p', CLASS=node['type'])) 26 text = versionlabels[node['type']] % node['version'] 27 if len(node): 28 text += ': ' 29 else: 30 text += '.' 31 self.body.append('<span class="versionmodified">%s</span>' % text) 32 33 from sphinx.writers.html import HTMLTranslator 34 from sphinx.locale import versionlabels 35 HTMLTranslator.visit_versionmodified = new_visit_versionmodified 30 if sphinx.__version__[:3] < '1.2': 31 # monkey-patch HTML translator to give versionmodified paragraphs a class 32 def new_visit_versionmodified(self, node): 33 self.body.append(self.starttag(node, 'p', CLASS=node['type'])) 34 text = versionlabels[node['type']] % node['version'] 35 if len(node): 36 text += ': ' 37 else: 38 text += '.' 39 self.body.append('<span class="versionmodified">%s</span>' % text) 40 HTMLTranslator.visit_versionmodified = new_visit_versionmodified 41 42 # monkey-patch HTML and LaTeX translators to keep doctest blocks in the 43 # doctest docs themselves 44 orig_visit_literal_block = HTMLTranslator.visit_literal_block 45 def new_visit_literal_block(self, node): 46 meta = self.builder.env.metadata[self.builder.current_docname] 47 old_trim_doctest_flags = self.highlighter.trim_doctest_flags 48 if 'keepdoctest' in meta: 49 self.highlighter.trim_doctest_flags = False 50 try: 51 orig_visit_literal_block(self, node) 52 finally: 53 self.highlighter.trim_doctest_flags = old_trim_doctest_flags 54 55 HTMLTranslator.visit_literal_block = new_visit_literal_block 56 57 orig_depart_literal_block = LaTeXTranslator.depart_literal_block 58 def new_depart_literal_block(self, node): 59 meta = self.builder.env.metadata[self.curfilestack[-1]] 60 old_trim_doctest_flags = self.highlighter.trim_doctest_flags 61 if 'keepdoctest' in meta: 62 self.highlighter.trim_doctest_flags = False 63 try: 64 orig_depart_literal_block(self, node) 65 finally: 66 self.highlighter.trim_doctest_flags = old_trim_doctest_flags 67 68 LaTeXTranslator.depart_literal_block = new_depart_literal_block 36 69 37 70 # Support for marking up and linking to bugs.python.org issues … … 41 74 text = 'issue ' + issue 42 75 refnode = nodes.reference(text, text, refuri=ISSUE_URI % issue) 76 return [refnode], [] 77 78 79 # Support for linking to Python source files easily 80 81 def source_role(typ, rawtext, text, lineno, inliner, options={}, content=[]): 82 has_t, title, target = split_explicit_title(text) 83 title = utils.unescape(title) 84 target = utils.unescape(target) 85 refnode = nodes.reference(title, title, refuri=SOURCE_URI % target) 43 86 return [refnode], [] 44 87 … … 72 115 73 116 117 # Support for documenting decorators 118 119 from sphinx import addnodes 120 from sphinx.domains.python import PyModulelevel, PyClassmember 121 122 class PyDecoratorMixin(object): 123 def handle_signature(self, sig, signode): 124 ret = super(PyDecoratorMixin, self).handle_signature(sig, signode) 125 signode.insert(0, addnodes.desc_addname('@', '@')) 126 return ret 127 128 def needs_arglist(self): 129 return False 130 131 class PyDecoratorFunction(PyDecoratorMixin, PyModulelevel): 132 def run(self): 133 # a decorator function is a function after all 134 self.name = 'py:function' 135 return PyModulelevel.run(self) 136 137 class PyDecoratorMethod(PyDecoratorMixin, PyClassmember): 138 def run(self): 139 self.name = 'py:method' 140 return PyClassmember.run(self) 141 142 143 # Support for documenting version of removal in deprecations 144 145 from sphinx.locale import versionlabels 146 from sphinx.util.compat import Directive 147 148 versionlabels['deprecated-removed'] = \ 149 'Deprecated since version %s, will be removed in version %s' 150 151 class DeprecatedRemoved(Directive): 152 has_content = True 153 required_arguments = 2 154 optional_arguments = 1 155 final_argument_whitespace = True 156 option_spec = {} 157 158 def run(self): 159 node = addnodes.versionmodified() 160 node.document = self.state.document 161 node['type'] = 'deprecated-removed' 162 version = (self.arguments[0], self.arguments[1]) 163 node['version'] = version 164 if len(self.arguments) == 3: 165 inodes, messages = self.state.inline_text(self.arguments[2], 166 self.lineno+1) 167 node.extend(inodes) 168 if self.content: 169 self.state.nested_parse(self.content, self.content_offset, node) 170 ret = [node] + messages 171 else: 172 ret = [node] 173 env = self.state.document.settings.env 174 env.note_versionchange('deprecated', version[0], node, self.lineno) 175 return ret 176 177 74 178 # Support for building "topic help" for pydoc 75 179 … … 78 182 'attribute-access', 'attribute-references', 'augassign', 'binary', 79 183 'bitwise', 'bltin-code-objects', 'bltin-ellipsis-object', 80 'bltin-file-objects', 'bltin-null-object', 'bltin-type-objects', 'booleans', 81 'break', 'callable-types', 'calls', 'class', 'coercion-rules', 82 'comparisons', 'compound', 'context-managers', 'continue', 'conversions', 83 'customization', 'debugger', 'del', 'dict', 'dynamic-features', 'else', 84 'exceptions', 'exec', 'execmodel', 'exprlists', 'floating', 'for', 85 'formatstrings', 'function', 'global', 'id-classes', 'identifiers', 'if', 86 'imaginary', 'import', 'in', 'integers', 'lambda', 'lists', 'naming', 87 'numbers', 'numeric-types', 'objects', 'operator-summary', 'pass', 'power', 88 'print', 'raise', 'return', 'sequence-methods', 'sequence-types', 89 'shifting', 'slicings', 'specialattrs', 'specialnames', 90 'string-conversions', 'string-methods', 'strings', 'subscriptions', 'truth', 91 'try', 'types', 'typesfunctions', 'typesmapping', 'typesmethods', 92 'typesmodules', 'typesseq', 'typesseq-mutable', 'unary', 'while', 'with', 93 'yield' 184 'bltin-null-object', 'bltin-type-objects', 'booleans', 185 'break', 'callable-types', 'calls', 'class', 'comparisons', 'compound', 186 'context-managers', 'continue', 'conversions', 'customization', 'debugger', 187 'del', 'dict', 'dynamic-features', 'else', 'exceptions', 'execmodel', 188 'exprlists', 'floating', 'for', 'formatstrings', 'function', 'global', 189 'id-classes', 'identifiers', 'if', 'imaginary', 'import', 'in', 'integers', 190 'lambda', 'lists', 'naming', 'numbers', 'numeric-types', 191 'objects', 'operator-summary', 'pass', 'power', 'raise', 'return', 192 'sequence-types', 'shifting', 'slicings', 'specialattrs', 'specialnames', 193 'string-methods', 'strings', 'subscriptions', 'truth', 'try', 'types', 194 'typesfunctions', 'typesmapping', 'typesmethods', 'typesmodules', 195 'typesseq', 'typesseq-mutable', 'unary', 'while', 'with', 'yield' 94 196 ] 95 197 … … 100 202 from docutils.utils import new_document 101 203 102 try: 103 from sphinx.builders import Builder 104 except ImportError: 105 # using Sphinx < 0.6, which has a different package layout 106 from sphinx.builder import Builder 107 # monkey-patch toctree directive to accept (and ignore) the :numbered: flag 108 from sphinx.directives.other import toctree_directive 109 toctree_directive.options['numbered'] = toctree_directive.options['glob'] 110 111 try: 112 from sphinx.writers.text import TextWriter 113 except ImportError: 114 from sphinx.textwriter import TextWriter 204 from sphinx.builders import Builder 205 from sphinx.writers.text import TextWriter 115 206 116 207 … … 129 220 def write(self, *ignored): 130 221 writer = TextWriter(self) 131 for label in self.status_iterator(pydoc_topic_labels, 'building topics... '): 132 if label not in self.env.labels: 222 for label in self.status_iterator(pydoc_topic_labels, 223 'building topics... ', 224 length=len(pydoc_topic_labels)): 225 if label not in self.env.domaindata['std']['labels']: 133 226 self.warn('label %r not in documentation' % label) 134 227 continue 135 docname, labelid, sectname = self.env. labels[label]228 docname, labelid, sectname = self.env.domaindata['std']['labels'][label] 136 229 doctree = self.env.get_and_resolve_doctree(docname, self) 137 230 document = new_document('<section node>') … … 139 232 destination = StringOutput(encoding='utf-8') 140 233 writer.write(document, destination) 141 self.topics[label] = writer.output234 self.topics[label] = str(writer.output) 142 235 143 236 def finish(self): 144 f = open(path.join(self.outdir, ' pydoc_topics.py'), 'w')237 f = open(path.join(self.outdir, 'topics.py'), 'w') 145 238 try: 146 239 f.write('# Autogenerated by Sphinx on %s\n' % asctime()) … … 158 251 159 252 import re 160 from sphinx import addnodes 161 162 opcode_sig_re = re.compile(r'(\w+(?:\+\d)?)\s*\((.*)\)') 253 254 opcode_sig_re = re.compile(r'(\w+(?:\+\d)?)(?:\s*\((.*)\))?') 163 255 164 256 def parse_opcode_signature(env, sig, signode): … … 169 261 opname, arglist = m.groups() 170 262 signode += addnodes.desc_name(opname, opname) 171 paramlist = addnodes.desc_parameterlist() 172 signode += paramlist 173 paramlist += addnodes.desc_parameter(arglist, arglist) 263 if arglist is not None: 264 paramlist = addnodes.desc_parameterlist() 265 signode += paramlist 266 paramlist += addnodes.desc_parameter(arglist, arglist) 174 267 return opname.strip() 268 269 270 # Support for documenting pdb commands 271 272 pdbcmd_sig_re = re.compile(r'([a-z()!]+)\s*(.*)') 273 274 # later... 275 #pdbargs_tokens_re = re.compile(r'''[a-zA-Z]+ | # identifiers 276 # [.,:]+ | # punctuation 277 # [\[\]()] | # parens 278 # \s+ # whitespace 279 # ''', re.X) 280 281 def parse_pdb_command(env, sig, signode): 282 """Transform a pdb command signature into RST nodes.""" 283 m = pdbcmd_sig_re.match(sig) 284 if m is None: 285 raise ValueError 286 name, args = m.groups() 287 fullname = name.replace('(', '').replace(')', '') 288 signode += addnodes.desc_name(name, name) 289 if args: 290 signode += addnodes.desc_addname(' '+args, ' '+args) 291 return fullname 175 292 176 293 177 294 def setup(app): 178 295 app.add_role('issue', issue_role) 296 app.add_role('source', source_role) 179 297 app.add_directive('impl-detail', ImplementationDetail) 298 app.add_directive('deprecated-removed', DeprecatedRemoved) 180 299 app.add_builder(PydocTopicsBuilder) 181 300 app.add_builder(suspicious.CheckSuspiciousMarkupBuilder) 182 301 app.add_description_unit('opcode', 'opcode', '%s (opcode)', 183 302 parse_opcode_signature) 303 app.add_description_unit('pdbcommand', 'pdbcmd', '%s (pdb command)', 304 parse_pdb_command) 184 305 app.add_description_unit('2to3fixer', '2to3fixer', '%s (2to3 fixer)') 306 app.add_directive_to_domain('py', 'decorator', PyDecoratorFunction) 307 app.add_directive_to_domain('py', 'decoratormethod', PyDecoratorMethod)
Note:
See TracChangeset
for help on using the changeset viewer.