# $Id: __init__.py 5618 2008-07-28 08:37:32Z strank $
# Author: David Goodger <goodger@python.org>
# Copyright: This module has been placed in the public domain.

"""
This package contains the Python Source Reader modules.
"""

__docformat__ = 'reStructuredText'


import sys
import docutils.readers
from docutils.readers.python import moduleparser
from docutils import parsers
from docutils import nodes
from docutils.readers.python import pynodes
from docutils import readers

class Reader(docutils.readers.Reader):

    config_section = 'python reader'
    config_section_dependencies = ('readers',)

    default_parser = 'restructuredtext'

    def parse(self):
        """Parse `self.input` into a document tree."""
        self.document = document = self.new_document()
        module_section = moduleparser.parse_module(self.input,
                                                   self.source.source_path)
        module_section.walk(DocformatVisitor(self.document))
        visitor = DocstringFormattingVisitor(
            document=document,
            default_parser=self.default_parser)
        module_section.walk(visitor)
        self.document.append(module_section)


class DocformatVisitor(nodes.SparseNodeVisitor):

    """
    This sets docformat attributes in a module.  Wherever an assignment
    to __docformat__ is found, we look for the enclosing scope -- a class,
    a module, or a function -- and set the docformat attribute there.

    We can't do this during the DocstringFormattingVisitor walking,
    because __docformat__ may appear below a docstring in that format
    (typically below the module docstring).
    """

    def visit_attribute(self, node):
        assert isinstance(node[0], pynodes.object_name)
        name = node[0][0].data
        if name != '__docformat__':
            return
        value = None
        for child in children:
            if isinstance(child, pynodes.expression_value):
                value = child[0].data
                break
        assert value.startswith("'") or value.startswith('"'), "__docformat__ must be assigned a string literal (not %s); line: %s" % (value, node['lineno'])
        name = name[1:-1]
        looking_in = node.parent
        while not isinstance(looking_in, (pynodes.module_section,
                                          pynodes.function_section,
                                          pynodes.class_section)):
            looking_in = looking_in.parent
        looking_in['docformat'] = name


class DocstringFormattingVisitor(nodes.SparseNodeVisitor):

    def __init__(self, document, default_parser):
        self.document = document
        self.default_parser = default_parser
        self.parsers = {}

    def visit_docstring(self, node):
        text = node[0].data
        docformat = self.find_docformat(node)
        del node[0]
        node['docformat'] = docformat
        parser = self.get_parser(docformat)
        parser.parse(text, self.document)
        for child in self.document.children:
            node.append(child)
        self.document.current_source = self.document.current_line = None
        del self.document[:]

    def get_parser(self, parser_name):
        """
        Get a parser based on its name.  We reuse parsers during this
        visitation, so parser instances are cached.
        """
        parser_name = parsers._parser_aliases.get(parser_name, parser_name)
        if parser_name not in self.parsers:
            cls = parsers.get_parser_class(parser_name)
            self.parsers[parser_name] = cls()
        return self.parsers[parser_name]

    def find_docformat(self, node):
        """
        Find the __docformat__ closest to this node (i.e., look in the
        class or module)
        """
        while node:
            if node.get('docformat'):
                return node['docformat']
            node = node.parent
        return self.default_parser


if __name__ == '__main__':
    try:
        import locale
        locale.setlocale(locale.LC_ALL, '')
    except:
        pass

    from docutils.core import publish_cmdline, default_description

    description = ('Generates pseudo-XML from Python modules '
                   '(for testing purposes).  ' + default_description)

    publish_cmdline(description=description,
                    reader=Reader())
