# Path: hq/hquery/evaluation_error.py
# class HqueryEvaluationError(RuntimeError):
# 
#     @classmethod
#     def must_be_node_set(cls, obj):
#         if not is_node_set(obj):
#             raise HqueryEvaluationError('Expected a node set, but found a(n) {0}'.format(obj.__class__.__name__))
# 
#     @classmethod
#     def must_be_node_set_or_sequence(cls, obj):
#         if not (is_node_set(obj) or is_sequence(obj)):
#             raise HqueryEvaluationError('Expected a node set or sequence, but found a(n) {0}'.format(
#                 obj.__class__.__name__
#             ))
# 
# Path: hq/hquery/expression_context.py
# def push_context(node, position=1, size=1, preserve_space=None):
#     msg = u'Pushing (node={0}, position={1}, size={2} on context stack.'
#     verbose_print(lambda: msg.format(debug_dump_node(node), position, size))
#     context_stack.append(ExpressionContext(node=node, position=position, size=size, preserve_space=preserve_space))
# 
# def pop_context():
#     result = context_stack.pop()
#     msg = u'Popping (node={0}, position={1}, size={2} off of context stack.'
#     verbose_print(lambda: msg.format(debug_dump_node(result.node), result.position, result.size))
#     return result
# 
# Path: hq/hquery/sequences.py
# def make_node_set(node_set, reverse=False):
#     ids = set()
# 
#     def is_unique_id(node):
#         node_id = id(node)
#         if node_id in ids:
#             return False
#         else:
#             ids.add(node_id)
#             return True
# 
#     if not isinstance(node_set, list):
#         node_set = [node_set]
# 
#     non_node_member = next(filterfalse(is_any_node, node_set), False)
#     if non_node_member:
#         format_str = 'Constructed node set that includes {0} object "{1}"'
#         raise HqueryEvaluationError(format_str.format(object_type_name(non_node_member), non_node_member))
# 
#     node_set = list(sorted(filter(is_unique_id, node_set), key=lambda n: n.hq_doc_index, reverse=reverse))
# 
#     return node_set
# 
# 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 debug_dump_long_string(s, length=50, one_line=True, suffix='...'):
#     return truncate_string(s, length, one_line, suffix)


from hq.hquery.evaluation_error import HqueryEvaluationError
from hq.hquery.expression_context import push_context, pop_context
from hq.hquery.sequences import make_node_set
from hq.soup_util import is_any_node, debug_dump_long_string


def evaluate_across_contexts(node_set, expression_fn):
    HqueryEvaluationError.must_be_node_set(node_set)

    node_set_len = len(node_set)
    ragged = [evaluate_in_context(node, expression_fn, position=index+1, size=node_set_len)
              for index, node in enumerate(node_set)]
    return make_node_set([item for sublist in ragged for item in sublist])


def evaluate_in_context(node, expression_fn, position=1, size=1, preserve_space=None):
    if not is_any_node(node):
        raise HqueryEvaluationError('cannot use {0} "{1}" as context node'.format(type(node),

# Path: hq/hquery/evaluation_error.py
# class HqueryEvaluationError(RuntimeError):
# 
#     @classmethod
#     def must_be_node_set(cls, obj):
#         if not is_node_set(obj):
#             raise HqueryEvaluationError('Expected a node set, but found a(n) {0}'.format(obj.__class__.__name__))
# 
#     @classmethod
#     def must_be_node_set_or_sequence(cls, obj):
#         if not (is_node_set(obj) or is_sequence(obj)):
#             raise HqueryEvaluationError('Expected a node set or sequence, but found a(n) {0}'.format(
#                 obj.__class__.__name__
#             ))
# 
# Path: hq/hquery/expression_context.py
# def push_context(node, position=1, size=1, preserve_space=None):
#     msg = u'Pushing (node={0}, position={1}, size={2} on context stack.'
#     verbose_print(lambda: msg.format(debug_dump_node(node), position, size))
#     context_stack.append(ExpressionContext(node=node, position=position, size=size, preserve_space=preserve_space))
# 
# def pop_context():
#     result = context_stack.pop()
#     msg = u'Popping (node={0}, position={1}, size={2} off of context stack.'
#     verbose_print(lambda: msg.format(debug_dump_node(result.node), result.position, result.size))
#     return result
# 
# Path: hq/hquery/sequences.py
# def make_node_set(node_set, reverse=False):
#     ids = set()
# 
#     def is_unique_id(node):
#         node_id = id(node)
#         if node_id in ids:
#             return False
#         else:
#             ids.add(node_id)
#             return True
# 
#     if not isinstance(node_set, list):
#         node_set = [node_set]
# 
#     non_node_member = next(filterfalse(is_any_node, node_set), False)
#     if non_node_member:
#         format_str = 'Constructed node set that includes {0} object "{1}"'
#         raise HqueryEvaluationError(format_str.format(object_type_name(non_node_member), non_node_member))
# 
#     node_set = list(sorted(filter(is_unique_id, node_set), key=lambda n: n.hq_doc_index, reverse=reverse))
# 
#     return node_set
# 
# 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 debug_dump_long_string(s, length=50, one_line=True, suffix='...'):
#     return truncate_string(s, length, one_line, suffix)


# Path: hq/hquery/evaluation_in_context.py
from hq.hquery.evaluation_error import HqueryEvaluationError
from hq.hquery.expression_context import push_context, pop_context
from hq.hquery.sequences import make_node_set
from hq.soup_util import is_any_node, debug_dump_long_string



def evaluate_across_contexts(node_set, expression_fn):
    HqueryEvaluationError.must_be_node_set(node_set)

    node_set_len = len(node_set)
    ragged = [evaluate_in_context(node, expression_fn, position=index+1, size=node_set_len)
              for index, node in enumerate(node_set)]
    return make_node_set([item for sublist in ragged for item in sublist])


def evaluate_in_context(node, expression_fn, position=1, size=1, preserve_space=None):
    if not is_any_node(node):
        raise HqueryEvaluationError('cannot use {0} "{1}" as context node'.format(type(node),

                                                                                  debug_dump_long_string(str(node))))