Beispiel #1
0
def doc2html(obj, doc):
    """Generate an HTML representation of a docstring"""
    if doc is None or not doc.strip():
        return '<div class="undocumented">Undocumented</div>'
    if not EPYTEXT:
        return boringDocstring(doc)
    errs = []
    pdoc = epytext.parse_docstring(doc, errs)
    if errs:
        errs = []
        def crappit(): pass
        crappit.__doc__ = doc
        doc = inspect.getdoc(crappit)
        pdoc = epytext.parse_docstring(doc, errs)
        if errs:
            if obj.system.options.verbosity > 0:
                print obj
            if obj.system.options.verbosity > 1:
                for i, l in enumerate(doc.splitlines()):
                    print "%4s"%(i+1), l
                for err in errs:
                    print err
            global errcount
            errcount += len(errs)
            return boringDocstring(doc)
    pdoc, fields = pdoc.split_fields()
    crap = pdoc.to_html(_EpydocLinker(obj))
    s = '<div>%s</div>' % (crap,)
    for field in fields:
        s += (('<div class="metadata"><span class="tag">%s</span> '
              '<span class="arg">%s</span>'
              '<span class="body">%s</span></div>')
              % (field.tag(), field.arg(),
                 field.body().to_html(_EpydocLinker(obj))))
    return s
Beispiel #2
0
def doc2html(obj, doc):
    """Generate an HTML representation of a docstring"""
    if doc is None or not doc.strip():
        return '<div class="undocumented">Undocumented</div>'
    if not EPYTEXT:
        return boringDocstring(doc)
    errs = []
    pdoc = epytext.parse_docstring(doc, errs)
    if errs:
        errs = []
        def crappit(): pass
        crappit.__doc__ = doc
        doc = inspect.getdoc(crappit)
        pdoc = epytext.parse_docstring(doc, errs)
        if errs:
            if obj.system.options.verbosity > 0:
                print(obj)
            if obj.system.options.verbosity > 1:
                for i, l in enumerate(doc.splitlines()):
                    print("%4s"%(i+1), l)
                for err in errs:
                    print(err)
            global errcount
            errcount += len(errs)
            return boringDocstring(doc)
    pdoc, fields = pdoc.split_fields()
    crap = pdoc.to_html(_EpydocLinker(obj))
    s = '<div>%s</div>' % (crap,)
    for field in fields:
        s += (('<div class="metadata"><span class="tag">%s</span> '
              '<span class="arg">%s</span>'
              '<span class="body">%s</span></div>')
              % (field.tag(), field.arg(),
                 field.body().to_html(_EpydocLinker(obj))))
    return s
Beispiel #3
0
def doc(obj, docform=2, join_token='\n    '):
    """Return documentation associated with an object.

    If the object does not have any documentation, return the empty string.
    Otherwise return the object documentation, in a form that depends on
    doc form.  If docform==0, the first line (short-form) of the
    documentation is returned.  If docform==1, the body of the
    documentation is returned, without the short-form.  If docform==2, the
    whole documentation is returned (both short-form and body).
    """
    docstr = obj.__doc__
    if docstr is None:
        return ''

    lines = string.split(docstr, '\n')
    if docform == 0:
        lines = [lines[0]]
    elif docform == 1:
        ## Determine a logical starting point that skips blank lines after
        ## the first line of documentation
        #for i in range(1,len(lines)):
        i = 1
        while i < len(lines):
            if lines[i].strip() != "":
                break
            i += 1
        lines = lines[i:]
    elif docform == 2:
        pass
    else:
        raise ValueError, "Argument to 'docform' must be either 0, 1, or 2"

    parsed_lines = []
    for line in lines:
        striped = string.lstrip(line)
        errors = []

        parsed = striped
        try:
            from epydoc.markup import epytext
            parsed = epytext.parse_docstring(striped,
                                             errors).to_plaintext(None)
        except:
            pass

        parsed = string.rstrip(parsed)

        if errors:
            exc = "'%s' contains the following errors\n" % parsed
            for e in errors:
                exc = "%s\n%s" % (exc, str(e))
            raise ValueError(exc)

        parsed_lines.append(parsed)

    as_string = string.join(parsed_lines, join_token)
    return as_string
Beispiel #4
0
def doc(obj, docform = 2, join_token = '\n    '):
    """Return documentation associated with an object.

    If the object does not have any documentation, return the empty string.
    Otherwise return the object documentation, in a form that depends on
    doc form.  If docform==0, the first line (short-form) of the
    documentation is returned.  If docform==1, the body of the
    documentation is returned, without the short-form.  If docform==2, the
    whole documentation is returned (both short-form and body).
    """
    docstr = obj.__doc__    
    if docstr is None:
        return ''

    lines = string.split(docstr, '\n')
    if docform==0:
        lines = [ lines[0] ]
    elif docform==1:
        ## Determine a logical starting point that skips blank lines after
        ## the first line of documentation
        #for i in range(1,len(lines)):
        i= 1
        while i < len(lines):
            if lines[i].strip() != "":
                break
            i+= 1
        lines = lines[i:]
    elif docform==2:
        pass
    else:
        raise ValueError,"Argument to 'docform' must be either 0, 1, or 2"
    
    parsed_lines = []
    for line in lines:
        striped = string.lstrip(line)
        errors  = []

        parsed = striped
        try:
            from epydoc.markup import epytext
            parsed  = epytext.parse_docstring( striped, errors ).to_plaintext(None)
        except:
            pass
        
        parsed  = string.rstrip( parsed )

        if errors:
            exc = "'%s' contains the following errors\n" % parsed
            for e in errors:
                exc = "%s\n%s" % (exc, str(e))
            raise ValueError(exc)
        
        parsed_lines.append( parsed )

    as_string = string.join( parsed_lines, join_token )
    return as_string
Beispiel #5
0
def format_epytext(docstring):
    if six.PY3:
        return u('Epydoc is not compatible with Python 3 interpreter')

    import epydoc.markup.epytext
    from epydoc.markup import DocstringLinker
    from epydoc.markup.epytext import parse_docstring, ParseError, _colorize

    def _add_para(doc, para_token, stack, indent_stack, errors):
        """Colorize the given paragraph, and add it to the DOM tree."""
        para = _colorize(doc, para_token, errors)
        if para_token.inline:
            para.attribs['inline'] = True
        stack[-1].children.append(para)

    epydoc.markup.epytext._add_para = _add_para
    ParseError.is_fatal = lambda self: False

    errors = []

    class EmptyLinker(DocstringLinker):
        def translate_indexterm(self, indexterm):
            return ""

        def translate_identifier_xref(self, identifier, label=None):
            return identifier

    docstring = parse_docstring(docstring, errors)
    docstring, fields = docstring.split_fields()
    html = docstring.to_html(EmptyLinker())

    if errors and not html:
        # It's not possible to recover original stacktraces of the errors
        error_lines = '\n'.join(text_type(e) for e in errors)
        raise Exception('Error parsing docstring. Probable causes:\n' +
                        error_lines)

    return html
def format_epytext(docstring):
    if six.PY3:
        return u('Epydoc is not compatible with Python 3 interpreter')

    import epydoc.markup.epytext
    from epydoc.markup import DocstringLinker
    from epydoc.markup.epytext import parse_docstring, ParseError, _colorize

    def _add_para(doc, para_token, stack, indent_stack, errors):
        """Colorize the given paragraph, and add it to the DOM tree."""
        para = _colorize(doc, para_token, errors)
        if para_token.inline:
            para.attribs['inline'] = True
        stack[-1].children.append(para)

    epydoc.markup.epytext._add_para = _add_para
    ParseError.is_fatal = lambda self: False

    errors = []

    class EmptyLinker(DocstringLinker):
        def translate_indexterm(self, indexterm):
            return ""

        def translate_identifier_xref(self, identifier, label=None):
            return identifier

    docstring = parse_docstring(docstring, errors)
    docstring, fields = docstring.split_fields()
    html = docstring.to_html(EmptyLinker())

    if errors and not html:
        # It's not possible to recover original stacktraces of the errors
        error_lines = '\n'.join(text_type(e) for e in errors)
        raise Exception('Error parsing docstring. Probable causes:\n' + error_lines)

    return html
  return False

ParseError.is_fatal = is_fatal

try:
  src = sys.stdin.read()
  errors = []

  class EmptyLinker(DocstringLinker):
    def translate_indexterm(self, indexterm):
      return ""

    def translate_identifier_xref(self, identifier, label=None):
      return identifier

  docstring = parse_docstring(src, errors)
  docstring, fields = docstring.split_fields()
  html = docstring.to_html(EmptyLinker())

  if errors and not html:
    sys.stderr.write("Error parsing docstring:\n")
    for error in errors:
      sys.stderr.write(str(error) + "\n")
    sys.exit(1)

  sys.stdout.write(html)
  sys.stdout.flush()
except:
  exc_type, exc_value, exc_traceback = sys.exc_info()
  sys.stderr.write("Error calculating docstring: " + str(exc_value))
  sys.exit(1)

ParseError.is_fatal = is_fatal

try:
    src = sys.stdin.read()
    errors = []

    class EmptyLinker(DocstringLinker):
        def translate_indexterm(self, indexterm):
            return ""

        def translate_identifier_xref(self, identifier, label=None):
            return identifier

    docstring = parse_docstring(src, errors)
    docstring, fields = docstring.split_fields()
    html = docstring.to_html(EmptyLinker())

    if errors and not html:
        sys.stderr.write("Error parsing docstring:\n")
        for error in errors:
            sys.stderr.write(str(error) + "\n")
        sys.exit(1)

    sys.stdout.write(html)
    sys.stdout.flush()
except:
    exc_type, exc_value, exc_traceback = sys.exc_info()
    sys.stderr.write("Error calculating docstring: " + str(exc_value))
    sys.exit(1)
Beispiel #9
0
def process_from_epydoc_to_sphinx(fle, imp):

    from epydoc.markup.epytext import parse_docstring

    astinput = ast.parse(imp.encode('utf8'), filename=fle.path)
    docstrings = []

    f = imp.split("\n")

    class Vis(NodeVisitor):
        def visit_FunctionDef(self, node, indent=4):
            if len(node.body) > 0 and isinstance(node.body[0], ast.Expr):
                potential_docstring = node.body[0]
                if isinstance(potential_docstring.value, ast.Str):
                    doc = "\n".join(f[node.lineno : potential_docstring.lineno])
                    doc = doc.split('"""')[1]
                    length = len(doc.split("\n"))

                    if doc[0] != "\n":
                        doc = " " * (node.col_offset + 4) + doc
                        length -= 1
                    if doc[-1] != "\n":
                        length -= 1

                    docstrings.append(
                        {
                            "offset": node.col_offset + indent,
                            "line_no": potential_docstring.lineno - length - 1,
                            "content": dedent(doc).strip(),
                            "length": length + 2,
                        }
                    )

        def visit_ClassDef(self, node):
            self.visit_FunctionDef(node)
            for i in node.body:
                if isinstance(i, (ast.FunctionDef, ast.ClassDef)):
                    self.visit_FunctionDef(i)

        def visit_Module(self, node):
            node.lineno = 0
            node.col_offset = 0
            self.visit_FunctionDef(node, indent=0)
            for i in node.body:
                if isinstance(i, (ast.FunctionDef, ast.ClassDef)):
                    self.visit_FunctionDef(i)

    v = Vis()
    v.visit(astinput)

    for i in docstrings:

        err = []
        parsed = parse_docstring(i["content"], err).split_fields()
        err = [x for x in err if x.is_fatal()]

        if err:
            print("")
            print("Errors, skipping " + fle.path + ":" + str(i["line_no"]))
            print(err)
            i["new_content"] = i["content"]
            continue

        def dump(t):
            resp = []
            if not t._tree.children:
                return ""

            for child in t._tree.children:
                if child.tag == "para":
                    for i in child.children:
                        if isinstance(i, (str, unicode)):
                            resp.append(i)
                            continue

                        if i.tag == "link":
                            resp.append(":py:obj:`" + i.children[0].children[0] + "`")
                            continue

                        if i.tag == "code":
                            resp.append("``%s``" % (i.children[0],))
                            continue

                        if i.tag == "italic":
                            resp.append("*%s*" % (i.children[0],))
                            continue

                        if i.tag == "bold":
                            resp.append("**%s**" % (i.children[0],))
                            continue

                        raise Exception(i.tag)

                    resp.append("\n\n")
                elif child.tag == "literalblock":
                    resp.append(":\n\n   ```\n" + child.children[0] + "\n   ```")

                else:
                    continue
                    raise Exception(child.tag)

            return "".join(resp)

        content = []
        if parsed[0]:
            content.append(dump(parsed[0]))
            content.append("")

        for x in parsed[1]:

            tag = x.tag()

            if tag in ["param", "type", "ivar", "cvar", "var", "see"]:
                content.append(":%s %s: " % (tag, x.arg()) + dump(x.body()))

            elif tag in ["rtype", "since"]:
                content.append(":%s: %s" % (tag, dump(x.body())))

            elif tag in ["raise", "raises"]:
                content.append(":raises %s: %s" % (tag, dump(x.body())))

            # TYPO IN TWISTED
            elif tag in ["params"]:
                content.append(":param %s: %s" % (tag, dump(x.body())))

            # TYPO IN TWISTED
            elif tag in ["types"]:
                content.append(":type %s: " % (tag,) + dump(x.body()))

            # TYPO IN TWISTED
            elif tag in ["arg"]:
                content.append(":param %s: %s" % (tag, dump(x.body())))

            # TYPO IN TWISTED
            elif tag in ["returntype"]:
                content.append(":rtype: %s" % (dump(x.body()),))

            elif tag in ["return", "returns"]:
                content.append(":returns: %s" % (dump(x.body()),))

            elif tag in ["note"]:
                content.append(".. note::")
                content.append("    " + dump(x.body()))

            else:
                print(x.body())
                print(parsed[0])
                raise Exception("Can't parse %s" % (tag,))

        k = StringIO()

        from .docstring_wrap import wrapPythonDocstring

        wrapPythonDocstring(
            "\n".join(content).decode('utf8'),
            k,
            width=79 - i["offset"],
            indentation=u'',
        )

        k.seek(0)
        i["new_content"] = k.read().strip()

    # Process docstrings here...
    last_point = 0

    regions = [[1, 0]]

    finished_file = []

    for i in docstrings:
        line_no = i["line_no"]
        length = i["length"]
        regions[-1][1] = line_no
        regions.append([line_no + length, -1])

    for region, i in zip(regions, docstrings):
        offset = i["offset"]
        new_content = i["new_content"]

        indented = list(
            map(lambda x: " " * offset + x if x else "", new_content.split("\n"))
        )
        indented_quotes = ' ' * offset + '"""'

        ripped = f[region[0] - 1 : region[1]]
        finished_file.extend(ripped)
        finished_file.extend([indented_quotes] + indented + [indented_quotes])

    return finished_file