# Path: hq/hquery/expression_context.py
# def peek_context():
#     try:
#         return context_stack[-1]
#     except IndexError:
#         raise ExpressionStackEmptyError('tried to peek while expression stack was empty')
# 
# Path: hq/string_util.py
# def truncate_string(s, length, one_line=True, suffix='...'):
#     if len(s) <= length:
#         result = s
#     else:
#         result = s[:length + 1].rsplit(' ', 1)[0] + suffix
#     if one_line:
#         result = result.replace('\n', '\\n')
#     return result
# 
# def is_a_string(obj):
#     class_name = obj.__class__.__name__
#     return class_name.endswith('str') or class_name.endswith('unicode')
# 
# Path: hq/verbosity.py
# def verbose_print(text, indent_after=False, outdent_before=False):
#     if settings.VERBOSE:
#         if outdent_before:
#             pop_indent()
#         if not is_a_string(text):
#             text = text()
#         print(u'{0}{1}'.format(' ' * indent_level, text), file=sys.stderr)
#         if indent_after:
#             push_indent()
# 
# Path: hq/soup_util.py
# def is_any_node(obj):
#     return is_root_node(obj) or is_tag_node(obj) or is_attribute_node(obj) or is_text_node(obj) or is_comment_node(obj)
# 
# def is_tag_node(obj):
#     return obj.__class__.__name__ == 'Tag'
# 
# def is_text_node(obj):
#     return obj.__class__.__name__ == 'NavigableString'
# 
# def is_attribute_node(obj):
#     return isinstance(obj, AttributeNode)
# 
# def debug_dump_node(obj):
#     if is_root_node(obj):
#         return 'ROOT DOCUMENT'
#     elif is_tag_node(obj):
#         return u'ELEMENT {0}'.format(debug_dump_long_string(str(obj)))
#     elif is_attribute_node(obj):
#         return 'ATTRIBUTE {0}="{1}"'.format(obj.name, debug_dump_long_string(obj.value))
#     elif is_text_node(obj):
#         return u'TEXT "{0}"'.format(debug_dump_long_string(obj.string))
#     elif is_comment_node(obj):
#         return u'COMMENT "{0}"'.format(debug_dump_long_string(obj.string))
#     else:
#         return 'NODE type {0}'.format(obj.__class__.__name__)
# 
# def debug_dump_long_string(s, length=50, one_line=True, suffix='...'):
#     return truncate_string(s, length, one_line, suffix)
# 
# def derive_text_from_node(obj, preserve_space=False):
#     if is_tag_node(obj) or is_root_node(obj):
#         result = u''
#         strings = list(obj.strings)
#         cursor = 0
#         for run in (strings if preserve_space else obj.stripped_strings):
#             if preserve_space:
#                 add_space = False
#             else:
#                 while cursor < len(strings):
#                     if run in strings[cursor]:
#                         break
#                     else:
#                         cursor += 1
#                 if cursor < len(strings):
#                     add_space = strings[cursor][0].isspace() or (cursor > 0 and strings[cursor - 1][-1].isspace())
#                 else:
#                     add_space = False
#             result += u'{0}{1}'.format(' ' if add_space else '', run)
#     elif is_attribute_node(obj):
#         result = obj.value
#     elif is_text_node(obj):
#         result = str(obj)
#     else:
#         raise RuntimeError("don't know how to derive test from {0}".format(debug_dump_node(obj)))
# 
#     if not preserve_space:
#         result = re.sub(u'\u00a0', ' ', result)
#         result = re.sub(r'\s+', ' ', result).strip()
# 
#     return result


import re
from builtins import str
from future.standard_library import install_aliases
from hq.hquery.expression_context import peek_context
from hq.string_util import truncate_string, is_a_string
from ..verbosity import verbose_print
from ..soup_util import is_any_node, is_tag_node, is_text_node, is_attribute_node, debug_dump_node, \
    debug_dump_long_string, derive_text_from_node
    if is_boolean(obj):
        return BOOLEAN
    elif is_node_set(obj):
        return SEQUENCE
    elif is_sequence(obj):
        return SEQUENCE
    elif is_number(obj):
        return NUMBER
    elif is_string(obj):
        return STRING
    else:
        verbose_print('UH-OH! Returning None from object_type({0})'.format(obj.__class__.__name__))
        return None


def object_type_name(obj):
    result = 'NULL OR UNKNOWN TYPE'

    if obj is not None:
        if isinstance(obj, int):
            index = obj
        else:
            index = object_type(obj)
        result = TYPE_NAMES[index]

    return result


def string_value(obj):
    if is_tag_node(obj) or is_attribute_node(obj) or is_text_node(obj):

# Path: hq/hquery/expression_context.py
# def peek_context():
#     try:
#         return context_stack[-1]
#     except IndexError:
#         raise ExpressionStackEmptyError('tried to peek while expression stack was empty')
# 
# Path: hq/string_util.py
# def truncate_string(s, length, one_line=True, suffix='...'):
#     if len(s) <= length:
#         result = s
#     else:
#         result = s[:length + 1].rsplit(' ', 1)[0] + suffix
#     if one_line:
#         result = result.replace('\n', '\\n')
#     return result
# 
# def is_a_string(obj):
#     class_name = obj.__class__.__name__
#     return class_name.endswith('str') or class_name.endswith('unicode')
# 
# Path: hq/verbosity.py
# def verbose_print(text, indent_after=False, outdent_before=False):
#     if settings.VERBOSE:
#         if outdent_before:
#             pop_indent()
#         if not is_a_string(text):
#             text = text()
#         print(u'{0}{1}'.format(' ' * indent_level, text), file=sys.stderr)
#         if indent_after:
#             push_indent()
# 
# Path: hq/soup_util.py
# def is_any_node(obj):
#     return is_root_node(obj) or is_tag_node(obj) or is_attribute_node(obj) or is_text_node(obj) or is_comment_node(obj)
# 
# def is_tag_node(obj):
#     return obj.__class__.__name__ == 'Tag'
# 
# def is_text_node(obj):
#     return obj.__class__.__name__ == 'NavigableString'
# 
# def is_attribute_node(obj):
#     return isinstance(obj, AttributeNode)
# 
# def debug_dump_node(obj):
#     if is_root_node(obj):
#         return 'ROOT DOCUMENT'
#     elif is_tag_node(obj):
#         return u'ELEMENT {0}'.format(debug_dump_long_string(str(obj)))
#     elif is_attribute_node(obj):
#         return 'ATTRIBUTE {0}="{1}"'.format(obj.name, debug_dump_long_string(obj.value))
#     elif is_text_node(obj):
#         return u'TEXT "{0}"'.format(debug_dump_long_string(obj.string))
#     elif is_comment_node(obj):
#         return u'COMMENT "{0}"'.format(debug_dump_long_string(obj.string))
#     else:
#         return 'NODE type {0}'.format(obj.__class__.__name__)
# 
# def debug_dump_long_string(s, length=50, one_line=True, suffix='...'):
#     return truncate_string(s, length, one_line, suffix)
# 
# def derive_text_from_node(obj, preserve_space=False):
#     if is_tag_node(obj) or is_root_node(obj):
#         result = u''
#         strings = list(obj.strings)
#         cursor = 0
#         for run in (strings if preserve_space else obj.stripped_strings):
#             if preserve_space:
#                 add_space = False
#             else:
#                 while cursor < len(strings):
#                     if run in strings[cursor]:
#                         break
#                     else:
#                         cursor += 1
#                 if cursor < len(strings):
#                     add_space = strings[cursor][0].isspace() or (cursor > 0 and strings[cursor - 1][-1].isspace())
#                 else:
#                     add_space = False
#             result += u'{0}{1}'.format(' ' if add_space else '', run)
#     elif is_attribute_node(obj):
#         result = obj.value
#     elif is_text_node(obj):
#         result = str(obj)
#     else:
#         raise RuntimeError("don't know how to derive test from {0}".format(debug_dump_node(obj)))
# 
#     if not preserve_space:
#         result = re.sub(u'\u00a0', ' ', result)
#         result = re.sub(r'\s+', ' ', result).strip()
# 
#     return result


# Path: hq/hquery/object_type.py
import re
from builtins import str
from future.standard_library import install_aliases
from hq.hquery.expression_context import peek_context
from hq.string_util import truncate_string, is_a_string
from ..verbosity import verbose_print
from ..soup_util import is_any_node, is_tag_node, is_text_node, is_attribute_node, debug_dump_node, \
    debug_dump_long_string, derive_text_from_node

    if is_boolean(obj):
        return BOOLEAN
    elif is_node_set(obj):
        return SEQUENCE
    elif is_sequence(obj):
        return SEQUENCE
    elif is_number(obj):
        return NUMBER
    elif is_string(obj):
        return STRING
    else:
        verbose_print('UH-OH! Returning None from object_type({0})'.format(obj.__class__.__name__))
        return None


def object_type_name(obj):
    result = 'NULL OR UNKNOWN TYPE'

    if obj is not None:
        if isinstance(obj, int):
            index = obj
        else:
            index = object_type(obj)
        result = TYPE_NAMES[index]

    return result


def string_value(obj):
    if is_tag_node(obj) or is_attribute_node(obj) or is_text_node(obj):

        return derive_text_from_node(obj, peek_context().preserve_space)