def _to_plaintext(node, indent=0, base_url=None, colorize=False, extra_offset=None):
    colorize_document = _colorize_document if colorize else lambda x: x
    colorize_error = _colorize_error if colorize else lambda x: x
    colorize_keys = _colorize_keys if colorize else lambda x: x

    if isinstance(node, Document):
        head_indent = '    ' * indent
        body_indent = '    ' * (indent + 1)

        body = '\n'.join([
            body_indent + colorize_keys(str(key) + ': ') +
            _to_plaintext(value, indent + 1, base_url=base_url, colorize=colorize, extra_offset=len(str(key)))
            for key, value in node.data.items()
        ] + [
            body_indent + colorize_keys(str(key) + '(') +
            _fields_to_plaintext(value, colorize=colorize) + colorize_keys(')')
            for key, value in node.links.items()
        ])

        head = colorize_document('<%s %s>' % (
            node.title.strip() or 'Document',
            json.dumps(node.url)
        ))

        return head if (not body) else head + '\n' + body

    elif isinstance(node, Object):
        head_indent = '    ' * indent
        body_indent = '    ' * (indent + 1)

        body = '\n'.join([
            body_indent + colorize_keys(str(key)) + ': ' +
            _to_plaintext(value, indent + 1, base_url=base_url, colorize=colorize, extra_offset=len(str(key)))
            for key, value in node.data.items()
        ] + [
            body_indent + colorize_keys(str(key) + '(') +
            _fields_to_plaintext(value, colorize=colorize) + colorize_keys(')')
            for key, value in node.links.items()
        ])

        return '{}' if (not body) else '{\n' + body + '\n' + head_indent + '}'

    if isinstance(node, Error):
        head_indent = '    ' * indent
        body_indent = '    ' * (indent + 1)

        body = '\n'.join([
            body_indent + colorize_keys(str(key) + ': ') +
            _to_plaintext(value, indent + 1, base_url=base_url, colorize=colorize, extra_offset=len(str(key)))
            for key, value in node.items()
        ])

        head = colorize_error('<Error: %s>' % node.title.strip() if node.title else '<Error>')

        return head if (not body) else head + '\n' + body

    elif isinstance(node, Array):
        head_indent = '    ' * indent
        body_indent = '    ' * (indent + 1)

        body = ',\n'.join([
            body_indent + _to_plaintext(value, indent + 1, base_url=base_url, colorize=colorize)
            for value in node
        ])

        return '[]' if (not body) else '[\n' + body + '\n' + head_indent + ']'

    elif isinstance(node, Link):
        return (
            colorize_keys('link(') +
            _fields_to_plaintext(node, colorize=colorize) +
            colorize_keys(')')
        )

    if isinstance(node, string_types) and (extra_offset is not None) and ('\n' in node):
        # Display newlines in strings gracefully.
        text = json.dumps(node)
        spacing = ('    ' * indent) + (' ' * extra_offset) + '   '
        return text.replace('\\n', '\n' + spacing)

    return json.dumps(node)
dataset/ETHPy150Open core-api/python-client/coreapi/codecs/coretext.py/_to_plaintext/original