/Doc/tools/sphinxext/pyspecific.py

http://unladen-swallow.googlecode.com/ · Python · 137 lines · 94 code · 26 blank · 17 comment · 9 complexity · 7e6212487d26dd98dd04e325731b1d0c MD5 · raw file

  1. # -*- coding: utf-8 -*-
  2. """
  3. pyspecific.py
  4. ~~~~~~~~~~~~~
  5. Sphinx extension with Python doc-specific markup.
  6. :copyright: 2008, 2009 by Georg Brandl.
  7. :license: Python license.
  8. """
  9. ISSUE_URI = 'http://bugs.python.org/issue%s'
  10. from docutils import nodes, utils
  11. # monkey-patch reST parser to disable alphabetic and roman enumerated lists
  12. from docutils.parsers.rst.states import Body
  13. Body.enum.converters['loweralpha'] = \
  14. Body.enum.converters['upperalpha'] = \
  15. Body.enum.converters['lowerroman'] = \
  16. Body.enum.converters['upperroman'] = lambda x: None
  17. def issue_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):
  18. issue = utils.unescape(text)
  19. text = 'issue ' + issue
  20. refnode = nodes.reference(text, text, refuri=ISSUE_URI % issue)
  21. return [refnode], []
  22. # Support for building "topic help" for pydoc
  23. pydoc_topic_labels = [
  24. 'assert', 'assignment', 'atom-identifiers', 'atom-literals',
  25. 'attribute-access', 'attribute-references', 'augassign', 'binary',
  26. 'bitwise', 'bltin-code-objects', 'bltin-ellipsis-object',
  27. 'bltin-file-objects', 'bltin-null-object', 'bltin-type-objects', 'booleans',
  28. 'break', 'callable-types', 'calls', 'class', 'coercion-rules',
  29. 'comparisons', 'compound', 'context-managers', 'continue', 'conversions',
  30. 'customization', 'debugger', 'del', 'dict', 'dynamic-features', 'else',
  31. 'exceptions', 'exec', 'execmodel', 'exprlists', 'floating', 'for',
  32. 'formatstrings', 'function', 'global', 'id-classes', 'identifiers', 'if',
  33. 'imaginary', 'import', 'in', 'integers', 'lambda', 'lists', 'naming',
  34. 'numbers', 'numeric-types', 'objects', 'operator-summary', 'pass', 'power',
  35. 'print', 'raise', 'return', 'sequence-methods', 'sequence-types',
  36. 'shifting', 'slicings', 'specialattrs', 'specialnames',
  37. 'string-conversions', 'string-methods', 'strings', 'subscriptions', 'truth',
  38. 'try', 'types', 'typesfunctions', 'typesmapping', 'typesmethods',
  39. 'typesmodules', 'typesseq', 'typesseq-mutable', 'unary', 'while', 'with',
  40. 'yield'
  41. ]
  42. from os import path
  43. from time import asctime
  44. from pprint import pformat
  45. from docutils.io import StringOutput
  46. from docutils.utils import new_document
  47. try:
  48. from sphinx.builders import Builder
  49. except ImportError:
  50. # using Sphinx < 0.6, which has a different package layout
  51. from sphinx.builder import Builder
  52. # monkey-patch toctree directive to accept (and ignore) the :numbered: flag
  53. from sphinx.directives.other import toctree_directive
  54. toctree_directive.options['numbered'] = toctree_directive.options['glob']
  55. try:
  56. from sphinx.writers.text import TextWriter
  57. except ImportError:
  58. from sphinx.textwriter import TextWriter
  59. class PydocTopicsBuilder(Builder):
  60. name = 'pydoc-topics'
  61. def init(self):
  62. self.topics = {}
  63. def get_outdated_docs(self):
  64. return 'all pydoc topics'
  65. def get_target_uri(self, docname, typ=None):
  66. return '' # no URIs
  67. def write(self, *ignored):
  68. writer = TextWriter(self)
  69. for label in self.status_iterator(pydoc_topic_labels, 'building topics... '):
  70. if label not in self.env.labels:
  71. self.warn('label %r not in documentation' % label)
  72. continue
  73. docname, labelid, sectname = self.env.labels[label]
  74. doctree = self.env.get_and_resolve_doctree(docname, self)
  75. document = new_document('<section node>')
  76. document.append(doctree.ids[labelid])
  77. destination = StringOutput(encoding='utf-8')
  78. writer.write(document, destination)
  79. self.topics[label] = writer.output
  80. def finish(self):
  81. f = open(path.join(self.outdir, 'pydoc_topics.py'), 'w')
  82. try:
  83. f.write('# Autogenerated by Sphinx on %s\n' % asctime())
  84. f.write('topics = ' + pformat(self.topics) + '\n')
  85. finally:
  86. f.close()
  87. # Support for checking for suspicious markup
  88. import suspicious
  89. # Support for documenting Opcodes
  90. import re
  91. from sphinx import addnodes
  92. opcode_sig_re = re.compile(r'(\w+(?:\+\d)?)\s*\((.*)\)')
  93. def parse_opcode_signature(env, sig, signode):
  94. """Transform an opcode signature into RST nodes."""
  95. m = opcode_sig_re.match(sig)
  96. if m is None:
  97. raise ValueError
  98. opname, arglist = m.groups()
  99. signode += addnodes.desc_name(opname, opname)
  100. paramlist = addnodes.desc_parameterlist()
  101. signode += paramlist
  102. paramlist += addnodes.desc_parameter(arglist, arglist)
  103. return opname.strip()
  104. def setup(app):
  105. app.add_role('issue', issue_role)
  106. app.add_builder(PydocTopicsBuilder)
  107. app.add_builder(suspicious.CheckSuspiciousMarkupBuilder)
  108. app.add_description_unit('opcode', 'opcode', '%s (opcode)',
  109. parse_opcode_signature)