diff options
author | wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> | 2006-01-09 20:44:25 +0000 |
---|---|---|
committer | wiemann <wiemann@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> | 2006-01-09 20:44:25 +0000 |
commit | d77fdfef70e08114f57cbef5d91707df8717ea9f (patch) | |
tree | 49444e3486c0c333cb7b33dfa721296c08ee4ece /sandbox/ianb | |
parent | 53cd16ca6ca5f638cbe5956988e88f9339e355cf (diff) | |
parent | 3993c4097756e9885bcfbd07cb1cc1e4e95e50e4 (diff) | |
download | docutils-0.4.tar.gz |
Release 0.4: tagging released revisiondocutils-0.4
git-svn-id: http://svn.code.sf.net/p/docutils/code/tags/docutils-0.4@4268 929543f6-e4f2-0310-98a6-ba3bd3dd1d04
Diffstat (limited to 'sandbox/ianb')
-rw-r--r-- | sandbox/ianb/extractor/default.css | 245 | ||||
-rw-r--r-- | sandbox/ianb/extractor/extractor.py | 336 | ||||
-rw-r--r-- | sandbox/ianb/wiki/Wiki.py | 250 | ||||
-rw-r--r-- | sandbox/ianb/wiki/docs/Wiki.txt | 54 |
4 files changed, 0 insertions, 885 deletions
diff --git a/sandbox/ianb/extractor/default.css b/sandbox/ianb/extractor/default.css deleted file mode 100644 index 05e43aab5..000000000 --- a/sandbox/ianb/extractor/default.css +++ /dev/null @@ -1,245 +0,0 @@ -/* -:Author: David Goodger -:Contact: goodger@users.sourceforge.net -:date: $Date$ -:version: $Revision$ -:copyright: This stylesheet has been placed in the public domain. - -Default cascading style sheet for the HTML output of Docutils. -*/ - -.topic { - margin-left: 5em; -} - -.topic-title { - margin-left: -1em; -} - -body { - background-color: #eeeeee; - font-family: Arial, sans-serif; -} - -em { - font-family: Times New Roman, Times, serif; -} - -li { - list-style-type: circle; -} - -a.target { - color: blue } - -a.toc-backref { - text-decoration: none ; - color: black } - -a:hover { - background-color: #cccccc; -} - -cite { - font-style: normal; - font-family: monospace; - font-weight: bold; -} - -dd { - margin-bottom: 0.5em } - -div.abstract { - margin: 2em 5em } - -div.abstract p.topic-title { - font-weight: bold ; - text-align: center } - -div.attention, div.caution, div.danger, div.error, div.hint, -div.important, div.note, div.tip, div.warning { - // margin: 2em ; - background-color: #cccccc; - align: center; - //width: 60%; - // border: medium outset ; - padding: 3px; - } - -div.attention p.admonition-title, div.caution p.admonition-title, -div.danger p.admonition-title, div.error p.admonition-title, -div.warning p.admonition-title { - color: red ; - font-weight: bold ; - font-family: sans-serif; - text-align: center } - -div.hint p.admonition-title, div.important p.admonition-title, -div.note p.admonition-title, div.tip p.admonition-title { - font-weight: bold ; - font-family: sans-serif; - text-align: center } - -div.dedication { - margin: 2em 5em ; - text-align: center ; - font-style: italic } - -div.dedication p.topic-title { - font-weight: bold ; - font-style: normal } - -div.figure { - margin-left: 2em } - -div.footer, div.header { - font-size: smaller } - -div.system-messages { - margin: 5em } - -div.system-messages h1 { - color: red } - -div.system-message { - border: medium outset ; - padding: 1em } - -div.system-message p.system-message-title { - color: red ; - font-weight: bold } - -div.topic { - margin: 2em } - -h1, h2, h3, h4, h5, h6 { - font-family: Helvetica, Arial, sans-serif; - border: thin solid black; - background-color: #cccccc; - -moz-border-radius: 8px; - padding: 4px; - } - -h1.title { - text-align: center; - background-color: #444499; - color: #eeeeee; - border: medium solid black; - -moz-border-radius: 20px; - } - -h2.subtitle { - text-align: center } - -hr { - width: 75% } - -ol.simple, ul.simple { - margin-bottom: 1em } - -ol.arabic { - list-style: decimal } - -ol.loweralpha { - list-style: lower-alpha } - -ol.upperalpha { - list-style: upper-alpha } - -ol.lowerroman { - list-style: lower-roman } - -ol.upperroman { - list-style: upper-roman } - -p.caption { - font-style: italic } - -p.credits { - font-style: italic ; - font-size: smaller } - -p.first { - margin-top: 0 } - -p.label { - white-space: nowrap } - -p.topic-title { - font-weight: bold } - -pre.address { - margin-bottom: 0 ; - margin-top: 0 ; - font-family: serif ; - font-size: 100% } - -pre.line-block { - font-family: serif ; - font-size: 100% } - -pre.literal-block, pre.doctest-block { - margin-left: 2em ; - margin-right: 2em ; - background-color: #ffffff; - border: thin black solid; - padding: 5px; -} - -span.classifier { - font-family: sans-serif ; - font-style: oblique } - -span.classifier-delimiter { - font-family: sans-serif ; - font-weight: bold } - -span.interpreted { - font-family: sans-serif } - -span.option-argument { - font-style: italic } - -span.pre { - white-space: pre } - -span.problematic { - color: red } - -table { - margin-top: 0.5em ; - margin-bottom: 0.5em } - -table.citation { - border-left: solid thin gray ; - padding-left: 0.5ex } - -table.docinfo { - margin: 2em 4em } - -table.footnote { - border-left: solid thin black ; - padding-left: 0.5ex } - -td, th { - padding-left: 0.5em ; - padding-right: 0.5em ; - vertical-align: top } - -td > p:first-child, th > p:first-child { - margin-top: 0em } - -th.docinfo-name, th.field-name { - font-weight: bold ; - text-align: left ; - white-space: nowrap } - -h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { - font-size: 100% } - -tt { - //background-color: #eeeeee; - color: #000066 } - -ul.auto-toc { - list-style-type: none } diff --git a/sandbox/ianb/extractor/extractor.py b/sandbox/ianb/extractor/extractor.py deleted file mode 100644 index 9411ecf6a..000000000 --- a/sandbox/ianb/extractor/extractor.py +++ /dev/null @@ -1,336 +0,0 @@ -#!/usr/bin/env python -""" -This module extracts the documentation from a module, and converts -it into a single reST document. - -Usage: - ./extractor.py some_module.py > some_module.txt -For more: - ./extractor.py --help - -The document is based on the module's docstring -- no other -documentation is implicitly included. - -Other documentation can be explicitly included by using the directives -``.. inline:: function_or_class`` or ``.. inline-all::``. - -The first directive includes the docstring from that function or -class. When the directive is encountered inside a class, it can refer -either to the global or local namespace, as in ``..inline:: -Document.add_child`` or ``.. inline:: add_child``. - -The second directive will include all children of the module or class, -except those which start with a ``"_"`` (i.e., private), those that -have ``:ignore:`` anywhere in their docstring, or those that have -already been included. - -You can also force a docstring to be ignored by using -``.. ignore:: function_or_class``. This is useful for properties, -whose documentation will not be extracted, or other times when -you want to document the function or class separately from its -docstring. - -TODO ----- - -* Allow docstrings to override the normal function argument - list (e.g., to hide non-public optional arguments). -* Some sort of table of contents support. - -""" - - -import os, re, sys -from docutils.readers.python import moduleparser - -class Document: - - def __init__(self, node, module): - self.node = node - self.parts = [] - self.children = {} - self.module = module - - def add_child(self, child): - self.children[child.name] = child - self.parts.append(child) - - def process(self): - for child in self.node.children: - self.process_node(child) - - def process_node(self, node): - if isinstance(node, moduleparser.Docstring): - self.parts.append(node.text) - elif isinstance(node, moduleparser.Class): - self.add_child(Class(node, self.module)) - elif isinstance(node, moduleparser.Function): - self.add_child(Function(node, self.module)) - - def documentation(self, context=None): - if context is None: - return Document.documentation(self, DocContext()) - newParts = [] - for part in self.parts: - if type(part) is type(""): - doc = self.module.substitute(part, self, context) - newParts.append(doc + "\n") - continue - if part.name.startswith('_') \ - and not part.name.startswith('__'): - continue - if context.seen(part): - continue - doc = part.documentation(context) - if doc.lower().find(':ignore:') != -1: - continue - newParts.append(indent(doc)) - context.setSeen(self) - return '\n'.join(newParts) - -class DocContext: - - def __init__(self): - self.partsSeen = {} - - def seen(self, obj): - return self.partsSeen.has_key(obj) - - def setSeen(self, obj): - self.partsSeen[obj] = 1 - -class Module(Document): - - def __init__(self, filename, text=None): - self.filename = filename - if text is None: - text = open(filename).read() - self.module_text = text - self.name = os.path.splitext(os.path.basename(filename))[0] - node = moduleparser.parse_module(text, filename) - Document.__init__(self, node, self) - self.imports = [] - self.subber = InlineSubstitution(self) - self.process() - - def substitute(self, s, currentNode=None, context=None): - return self.subber.substitute(s, currentNode, context) - - def process_node(self, node): - if isinstance(node, moduleparser.Import): - self.imports.append((node.names, node.from_name)) - else: - Document.process_node(self, node) - - def documentation(self, context=None): - return "%s\n%s\n\n%s" % \ - (self.name, - "=" * len(self.name), - Document.documentation(self, context=None)) - - def importText(self, im): - if im[1]: - return 'from %s import %s' % (im[1], im[0]) - else: - return 'import %s' % im[0] - -class InlineSubstitution: - - def __init__(self, rootNode): - self.rootNode = rootNode - - _inlineRE = re.compile(r'( *).. +inline:: *(.*)') - _inlineAllRE = re.compile(r'( *).. +inline-all:: *') - _ignoreRE = re.compile(r'( *).. ignore:: *(.*)\n?') - - def substitute(self, s, currentNode=None, context=None): - if currentNode is None: - currentNode = self.rootNode - s = self._ignoreRE.sub( - lambda m, cur=currentNode, con=context, : self._ignoreSubber(m, cur, con), - s) - s = self._inlineRE.sub( - lambda m, cur=currentNode, con=context: self._inlineSubber(m, cur, con), - s) - s = self._inlineAllRE.sub( - lambda m, cur=currentNode, con=context: self._inlineAllSubber(m, cur, con), - s) - return s - - def _inlineSubber(self, match, currentNode, context): - level = len(match.group(1)) - name = match.group(2).strip().split('.') - child = self._getChild(name, currentNode) - return indent(self.substitute(child.documentation(context), child), level) - - def _ignoreSubber(self, match, currentNode, context): - name = match.group(2).strip().split('.') - child = self._getChild(name, currentNode) - context.setSeen(child) - return '' - - def _getChild(self, name, currentNode): - nameList = name - obj = currentNode - while 1: - if not nameList: - return obj - if not obj.children.has_key(nameList[0]): - if currentNode is self.rootNode: - raise NameError, '%s not found' % '.'.join(name) - else: - return self._getChild(name, self.rootNode) - obj = obj.children[nameList[0]] - nameList = nameList[1:] - - def _inlineAllSubber(self, match, currentNode, context): - level = len(match.group(1)) - children = currentNode.children.keys() - children.sort() - children = [currentNode.children[name] for name in children] - allDocs = [] - for child in children: - if child.name.startswith('_'): - continue - doc = child.documentation(context) - if doc.lower().find(':ignore:') != -1: - continue - allDocs.append(self.substitute(doc, child)) - return indent('\n'.join(allDocs), level) - - - -class Function(Document): - - def __init__(self, node, module): - Document.__init__(self, node, module) - self.name = node.name - self.parameters = [] - self.process() - - def process_node(self, node): - if isinstance(node, moduleparser.ParameterList): - for parameter in node.children: - self.process_parameter(parameter) - else: - Document.process_node(self, node) - - def process_parameter(self, param): - ## @@: handle defaults, *args, etc. - if param.name == 'self': - return - if param.children: - val = ('default', (param.name, param.children[0].text)) - elif isinstance(param, moduleparser.ExcessPositionalArguments): - val = ('*', param.name) - elif isinstance(param, moduleparser.ExcessKeywordArguments): - val = ('**', param.name) - else: - val = ('normal', param.name) - self.parameters.append(val) - - def documentation(self, context): - d = "`%s(%s)`:\n" % (self.name, - ', '.join([self.parameterText(p) - for p in self.parameters])) - doc = Document.documentation(self, context) - if not doc: - doc = "Not documented." - return d + indent(doc) + "\n" - - def parameterText(self, param): - t, name = param - if t == 'normal': - return name - elif t == 'default': - return '%s=%s' % (name[0], name[1]) - elif t == '*': - return '*%s' % name - elif t == '**': - return '**%s' % name - else: - assert 0 - -class Class(Document): - - def __init__(self, node, module): - Document.__init__(self, node, module) - self.bases = [] - self.name = node.name - for attr, value in node.attlist(): - if attr == 'bases': - self.bases = value - self.process() - - def documentation(self, context): - if self.bases: - base = 'class `%s(%s)`:' % (self.name, self.bases) - else: - base = 'class `%s`:' % self.name - return base + "\n" + indent(Document.documentation(self, context)) - - -def indent(text, amount=4): - return '\n'.join([(' '*amount) + line for line in text.split('\n')]) - -def create_documentation(filename, output): - if type(output) is type(""): - output = open(output, 'w') - mod = Module(filename) - doc = mod.documentation() - if doc.lower().find(':ignore:') == -1: - output.write(mod.documentation()) - -######################################## -## Command-line interface -######################################## - -def main(options, args): - for arg in args: - if os.path.isdir(arg) and options.recurse: - main(options, [os.path.join(arg, f) for f in os.listdir(arg)]) - continue - if options.recurse and not arg.endswith('.py'): - continue - filename = os.path.splitext(arg)[0] + ".txt" - filename = os.path.join(options.output, filename) - filename = os.path.normpath(filename) - if not options.quiet: - sys.stdout.write('%s -> %s ...' % (os.path.normpath(arg), - filename)) - sys.stdout.flush() - create_documentation(arg, filename) - if not options.quiet: - sys.stdout.write('done.\n') - sys.stdout.flush() - -if __name__ == '__main__': - from optparse import OptionParser - parser = OptionParser() - parser.add_option('-r', '--recurse', - action="store_true", - dest="recurse", - default=0, - help="recurse into subdirectories") - parser.add_option('-o', '--output', - dest="output", - help="write documentation to FILE (or directory)", - metavar="FILE") - parser.add_option('-q', '--quiet', - dest="quiet", - default=0, - action="store_true", - help="be quiet") - (options, args) = parser.parse_args() - if len(args) == 1 and options.output \ - and not os.path.isdir(options.output): - if options.output == '-': - options.output = sys.stdout - create_documentation(args[0], options.output) - else: - if not options.output: - options.output = '.' - main(options, args) - - - diff --git a/sandbox/ianb/wiki/Wiki.py b/sandbox/ianb/wiki/Wiki.py deleted file mode 100644 index b7cfb3eef..000000000 --- a/sandbox/ianb/wiki/Wiki.py +++ /dev/null @@ -1,250 +0,0 @@ -""" -The Wiki module primarily exports the `WikiPage` class: -""" - -import os, re, time -from docutils import core, io -from docutils import readers - -__all__ = ['WikiPage', 'allPages', 'recentPages', - 'searchTitles', 'search', 'css'] - -## All the Wiki pages will be kept in this directory: -pageDir = '/usr/home/ianb/w/pypaper/pages/' - -class WikiPage(object): - """ - WikiPage is a class to represent one page in a WikiWikiWeb [#]_. - The page may or may not yet exist -- that is, it may not yet - have content. - - .. [#] http://c2.com/cgi-bin/wiki - - It has the following properties and methods: - - `html`: - A read-only property giving the HTML for the page. - If the page does not yet have content the text - ``"This page has not yet been created"`` is returned. - `text`: - The text for the page. To save new text, simply - assign to this property. - `title`: - The title of the page. - `name`: - The name of the page -- a canonical identifier. - Related to the title, but not necessarily the - same. - .. ignore: html - .. ignore: text - .. ignore: setText - .. ignore: title - - """ - - def __init__(self, pageName): - """ - Each page has a name, which is a unique identifier, for example - ``"FrontPage"``, which identifies the page in the URL and - for linking. - """ - self.name = pageName - - def basePath(self): - """ - :Ignore: yes - Returns the base path (sans extension) for this page - """ - return _basePath(self.name) - - basePath = property(basePath) - - def exists(self): - """Does this page have content yet?""" - return _exists(self.name) - - def html(self): - """Returns text of HTML for page (HTML fragment only)""" - if self.exists(): - html = open(self.basePath + ".html").read() - html = self._subWikiLinks(html) - return html - else: - return 'This page has not yet been created.' - - html = property(html) - - def preview(self, text): - """Returns an HTML preview of the text""" - return self._subWikiLinks(self._convertText(text)) - - _wikiLinkRE = re.compile(r'(<a [^>]* href=")!(.*?)("[^>]*>)(.*?)(</a>)', - re.I+re.S) - - def _subWikiLinks(self, text): - return self._wikiLinkRE.sub(self._subLink, ' %s ' % text) - - def _subLink(self, match): - if _exists(match.group(2)): - return match.group(1) + match.group(2) + match.group(3) + match.group(4) + match.group(5) - else: - return '<span class="nowiki">%s%s%s%s?%s</span>' \ - % (match.group(4), match.group(1), match.group(2), - match.group(3), match.group(5)) - - def text(self): - """ - The text of the page. ReStructuredText is used, though the - parsing is internal to the module. You can assign to this - property to save new text for the page. - """ - if self.exists(): - return open(self.basePath + ".txt").read() - else: - return '' - - def setText(self, text): - """Sets the text for the page (and updates cached HTML at the - same time)""" - f = open(self.basePath + ".txt", 'w') - f.write(text) - f.close() - f = open(self.basePath + ".html", 'w') - f.write(self._convertText(text)) - f.close() - - def _convertText(self, text): - return self._cleanHTML(core.publish_string( - source=text, - reader=Reader(), - parser_name='restructuredtext', - writer_name='html')) - - def _cleanHTML(self, html): - return html[html.find('<body>'):html.find('</body>')] - - text = property(text, setText) - - def searchMatches(self, text): - """ - :Ignore: yes - """ - return self.searchTitleMatches(text) \ - or self.text().lower().find(text.lower()) != -1 - - def searchTitleMatches(self, text): - """ - :Ignore: yes - """ - return self.title().lower().find(text.lower()) != -1 - - def modifiedDate(self): - """Date modified (integer timestamp)""" - return os.stat(self.basePath + ".txt").st_mtime - - modifiedDate = property(modifiedDate) - - def modifiedDateText(self): - """Text representation of modified date""" - return time.strftime("%a %m/%d/%y", time.gmtime(self.modifiedDate())) - - modifiedDateText = property(modifiedDateText) - - def title(self): - """Page title""" - return self.name - - title = property(title) - -""" -Methods for searching the wiki pages: -""" - -def allPages(): - """All pages with content in the system""" - return [WikiPage(page[:-4]) - for page in os.listdir(pageDir) - if page.endswith('.txt')] - -def recentPages(): - """All pages, sorted by date modified, most recent first""" - pages = allPages() - pages.sort(lambda a, b: cmp(b.modifiedDate(), a.modifiedDate())) - return pages - -def searchTitles(text): - """Search page titles for ``text``, returning list of pages""" - return [page for page in allPages() - if page.searchTitleMatches(text)] - -def search(text): - """Search titles and bodies of pages for ``text``, returning list - of pages""" - return [page for page in allPages() - if page.searchMatches(text)] - - -def _basePath(name): - return os.path.join(pageDir, name) - -def _exists(name): - return os.path.exists(_basePath(name) + ".html") - -""" -There is one module global to be printed at the top of -every Wiki page: - - `css`: - The HTML to put the proper CSS at the top of the page. This - should be put in the ``<head>`` section of the page. -""" - -try: - f = open('default.css') -except IOError: - css = "" -else: - css = '<style type="text/css">\n%s</style>\n' % f.read() - f.close() - -######################################## -## reST-specific stuff -######################################## - - -from docutils import nodes -from docutils.readers import standalone -from docutils.transforms import Transform - -class WikiLinkResolver(nodes.SparseNodeVisitor): - ":Ignore: yes" - - def visit_reference(self, node): - if node.resolved or not node.hasattr('refname'): - return - refname = node['refname'] - node.resolved = 1 - node['class'] = 'wiki' - # I put a ! here to distinguish Wiki links from other - # links -- Wiki links have to be fixed up at view time, - # to distinguish between dangling and resolved Wiki - # links. - node['refuri'] = '!' + refname - del node['refname'] - -class WikiLink(Transform): - ":Ignore: yes" - - default_priority = 800 - - def apply(self): - visitor = WikiLinkResolver(self.document) - self.document.walk(visitor) - -class Reader(standalone.Reader): - ":Ignore: yes" - - supported = standalone.Reader.supported + ('wiki',) - - def get_transforms(self): - return standalone.Reader.get_transforms(self) + [WikiLink] diff --git a/sandbox/ianb/wiki/docs/Wiki.txt b/sandbox/ianb/wiki/docs/Wiki.txt deleted file mode 100644 index c63094529..000000000 --- a/sandbox/ianb/wiki/docs/Wiki.txt +++ /dev/null @@ -1,54 +0,0 @@ -Wiki -==== - -The Wiki module primarily exports the `WikiPage` class: - - class `WikiPage(object)`: - WikiPage is a class to represent one page in a WikiWikiWeb [#]_. - The page may or may not yet exist -- that is, it may not yet - have content. - - .. [#] http://c2.com/cgi-bin/wiki - - It has the following properties and methods: - - `html`: - A read-only property giving the HTML for the page. - If the page does not yet have content the text - ``"This page has not yet been created"`` is returned. - `text`: - The text for the page. To save new text, simply - assign to this property. - `title`: - The title of the page. - `name`: - The name of the page -- a canonical identifier. - Related to the title, but not necessarily the - same. - `exists()`: - Does this page have content yet? - `modifiedDate()`: - Date modified (integer timestamp) - `modifiedDateText()`: - Text representation of modified date - `preview(text)`: - Returns an HTML preview of the text - -There are also several searching methods: - - `allPages()`: - All pages with content in the system - `recentPages()`: - All pages, sorted by date modified, most recent first - `search(text)`: - Search titles and bodies of pages for ``text``, returning list - of pages - `searchTitles(text)`: - Search page titles for ``text``, returning list of pages - -There is one module global to be printed at the top of -every Wiki page: - - `css`: - The HTML to put the proper CSS at the top of the page. This - should be put in the ``<head>`` section of the page.
\ No newline at end of file |