"""Compiler tools with improved interactive support.

Provides compilation machinery similar to codeop, but with caching support so
we can provide interactive tracebacks.

Authors
-------
* Robert Kern
* Fernando Perez
* Thomas Kluyver
"""

# Note: though it might be more natural to name this module 'compiler', that
# name is in the stdlib and name collisions with the stdlib tend to produce
# weird problems (often with third-party tools).

#-----------------------------------------------------------------------------
#  Copyright (C) 2010-2011 The IPython Development Team.
#
#  Distributed under the terms of the BSD License.
#
#  The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
from __future__ import print_function

# Stdlib imports
from ast import PyCF_ONLY_AST
import codeop
import hashlib
import linecache
import time

#-----------------------------------------------------------------------------
# Local utilities
#-----------------------------------------------------------------------------

def code_name(code, number=0):
    """ Compute a (probably) unique name for code for caching.

    This now expects code to be unicode.
    """
    hash_digest = hashlib.md5(code.encode("utf-8")).hexdigest()
    # Include the number and 12 characters of the hash in the name.  It's
    # pretty much impossible that in a single session we'll have collisions
    # even with truncated hashes, and the full one makes tracebacks too long
    return '<ipython-input-{0}-{1}>'.format(number, hash_digest[:12])

#-----------------------------------------------------------------------------
# Classes and functions
#-----------------------------------------------------------------------------

class CachingCompiler(codeop.Compile):
    """A compiler that caches code compiled from interactive statements.
    """

    def __init__(self):
        codeop.Compile.__init__(self)

        # This is ugly, but it must be done this way to allow multiple
        # simultaneous ipython instances to coexist.  Since Python itself
        # directly accesses the data structures in the linecache module, and
        # the cache therein is global, we must work with that data structure.
        # We must hold a reference to the original checkcache routine and call
        # that in our own check_cache() below, but the special IPython cache
        # must also be shared by all IPython instances.  If we were to hold
        # separate caches (one in each CachingCompiler instance), any call made
        # by Python itself to linecache.checkcache() would obliterate the
        # cached data from the other IPython instances.
        if not hasattr(linecache, '_ipython_cache'):
            linecache._ipython_cache = {}
        if not hasattr(linecache, '_checkcache_ori'):
            linecache._checkcache_ori = linecache.checkcache
        # Now, we must monkeypatch the linecache directly so that parts of the
        # stdlib that call it outside our control go through our codepath
        # (otherwise we'd lose our tracebacks).
        linecache.checkcache = self.check_cache

    def ast_parse(self, source, filename='<unknown>', symbol='exec'):
        """Parse code to an AST with the current compiler flags active.

        Arguments are exactly the same as ast.parse (in the standard library),
        and are passed to the built-in compile function."""
        return compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1)

    def reset_compiler_flags(self):
        """Reset compiler flags to default state."""
        # This value is copied from codeop.Compile.__init__, so if that ever
        # changes, it will need to be updated.
        self.flags = codeop.PyCF_DONT_IMPLY_DEDENT

    @property
    def compiler_flags(self):
        """Flags currently active in the compilation process.
        """
        return self.flags

    def cache(self, code, number=0):
        """Make a name for a block of code, and cache the code.

        Parameters
        ----------
        code : str
          The Python source code to cache.
        number : int
          A number which forms part of the code's name. Used for the execution
          counter.

        Returns
        -------
        The name of the cached code (as a string). Pass this as the filename
        argument to compilation, so that tracebacks are correctly hooked up.
        """
        name = code_name(code, number)
        entry = (len(code), time.time(),
                 [line+'\n' for line in code.splitlines()], name)
        linecache.cache[name] = entry
        linecache._ipython_cache[name] = entry
        return name

    def check_cache(self, *args):
        """Call linecache.checkcache() safely protecting our cached values.
        """
        # First call the orignal checkcache as intended
        linecache._checkcache_ori(*args)
        # Then, update back the cache with our data, so that tracebacks related
        # to our compiled codes can be produced.
        linecache.cache.update(linecache._ipython_cache)


"""A simple Python template renderer, for a nano-subset of Django syntax."""

# Coincidentally named the same as http://code.activestate.com/recipes/496702/

import re

from coverage.backward import set                       # pylint: disable=W0622

class CodeBuilder(object):
    """Build source code conveniently."""

    def __init__(self, indent=0):
        self.code = []
        self.indent_amount = indent

    def add_line(self, line):
        """Add a line of source to the code.

        Don't include indentations or newlines.

        """
        self.code.append(" " * self.indent_amount)
        self.code.append(line)
        self.code.append("\n")

    def add_section(self):
        """Add a section, a sub-CodeBuilder."""
        sect = CodeBuilder(self.indent_amount)
        self.code.append(sect)
        return sect

    def indent(self):
        """Increase the current indent for following lines."""
        self.indent_amount += 4

    def dedent(self):
        """Decrease the current indent for following lines."""
        self.indent_amount -= 4

    def __str__(self):
        return "".join([str(c) for c in self.code])

    def get_function(self, fn_name):
        """Compile the code, and return the function `fn_name`."""
        assert self.indent_amount == 0
        g = {}
        code_text = str(self)
        exec(code_text, g)
        return g[fn_name]

class Templite(object):
    """A simple template renderer, for a nano-subset of Django syntax.

    Supported constructs are extended variable access::

        {{var.modifer.modifier|filter|filter}}

    loops::

        {% for var in list %}...{% endfor %}

    and ifs::

        {% if var %}...{% endif %}

    Comments are within curly-hash markers::

        {# This will be ignored #}

    Construct a Templite with the template text, then use `render` against a
    dictionary context to create a finished string.

    """
    def __init__(self, text, *contexts):
        """Construct a Templite with the given `text`.

        `contexts` are dictionaries of values to use for future renderings.
        These are good for filters and global values.

        """
        self.text = text
        self.context = {}
        for context in contexts:
            self.context.update(context)

        # We construct a function in source form, then compile it and hold onto
        # it, and execute it to render the template.
        code = CodeBuilder()

        code.add_line("def render(ctx, dot):")
        code.indent()
        vars_code = code.add_section()
        self.all_vars = set()
        self.loop_vars = set()
        code.add_line("result = []")
        code.add_line("a = result.append")
        code.add_line("e = result.extend")
        code.add_line("s = str")

        buffered = []
        def flush_output():
            """Force `buffered` to the code builder."""
            if len(buffered) == 1:
                code.add_line("a(%s)" % buffered[0])
            elif len(buffered) > 1:
                code.add_line("e([%s])" % ",".join(buffered))
            del buffered[:]

        # Split the text to form a list of tokens.
        toks = re.split(r"(?s)({{.*?}}|{%.*?%}|{#.*?#})", text)

        ops_stack = []
        for tok in toks:
            if tok.startswith('{{'):
                # An expression to evaluate.
                buffered.append("s(%s)" % self.expr_code(tok[2:-2].strip()))
            elif tok.startswith('{#'):
                # Comment: ignore it and move on.
                continue
            elif tok.startswith('{%'):
                # Action tag: split into words and parse further.
                flush_output()
                words = tok[2:-2].strip().split()
                if words[0] == 'if':
                    # An if statement: evaluate the expression to determine if.
                    assert len(words) == 2
                    ops_stack.append('if')
                    code.add_line("if %s:" % self.expr_code(words[1]))
                    code.indent()
                elif words[0] == 'for':
                    # A loop: iterate over expression result.
                    assert len(words) == 4 and words[2] == 'in'
                    ops_stack.append('for')
                    self.loop_vars.add(words[1])
                    code.add_line(
                        "for c_%s in %s:" % (
                            words[1],
                            self.expr_code(words[3])
                        )
                    )
                    code.indent()
                elif words[0].startswith('end'):
                    # Endsomething.  Pop the ops stack
                    end_what = words[0][3:]
                    if ops_stack[-1] != end_what:
                        raise SyntaxError("Mismatched end tag: %r" % end_what)
                    ops_stack.pop()
                    code.dedent()
                else:
                    raise SyntaxError("Don't understand tag: %r" % words[0])
            else:
                # Literal content.  If it isn't empty, output it.
                if tok:
                    buffered.append("%r" % tok)
        flush_output()

        for var_name in self.all_vars - self.loop_vars:
            vars_code.add_line("c_%s = ctx[%r]" % (var_name, var_name))

        if ops_stack:
            raise SyntaxError("Unmatched action tag: %r" % ops_stack[-1])

        code.add_line("return ''.join(result)")
        code.dedent()
        self.render_function = code.get_function('render')

    def expr_code(self, expr):
        """Generate a Python expression for `expr`."""
        if "|" in expr:
            pipes = expr.split("|")
            code = self.expr_code(pipes[0])
            for func in pipes[1:]:
                self.all_vars.add(func)
                code = "c_%s(%s)" % (func, code)
        elif "." in expr:
            dots = expr.split(".")
            code = self.expr_code(dots[0])
            args = [repr(d) for d in dots[1:]]
            code = "dot(%s, %s)" % (code, ", ".join(args))
        else:
            self.all_vars.add(expr)
            code = "c_%s" % expr
        return code

    def render(self, context=None):
        """Render this template by applying it to `context`.

        `context` is a dictionary of values to use in this rendering.

        """
        # Make the complete context we'll use.
        ctx = dict(self.context)
        if context:
            ctx.update(context)
        return self.render_function(ctx, self.do_dots)

    def do_dots(self, value, *dots):
        """Evaluate dotted expressions at runtime."""
        for dot in dots:
            try:
                value = getattr(value, dot)
            except AttributeError:
                value = value[dot]
            if hasattr(value, '__call__'):
                value = value()
        return value


from __future__ import unicode_literals

from django import template

def render_template(tpl, context):
    '''
    A shortcut function to render a partial template with context and return
    the output.
    '''

    templates = [tpl] if type(tpl) != list else tpl
    tpl_instance = None

    for tpl in templates:
        try:
            tpl_instance = template.loader.get_template(tpl)
            break
        except template.TemplateDoesNotExist:
            pass

    if not tpl_instance:
        raise Exception('Template does not exist: ' + templates[-1])

    return tpl_instance.render(template.Context(context))


# -*- coding: utf-8 -*-
"""Display formatters.

Authors:

* Robert Kern
* Brian Granger
"""
#-----------------------------------------------------------------------------
# Copyright (C) 2010-2011, IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

# Stdlib imports
import abc
import sys
# We must use StringIO, as cStringIO doesn't handle unicode properly.
from StringIO import StringIO

# Our own imports
from IPython.config.configurable import Configurable
from IPython.lib import pretty
from IPython.utils.traitlets import Bool, Dict, Integer, Unicode, CUnicode, ObjectName
from IPython.utils.py3compat import unicode_to_str

#-----------------------------------------------------------------------------
# The main DisplayFormatter class
#-----------------------------------------------------------------------------

class DisplayFormatter(Configurable):

    # When set to true only the default plain text formatter will be used.
    plain_text_only = Bool(False, config=True)

    # A dict of formatter whose keys are format types (MIME types) and whose
    # values are subclasses of BaseFormatter.
    formatters = Dict()
    def _formatters_default(self):
        """Activate the default formatters."""
        formatter_classes = [
            PlainTextFormatter,
            HTMLFormatter,
            SVGFormatter,
            PNGFormatter,
            JPEGFormatter,
            LatexFormatter,
            JSONFormatter,
            JavascriptFormatter
        ]
        d = {}
        for cls in formatter_classes:
            f = cls(config=self.config)
            d[f.format_type] = f
        return d

    def format(self, obj, include=None, exclude=None):
        """Return a format data dict for an object.

        By default all format types will be computed.

        The following MIME types are currently implemented:

        * text/plain
        * text/html
        * text/latex
        * application/json
        * application/javascript
        * image/png
        * image/jpeg
        * image/svg+xml

        Parameters
        ----------
        obj : object
            The Python object whose format data will be computed.
        include : list or tuple, optional
            A list of format type strings (MIME types) to include in the
            format data dict. If this is set *only* the format types included
            in this list will be computed.
        exclude : list or tuple, optional
            A list of format type string (MIME types) to exclue in the format
            data dict. If this is set all format types will be computed,
            except for those included in this argument.

        Returns
        -------
        format_dict : dict
            A dictionary of key/value pairs, one or each format that was
            generated for the object. The keys are the format types, which
            will usually be MIME type strings and the values and JSON'able
            data structure containing the raw data for the representation in
            that format.
        """
        format_dict = {}

        # If plain text only is active
        if self.plain_text_only:
            formatter = self.formatters['text/plain']
            try:
                data = formatter(obj)
            except:
                # FIXME: log the exception
                raise
            if data is not None:
                format_dict['text/plain'] = data
            return format_dict

        for format_type, formatter in self.formatters.items():
            if include is not None:
                if format_type not in include:
                    continue
            if exclude is not None:
                if format_type in exclude:
                    continue
            try:
                data = formatter(obj)
            except:
                # FIXME: log the exception
                raise
            if data is not None:
                format_dict[format_type] = data
        return format_dict

    @property
    def format_types(self):
        """Return the format types (MIME types) of the active formatters."""
        return self.formatters.keys()

#-----------------------------------------------------------------------------
# Formatters for specific format types (text, html, svg, etc.)
#-----------------------------------------------------------------------------

class FormatterABC(object):
    """ Abstract base class for Formatters.

    A formatter is a callable class that is responsible for computing the
    raw format data for a particular format type (MIME type). For example,
    an HTML formatter would have a format type of `text/html` and would return
    the HTML representation of the object when called.
    """
    __metaclass__ = abc.ABCMeta

    # The format type of the data returned, usually a MIME type.
    format_type = 'text/plain'

    # Is the formatter enabled...
    enabled = True

    @abc.abstractmethod
    def __call__(self, obj):
        """Return a JSON'able representation of the object.

        If the object cannot be formatted by this formatter, then return None
        """
        try:
            return repr(obj)
        except TypeError:
            return None

class BaseFormatter(Configurable):
    """A base formatter class that is configurable.

    This formatter should usually be used as the base class of all formatters.
    It is a traited :class:`Configurable` class and includes an extensible
    API for users to determine how their objects are formatted. The following
    logic is used to find a function to format an given object.

    1. The object is introspected to see if it has a method with the name
       :attr:`print_method`. If is does, that object is passed to that method
       for formatting.
    2. If no print method is found, three internal dictionaries are consulted
       to find print method: :attr:`singleton_printers`, :attr:`type_printers`
       and :attr:`deferred_printers`.

    Users should use these dictionaries to register functions that will be
    used to compute the format data for their objects (if those objects don't
    have the special print methods). The easiest way of using these
    dictionaries is through the :meth:`for_type` and :meth:`for_type_by_name`
    methods.

    If no function/callable is found to compute the format data, ``None`` is
    returned and this format type is not used.
    """

    format_type = Unicode('text/plain')

    enabled = Bool(True, config=True)

    print_method = ObjectName('__repr__')

    # The singleton printers.
    # Maps the IDs of the builtin singleton objects to the format functions.
    singleton_printers = Dict(config=True)
    def _singleton_printers_default(self):
        return {}

    # The type-specific printers.
    # Map type objects to the format functions.
    type_printers = Dict(config=True)
    def _type_printers_default(self):
        return {}

    # The deferred-import type-specific printers.
    # Map (modulename, classname) pairs to the format functions.
    deferred_printers = Dict(config=True)
    def _deferred_printers_default(self):
        return {}

    def __call__(self, obj):
        """Compute the format for an object."""
        if self.enabled:
            obj_id = id(obj)
            try:
                obj_class = getattr(obj, '__class__', None) or type(obj)
                # First try to find registered singleton printers for the type.
                try:
                    printer = self.singleton_printers[obj_id]
                except (TypeError, KeyError):
                    pass
                else:
                    return printer(obj)
                # Next look for type_printers.
                for cls in pretty._get_mro(obj_class):
                    if cls in self.type_printers:
                        return self.type_printers[cls](obj)
                    else:
                        printer = self._in_deferred_types(cls)
                        if printer is not None:
                            return printer(obj)
                # Finally look for special method names.
                if hasattr(obj_class, self.print_method):
                    printer = getattr(obj_class, self.print_method)
                    return printer(obj)
                return None
            except Exception:
                pass
        else:
            return None

    def for_type(self, typ, func):
        """Add a format function for a given type.

        Parameters
        -----------
        typ : class
            The class of the object that will be formatted using `func`.
        func : callable
            The callable that will be called to compute the format data. The
            call signature of this function is simple, it must take the
            object to be formatted and return the raw data for the given
            format. Subclasses may use a different call signature for the
            `func` argument.
        """
        oldfunc = self.type_printers.get(typ, None)
        if func is not None:
            # To support easy restoration of old printers, we need to ignore
            # Nones.
            self.type_printers[typ] = func
        return oldfunc

    def for_type_by_name(self, type_module, type_name, func):
        """Add a format function for a type specified by the full dotted
        module and name of the type, rather than the type of the object.

        Parameters
        ----------
        type_module : str
            The full dotted name of the module the type is defined in, like
            ``numpy``.
        type_name : str
            The name of the type (the class name), like ``dtype``
        func : callable
            The callable that will be called to compute the format data. The
            call signature of this function is simple, it must take the
            object to be formatted and return the raw data for the given
            format. Subclasses may use a different call signature for the
            `func` argument.
        """
        key = (type_module, type_name)
        oldfunc = self.deferred_printers.get(key, None)
        if func is not None:
            # To support easy restoration of old printers, we need to ignore
            # Nones.
            self.deferred_printers[key] = func
        return oldfunc

    def _in_deferred_types(self, cls):
        """
        Check if the given class is specified in the deferred type registry.

        Returns the printer from the registry if it exists, and None if the
        class is not in the registry. Successful matches will be moved to the
        regular type registry for future use.
        """
        mod = getattr(cls, '__module__', None)
        name = getattr(cls, '__name__', None)
        key = (mod, name)
        printer = None
        if key in self.deferred_printers:
            # Move the printer over to the regular registry.
            printer = self.deferred_printers.pop(key)
            self.type_printers[cls] = printer
        return printer

class PlainTextFormatter(BaseFormatter):
    """The default pretty-printer.

    This uses :mod:`IPython.lib.pretty` to compute the format data of
    the object. If the object cannot be pretty printed, :func:`repr` is used.
    See the documentation of :mod:`IPython.lib.pretty` for details on
    how to write pretty printers.  Here is a simple example::

        def dtype_pprinter(obj, p, cycle):
            if cycle:
                return p.text('dtype(...)')
            if hasattr(obj, 'fields'):
                if obj.fields is None:
                    p.text(repr(obj))
                else:
                    p.begin_group(7, 'dtype([')
                    for i, field in enumerate(obj.descr):
                        if i > 0:
                            p.text(',')
                            p.breakable()
                        p.pretty(field)
                    p.end_group(7, '])')
    """

    # The format type of data returned.
    format_type = Unicode('text/plain')

    # This subclass ignores this attribute as it always need to return
    # something.
    enabled = Bool(True, config=False)

    # Look for a _repr_pretty_ methods to use for pretty printing.
    print_method = ObjectName('_repr_pretty_')

    # Whether to pretty-print or not.
    pprint = Bool(True, config=True)

    # Whether to be verbose or not.
    verbose = Bool(False, config=True)

    # The maximum width.
    max_width = Integer(79, config=True)

    # The newline character.
    newline = Unicode('\n', config=True)

    # format-string for pprinting floats
    float_format = Unicode('%r')
    # setter for float precision, either int or direct format-string
    float_precision = CUnicode('', config=True)

    def _float_precision_changed(self, name, old, new):
        """float_precision changed, set float_format accordingly.

        float_precision can be set by int or str.
        This will set float_format, after interpreting input.
        If numpy has been imported, numpy print precision will also be set.

        integer `n` sets format to '%.nf', otherwise, format set directly.

        An empty string returns to defaults (repr for float, 8 for numpy).

        This parameter can be set via the '%precision' magic.
        """

        if '%' in new:
            # got explicit format string
            fmt = new
            try:
                fmt%3.14159
            except Exception:
                raise ValueError("Precision must be int or format string, not %r"%new)
        elif new:
            # otherwise, should be an int
            try:
                i = int(new)
                assert i >= 0
            except ValueError:
                raise ValueError("Precision must be int or format string, not %r"%new)
            except AssertionError:
                raise ValueError("int precision must be non-negative, not %r"%i)

            fmt = '%%.%if'%i
            if 'numpy' in sys.modules:
                # set numpy precision if it has been imported
                import numpy
                numpy.set_printoptions(precision=i)
        else:
            # default back to repr
            fmt = '%r'
            if 'numpy' in sys.modules:
                import numpy
                # numpy default is 8
                numpy.set_printoptions(precision=8)
        self.float_format = fmt

    # Use the default pretty printers from IPython.lib.pretty.
    def _singleton_printers_default(self):
        return pretty._singleton_pprinters.copy()

    def _type_printers_default(self):
        d = pretty._type_pprinters.copy()
        d[float] = lambda obj,p,cycle: p.text(self.float_format%obj)
        return d

    def _deferred_printers_default(self):
        return pretty._deferred_type_pprinters.copy()

    #### FormatterABC interface ####

    def __call__(self, obj):
        """Compute the pretty representation of the object."""
        if not self.pprint:
            try:
                return repr(obj)
            except TypeError:
                return ''
        else:
            # This uses use StringIO, as cStringIO doesn't handle unicode.
            stream = StringIO()
            # self.newline.encode() is a quick fix for issue gh-597. We need to
            # ensure that stream does not get a mix of unicode and bytestrings,
            # or it will cause trouble.
            printer = pretty.RepresentationPrinter(stream, self.verbose,
                self.max_width, unicode_to_str(self.newline),
                singleton_pprinters=self.singleton_printers,
                type_pprinters=self.type_printers,
                deferred_pprinters=self.deferred_printers)
            printer.pretty(obj)
            printer.flush()
            return stream.getvalue()

class HTMLFormatter(BaseFormatter):
    """An HTML formatter.

    To define the callables that compute the HTML representation of your
    objects, define a :meth:`_repr_html_` method or use the :meth:`for_type`
    or :meth:`for_type_by_name` methods to register functions that handle
    this.

    The return value of this formatter should be a valid HTML snippet that
    could be injected into an existing DOM. It should *not* include the
    ```<html>`` or ```<body>`` tags.
    """
    format_type = Unicode('text/html')

    print_method = ObjectName('_repr_html_')

class SVGFormatter(BaseFormatter):
    """An SVG formatter.

    To define the callables that compute the SVG representation of your
    objects, define a :meth:`_repr_svg_` method or use the :meth:`for_type`
    or :meth:`for_type_by_name` methods to register functions that handle
    this.

    The return value of this formatter should be valid SVG enclosed in
    ```<svg>``` tags, that could be injected into an existing DOM. It should
    *not* include the ```<html>`` or ```<body>`` tags.
    """
    format_type = Unicode('image/svg+xml')

    print_method = ObjectName('_repr_svg_')

class PNGFormatter(BaseFormatter):
    """A PNG formatter.

    To define the callables that compute the PNG representation of your
    objects, define a :meth:`_repr_png_` method or use the :meth:`for_type`
    or :meth:`for_type_by_name` methods to register functions that handle
    this.

    The return value of this formatter should be raw PNG data, *not*
    base64 encoded.
    """
    format_type = Unicode('image/png')

    print_method = ObjectName('_repr_png_')

class JPEGFormatter(BaseFormatter):
    """A JPEG formatter.

    To define the callables that compute the JPEG representation of your
    objects, define a :meth:`_repr_jpeg_` method or use the :meth:`for_type`
    or :meth:`for_type_by_name` methods to register functions that handle
    this.

    The return value of this formatter should be raw JPEG data, *not*
    base64 encoded.
    """
    format_type = Unicode('image/jpeg')

    print_method = ObjectName('_repr_jpeg_')

class LatexFormatter(BaseFormatter):
    """A LaTeX formatter.

    To define the callables that compute the LaTeX representation of your
    objects, define a :meth:`_repr_latex_` method or use the :meth:`for_type`
    or :meth:`for_type_by_name` methods to register functions that handle
    this.

    The return value of this formatter should be a valid LaTeX equation,
    enclosed in either ```$```, ```$$``` or another LaTeX equation
    environment.
    """
    format_type = Unicode('text/latex')

    print_method = ObjectName('_repr_latex_')

class JSONFormatter(BaseFormatter):
    """A JSON string formatter.

    To define the callables that compute the JSON string representation of
    your objects, define a :meth:`_repr_json_` method or use the :meth:`for_type`
    or :meth:`for_type_by_name` methods to register functions that handle
    this.

    The return value of this formatter should be a valid JSON string.
    """
    format_type = Unicode('application/json')

    print_method = ObjectName('_repr_json_')

class JavascriptFormatter(BaseFormatter):
    """A Javascript formatter.

    To define the callables that compute the Javascript representation of
    your objects, define a :meth:`_repr_javascript_` method or use the
    :meth:`for_type` or :meth:`for_type_by_name` methods to register functions
    that handle this.

    The return value of this formatter should be valid Javascript code and
    should *not* be enclosed in ```<script>``` tags.
    """
    format_type = Unicode('application/javascript')

    print_method = ObjectName('_repr_javascript_')

FormatterABC.register(BaseFormatter)
FormatterABC.register(PlainTextFormatter)
FormatterABC.register(HTMLFormatter)
FormatterABC.register(SVGFormatter)
FormatterABC.register(PNGFormatter)
FormatterABC.register(JPEGFormatter)
FormatterABC.register(LatexFormatter)
FormatterABC.register(JSONFormatter)
FormatterABC.register(JavascriptFormatter)

def format_display_data(obj, include=None, exclude=None):
    """Return a format data dict for an object.

    By default all format types will be computed.

    The following MIME types are currently implemented:

    * text/plain
    * text/html
    * text/latex
    * application/json
    * application/javascript
    * image/png
    * image/jpeg
    * image/svg+xml

    Parameters
    ----------
    obj : object
        The Python object whose format data will be computed.

    Returns
    -------
    format_dict : dict
        A dictionary of key/value pairs, one or each format that was
        generated for the object. The keys are the format types, which
        will usually be MIME type strings and the values and JSON'able
        data structure containing the raw data for the representation in
        that format.
    include : list or tuple, optional
        A list of format type strings (MIME types) to include in the
        format data dict. If this is set *only* the format types included
        in this list will be computed.
    exclude : list or tuple, optional
        A list of format type string (MIME types) to exclue in the format
        data dict. If this is set all format types will be computed,
        except for those included in this argument.
    """
    from IPython.core.interactiveshell import InteractiveShell

    InteractiveShell.instance().display_formatter.format(
        obj,
        include,
        exclude
    )


import logging
import optparse
import os
import re
import sys
import ConfigParser
from optparse import OptionParser
from nose.util import absdir, tolist
from nose.plugins.manager import NoPlugins
from warnings import warn

log = logging.getLogger(__name__)

# not allowed in config files
option_blacklist = ['help', 'verbose']

config_files = [
    # Linux users will prefer this
    "~/.noserc",
    # Windows users will prefer this
    "~/nose.cfg"
    ]

# plaforms on which the exe check defaults to off
# Windows and IronPython
exe_allowed_platforms = ('win32', 'cli')

class NoSuchOptionError(Exception):
    def __init__(self, name):
        Exception.__init__(self, name)
        self.name = name

class ConfigError(Exception):
    pass

class ConfiguredDefaultsOptionParser(object):
    """
    Handler for options from commandline and config files.
    """
    def __init__(self, parser, config_section, error=None, file_error=None):
        self._parser = parser
        self._config_section = config_section
        if error is None:
            error = self._parser.error
        self._error = error
        if file_error is None:
            file_error = lambda msg, **kw: error(msg)
        self._file_error = file_error

    def _configTuples(self, cfg, filename):
        config = []
        if self._config_section in cfg.sections():
            for name, value in cfg.items(self._config_section):
                config.append((name, value, filename))
        return config

    def _readFromFilenames(self, filenames):
        config = []
        for filename in filenames:
            cfg = ConfigParser.RawConfigParser()
            try:
                cfg.read(filename)
            except ConfigParser.Error, exc:
                raise ConfigError("Error reading config file %r: %s" %
                                  (filename, str(exc)))
            config.extend(self._configTuples(cfg, filename))
        return config

    def _readFromFileObject(self, fh):
        cfg = ConfigParser.RawConfigParser()
        try:
            filename = fh.name
        except AttributeError:
            filename = '<???>'
        try:
            cfg.readfp(fh)
        except ConfigParser.Error, exc:
            raise ConfigError("Error reading config file %r: %s" %
                              (filename, str(exc)))
        return self._configTuples(cfg, filename)

    def _readConfiguration(self, config_files):
        try:
            config_files.readline
        except AttributeError:
            filename_or_filenames = config_files
            if isinstance(filename_or_filenames, basestring):
                filenames = [filename_or_filenames]
            else:
                filenames = filename_or_filenames
            config = self._readFromFilenames(filenames)
        else:
            fh = config_files
            config = self._readFromFileObject(fh)
        return config

    def _processConfigValue(self, name, value, values, parser):
        opt_str = '--' + name
        option = parser.get_option(opt_str)
        if option is None:
            raise NoSuchOptionError(name)
        else:
            option.process(opt_str, value, values, parser)

    def _applyConfigurationToValues(self, parser, config, values):
        for name, value, filename in config:
            if name in option_blacklist:
                continue
            try:
                self._processConfigValue(name, value, values, parser)
            except NoSuchOptionError, exc:
                self._file_error(
                    "Error reading config file %r: "
                    "no such option %r" % (filename, exc.name),
                    name=name, filename=filename)
            except optparse.OptionValueError, exc:
                msg = str(exc).replace('--' + name, repr(name), 1)
                self._file_error("Error reading config file %r: "
                                 "%s" % (filename, msg),
                                 name=name, filename=filename)

    def parseArgsAndConfigFiles(self, args, config_files):
        values = self._parser.get_default_values()
        try:
            config = self._readConfiguration(config_files)
        except ConfigError, exc:
            self._error(str(exc))
        else:
            self._applyConfigurationToValues(self._parser, config, values)
        return self._parser.parse_args(args, values)

class Config(object):
    """nose configuration.

    Instances of Config are used throughout nose to configure
    behavior, including plugin lists. Here are the default values for
    all config keys::

      self.env = env = kw.pop('env', {})
      self.args = ()
      self.testMatch = re.compile(r'(?:^|[\\b_\\.%s-])[Tt]est' % os.sep)
      self.addPaths = not env.get('NOSE_NOPATH', False)
      self.configSection = 'nosetests'
      self.debug = env.get('NOSE_DEBUG')
      self.debugLog = env.get('NOSE_DEBUG_LOG')
      self.exclude = None
      self.getTestCaseNamesCompat = False
      self.includeExe = env.get('NOSE_INCLUDE_EXE',
                                sys.platform in exe_allowed_platforms)
      self.ignoreFiles = (re.compile(r'^\.'),
                          re.compile(r'^_'),
                          re.compile(r'^setup\.py$')
                          )
      self.include = None
      self.loggingConfig = None
      self.logStream = sys.stderr
      self.options = NoOptions()
      self.parser = None
      self.plugins = NoPlugins()
      self.srcDirs = ('lib', 'src')
      self.runOnInit = True
      self.stopOnError = env.get('NOSE_STOP', False)
      self.stream = sys.stderr
      self.testNames = ()
      self.verbosity = int(env.get('NOSE_VERBOSE', 1))
      self.where = ()
      self.py3where = ()
      self.workingDir = None
    """

    def __init__(self, **kw):
        self.env = env = kw.pop('env', {})
        self.args = ()
        self.testMatchPat = env.get('NOSE_TESTMATCH',
                                    r'(?:^|[\b_\.%s-])[Tt]est' % os.sep)
        self.testMatch = re.compile(self.testMatchPat)
        self.addPaths = not env.get('NOSE_NOPATH', False)
        self.configSection = 'nosetests'
        self.debug = env.get('NOSE_DEBUG')
        self.debugLog = env.get('NOSE_DEBUG_LOG')
        self.exclude = None
        self.getTestCaseNamesCompat = False
        self.includeExe = env.get('NOSE_INCLUDE_EXE',
                                  sys.platform in exe_allowed_platforms)
        self.ignoreFilesDefaultStrings = [r'^\.',
                                          r'^_',
                                          r'^setup\.py$',
                                          ]
        self.ignoreFiles = map(re.compile, self.ignoreFilesDefaultStrings)
        self.include = None
        self.loggingConfig = None
        self.logStream = sys.stderr
        self.options = NoOptions()
        self.parser = None
        self.plugins = NoPlugins()
        self.srcDirs = ('lib', 'src')
        self.runOnInit = True
        self.stopOnError = env.get('NOSE_STOP', False)
        self.stream = sys.stderr
        self.testNames = []
        self.verbosity = int(env.get('NOSE_VERBOSE', 1))
        self.where = ()
        self.py3where = ()
        self.workingDir = os.getcwd()
        self.traverseNamespace = False
        self.firstPackageWins = False
        self.parserClass = OptionParser
        self.worker = False

        self._default = self.__dict__.copy()
        self.update(kw)
        self._orig = self.__dict__.copy()

    def __getstate__(self):
        state = self.__dict__.copy()
        del state['stream']
        del state['_orig']
        del state['_default']
        del state['env']
        del state['logStream']
        # FIXME remove plugins, have only plugin manager class
        state['plugins'] = self.plugins.__class__
        return state

    def __setstate__(self, state):
        plugincls = state.pop('plugins')
        self.update(state)
        self.worker = True
        # FIXME won't work for static plugin lists
        self.plugins = plugincls()
        self.plugins.loadPlugins()
        # needed so .can_configure gets set appropriately
        dummy_parser = self.parserClass()
        self.plugins.addOptions(dummy_parser, {})
        self.plugins.configure(self.options, self)

    def __repr__(self):
        d = self.__dict__.copy()
        # don't expose env, could include sensitive info
        d['env'] = {}
        keys = [ k for k in d.keys()
                 if not k.startswith('_') ]
        keys.sort()
        return "Config(%s)" % ', '.join([ '%s=%r' % (k, d[k])
                                          for k in keys ])
    __str__ = __repr__

    def _parseArgs(self, argv, cfg_files):
        def warn_sometimes(msg, name=None, filename=None):
            if (hasattr(self.plugins, 'excludedOption') and
                self.plugins.excludedOption(name)):
                msg = ("Option %r in config file %r ignored: "
                       "excluded by runtime environment" %
                       (name, filename))
                warn(msg, RuntimeWarning)
            else:
                raise ConfigError(msg)
        parser = ConfiguredDefaultsOptionParser(
            self.getParser(), self.configSection, file_error=warn_sometimes)
        return parser.parseArgsAndConfigFiles(argv[1:], cfg_files)

    def configure(self, argv=None, doc=None):
        """Configure the nose running environment. Execute configure before
        collecting tests with nose.TestCollector to enable output capture and
        other features.
        """
        env = self.env
        if argv is None:
            argv = sys.argv

        cfg_files = getattr(self, 'files', [])
        options, args = self._parseArgs(argv, cfg_files)
        # If -c --config has been specified on command line,
        # load those config files and reparse
        if getattr(options, 'files', []):
            options, args = self._parseArgs(argv, options.files)

        self.options = options
        if args:
            self.testNames = args
        if options.testNames is not None:
            self.testNames.extend(tolist(options.testNames))

        if options.py3where is not None:
            if sys.version_info >= (3,):
                options.where = options.py3where

        # `where` is an append action, so it can't have a default value
        # in the parser, or that default will always be in the list
        if not options.where:
            options.where = env.get('NOSE_WHERE', None)

        # include and exclude also
        if not options.ignoreFiles:
            options.ignoreFiles = env.get('NOSE_IGNORE_FILES', [])
        if not options.include:
            options.include = env.get('NOSE_INCLUDE', [])
        if not options.exclude:
            options.exclude = env.get('NOSE_EXCLUDE', [])

        self.addPaths = options.addPaths
        self.stopOnError = options.stopOnError
        self.verbosity = options.verbosity
        self.includeExe = options.includeExe
        self.traverseNamespace = options.traverseNamespace
        self.debug = options.debug
        self.debugLog = options.debugLog
        self.loggingConfig = options.loggingConfig
        self.firstPackageWins = options.firstPackageWins
        self.configureLogging()

        if options.where is not None:
            self.configureWhere(options.where)

        if options.testMatch:
            self.testMatch = re.compile(options.testMatch)

        if options.ignoreFiles:
            self.ignoreFiles = map(re.compile, tolist(options.ignoreFiles))
            log.info("Ignoring files matching %s", options.ignoreFiles)
        else:
            log.info("Ignoring files matching %s", self.ignoreFilesDefaultStrings)

        if options.include:
            self.include = map(re.compile, tolist(options.include))
            log.info("Including tests matching %s", options.include)

        if options.exclude:
            self.exclude = map(re.compile, tolist(options.exclude))
            log.info("Excluding tests matching %s", options.exclude)

        # When listing plugins we don't want to run them
        if not options.showPlugins:
            self.plugins.configure(options, self)
            self.plugins.begin()

    def configureLogging(self):
        """Configure logging for nose, or optionally other packages. Any logger
        name may be set with the debug option, and that logger will be set to
        debug level and be assigned the same handler as the nose loggers, unless
        it already has a handler.
        """
        if self.loggingConfig:
            from logging.config import fileConfig
            fileConfig(self.loggingConfig)
            return

        format = logging.Formatter('%(name)s: %(levelname)s: %(message)s')
        if self.debugLog:
            handler = logging.FileHandler(self.debugLog)
        else:
            handler = logging.StreamHandler(self.logStream)
        handler.setFormatter(format)

        logger = logging.getLogger('nose')
        logger.propagate = 0

        # only add our default handler if there isn't already one there
        # this avoids annoying duplicate log messages.
        if handler not in logger.handlers:
            logger.addHandler(handler)

        # default level
        lvl = logging.WARNING
        if self.verbosity >= 5:
            lvl = 0
        elif self.verbosity >= 4:
            lvl = logging.DEBUG
        elif self.verbosity >= 3:
            lvl = logging.INFO
        logger.setLevel(lvl)

        # individual overrides
        if self.debug:
            # no blanks
            debug_loggers = [ name for name in self.debug.split(',')
                              if name ]
            for logger_name in debug_loggers:
                l = logging.getLogger(logger_name)
                l.setLevel(logging.DEBUG)
                if not l.handlers and not logger_name.startswith('nose'):
                    l.addHandler(handler)

    def configureWhere(self, where):
        """Configure the working directory or directories for the test run.
        """
        from nose.importer import add_path
        self.workingDir = None
        where = tolist(where)
        warned = False
        for path in where:
            if not self.workingDir:
                abs_path = absdir(path)
                if abs_path is None:
                    raise ValueError("Working directory %s not found, or "
                                     "not a directory" % path)
                log.info("Set working dir to %s", abs_path)
                self.workingDir = abs_path
                if self.addPaths and \
                       os.path.exists(os.path.join(abs_path, '__init__.py')):
                    log.info("Working directory %s is a package; "
                             "adding to sys.path" % abs_path)
                    add_path(abs_path)
                continue
            if not warned:
                warn("Use of multiple -w arguments is deprecated and "
                     "support may be removed in a future release. You can "
                     "get the same behavior by passing directories without "
                     "the -w argument on the command line, or by using the "
                     "--tests argument in a configuration file.",
                     DeprecationWarning)
            self.testNames.append(path)

    def default(self):
        """Reset all config values to defaults.
        """
        self.__dict__.update(self._default)

    def getParser(self, doc=None):
        """Get the command line option parser.
        """
        if self.parser:
            return self.parser
        env = self.env
        parser = self.parserClass(doc)
        parser.add_option(
            "-V","--version", action="store_true",
            dest="version", default=False,
            help="Output nose version and exit")
        parser.add_option(
            "-p", "--plugins", action="store_true",
            dest="showPlugins", default=False,
            help="Output list of available plugins and exit. Combine with "
            "higher verbosity for greater detail")
        parser.add_option(
            "-v", "--verbose",
            action="count", dest="verbosity",
            default=self.verbosity,
            help="Be more verbose. [NOSE_VERBOSE]")
        parser.add_option(
            "--verbosity", action="store", dest="verbosity",
            metavar='VERBOSITY',
            type="int", help="Set verbosity; --verbosity=2 is "
            "the same as -v")
        parser.add_option(
            "-q", "--quiet", action="store_const", const=0, dest="verbosity",
            help="Be less verbose")
        parser.add_option(
            "-c", "--config", action="append", dest="files",
            metavar="FILES",
            help="Load configuration from config file(s). May be specified "
            "multiple times; in that case, all config files will be "
            "loaded and combined")
        parser.add_option(
            "-w", "--where", action="append", dest="where",
            metavar="WHERE",
            help="Look for tests in this directory. "
            "May be specified multiple times. The first directory passed "
            "will be used as the working directory, in place of the current "
            "working directory, which is the default. Others will be added "
            "to the list of tests to execute. [NOSE_WHERE]"
            )
        parser.add_option(
            "--py3where", action="append", dest="py3where",
            metavar="PY3WHERE",
            help="Look for tests in this directory under Python 3.x. "
            "Functions the same as 'where', but only applies if running under "
            "Python 3.x or above.  Note that, if present under 3.x, this "
            "option completely replaces any directories specified with "
            "'where', so the 'where' option becomes ineffective. "
            "[NOSE_PY3WHERE]"
            )
        parser.add_option(
            "-m", "--match", "--testmatch", action="store",
            dest="testMatch", metavar="REGEX",
            help="Files, directories, function names, and class names "
            "that match this regular expression are considered tests.  "
            "Default: %s [NOSE_TESTMATCH]" % self.testMatchPat,
            default=self.testMatchPat)
        parser.add_option(
            "--tests", action="store", dest="testNames", default=None,
            metavar='NAMES',
            help="Run these tests (comma-separated list). This argument is "
            "useful mainly from configuration files; on the command line, "
            "just pass the tests to run as additional arguments with no "
            "switch.")
        parser.add_option(
            "-l", "--debug", action="store",
            dest="debug", default=self.debug,
            help="Activate debug logging for one or more systems. "
            "Available debug loggers: nose, nose.importer, "
            "nose.inspector, nose.plugins, nose.result and "
            "nose.selector. Separate multiple names with a comma.")
        parser.add_option(
            "--debug-log", dest="debugLog", action="store",
            default=self.debugLog, metavar="FILE",
            help="Log debug messages to this file "
            "(default: sys.stderr)")
        parser.add_option(
            "--logging-config", "--log-config",
            dest="loggingConfig", action="store",
            default=self.loggingConfig, metavar="FILE",
            help="Load logging config from this file -- bypasses all other"
            " logging config settings.")
        parser.add_option(
            "-I", "--ignore-files", action="append", dest="ignoreFiles",
            metavar="REGEX",
            help="Completely ignore any file that matches this regular "
            "expression. Takes precedence over any other settings or "
            "plugins. "
            "Specifying this option will replace the default setting. "
            "Specify this option multiple times "
            "to add more regular expressions [NOSE_IGNORE_FILES]")
        parser.add_option(
            "-e", "--exclude", action="append", dest="exclude",
            metavar="REGEX",
            help="Don't run tests that match regular "
            "expression [NOSE_EXCLUDE]")
        parser.add_option(
            "-i", "--include", action="append", dest="include",
            metavar="REGEX",
            help="This regular expression will be applied to files, "
            "directories, function names, and class names for a chance "
            "to include additional tests that do not match TESTMATCH.  "
            "Specify this option multiple times "
            "to add more regular expressions [NOSE_INCLUDE]")
        parser.add_option(
            "-x", "--stop", action="store_true", dest="stopOnError",
            default=self.stopOnError,
            help="Stop running tests after the first error or failure")
        parser.add_option(
            "-P", "--no-path-adjustment", action="store_false",
            dest="addPaths",
            default=self.addPaths,
            help="Don't make any changes to sys.path when "
            "loading tests [NOSE_NOPATH]")
        parser.add_option(
            "--exe", action="store_true", dest="includeExe",
            default=self.includeExe,
            help="Look for tests in python modules that are "
            "executable. Normal behavior is to exclude executable "
            "modules, since they may not be import-safe "
            "[NOSE_INCLUDE_EXE]")
        parser.add_option(
            "--noexe", action="store_false", dest="includeExe",
            help="DO NOT look for tests in python modules that are "
            "executable. (The default on the windows platform is to "
            "do so.)")
        parser.add_option(
            "--traverse-namespace", action="store_true",
            default=self.traverseNamespace, dest="traverseNamespace",
            help="Traverse through all path entries of a namespace package")
        parser.add_option(
            "--first-package-wins", "--first-pkg-wins", "--1st-pkg-wins",
            action="store_true", default=False, dest="firstPackageWins",
            help="nose's importer will normally evict a package from sys."
            "modules if it sees a package with the same name in a different "
            "location. Set this option to disable that behavior.")

        self.plugins.loadPlugins()
        self.pluginOpts(parser)

        self.parser = parser
        return parser

    def help(self, doc=None):
        """Return the generated help message
        """
        return self.getParser(doc).format_help()

    def pluginOpts(self, parser):
        self.plugins.addOptions(parser, self.env)

    def reset(self):
        self.__dict__.update(self._orig)

    def todict(self):
        return self.__dict__.copy()

    def update(self, d):
        self.__dict__.update(d)

class NoOptions(object):
    """Options container that returns None for all options.
    """
    def __getstate__(self):
        return {}

    def __setstate__(self, state):
        pass

    def __getnewargs__(self):
        return ()

    def __getattr__(self, attr):
        return None

    def __nonzero__(self):
        return False

def user_config_files():
    """Return path to any existing user config files
    """
    return filter(os.path.exists,
                  map(os.path.expanduser, config_files))

def all_config_files():
    """Return path to any existing user config files, plus any setup.cfg
    in the current working directory.
    """
    user = user_config_files()
    if os.path.exists('setup.cfg'):
        return user + ['setup.cfg']
    return user

# used when parsing config files
def flag(val):
    """Does the value look like an on/off flag?"""
    if val == 1:
        return True
    elif val == 0:
        return False
    val = str(val)
    if len(val) > 5:
        return False
    return val.upper() in ('1', '0', 'F', 'T', 'TRUE', 'FALSE', 'ON', 'OFF')

def _bool(val):
    return str(val).upper() in ('1', 'T', 'TRUE', 'ON')


# encoding: utf-8
"""
Paging capabilities for IPython.core

Authors:

* Brian Granger
* Fernando Perez

Notes
-----

For now this uses ipapi, so it can't be in IPython.utils.  If we can get
rid of that dependency, we could move it there.
-----
"""

#-----------------------------------------------------------------------------
#  Copyright (C) 2008-2011  The IPython Development Team
#
#  Distributed under the terms of the BSD License.  The full license is in
#  the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

import os
import re
import sys
import tempfile

from io import UnsupportedOperation

from IPython.core import ipapi
from IPython.core.error import TryNext
from IPython.utils.cursesimport import use_curses
from IPython.utils.data import chop
from IPython.utils import io
from IPython.utils.process import system
from IPython.utils.terminal import get_terminal_size

#-----------------------------------------------------------------------------
# Classes and functions
#-----------------------------------------------------------------------------

esc_re = re.compile(r"(\x1b[^m]+m)")

def page_dumb(strng, start=0, screen_lines=25):
    """Very dumb 'pager' in Python, for when nothing else works.

    Only moves forward, same interface as page(), except for pager_cmd and
    mode."""

    out_ln  = strng.splitlines()[start:]
    screens = chop(out_ln,screen_lines-1)
    if len(screens) == 1:
        print >>io.stdout, os.linesep.join(screens[0])
    else:
        last_escape = ""
        for scr in screens[0:-1]:
            hunk = os.linesep.join(scr)
            print >>io.stdout, last_escape + hunk
            if not page_more():
                return
            esc_list = esc_re.findall(hunk)
            if len(esc_list) > 0:
                last_escape = esc_list[-1]
        print >>io.stdout, last_escape + os.linesep.join(screens[-1])

def _detect_screen_size(use_curses, screen_lines_def):
    """Attempt to work out the number of lines on the screen.

    This is called by page(). It can raise an error (e.g. when run in the
    test suite), so it's separated out so it can easily be called in a try block.
    """
    TERM = os.environ.get('TERM',None)
    if (TERM=='xterm' or TERM=='xterm-color') and sys.platform != 'sunos5':
        local_use_curses = use_curses
    else:
        # curses causes problems on many terminals other than xterm, and
        # some termios calls lock up on Sun OS5.
        local_use_curses = False
    if local_use_curses:
        import termios
        import curses
        # There is a bug in curses, where *sometimes* it fails to properly
        # initialize, and then after the endwin() call is made, the
        # terminal is left in an unusable state.  Rather than trying to
        # check everytime for this (by requesting and comparing termios
        # flags each time), we just save the initial terminal state and
        # unconditionally reset it every time.  It's cheaper than making
        # the checks.
        term_flags = termios.tcgetattr(sys.stdout)

        # Curses modifies the stdout buffer size by default, which messes
        # up Python's normal stdout buffering.  This would manifest itself
        # to IPython users as delayed printing on stdout after having used
        # the pager.
        #
        # We can prevent this by manually setting the NCURSES_NO_SETBUF
        # environment variable.  For more details, see:
        # http://bugs.python.org/issue10144
        NCURSES_NO_SETBUF = os.environ.get('NCURSES_NO_SETBUF', None)
        os.environ['NCURSES_NO_SETBUF'] = ''

        # Proceed with curses initialization
        scr = curses.initscr()
        screen_lines_real,screen_cols = scr.getmaxyx()
        curses.endwin()

        # Restore environment
        if NCURSES_NO_SETBUF is None:
            del os.environ['NCURSES_NO_SETBUF']
        else:
            os.environ['NCURSES_NO_SETBUF'] = NCURSES_NO_SETBUF

        # Restore terminal state in case endwin() didn't.
        termios.tcsetattr(sys.stdout,termios.TCSANOW,term_flags)
        # Now we have what we needed: the screen size in rows/columns
        return screen_lines_real
        #print '***Screen size:',screen_lines_real,'lines x',\
        #screen_cols,'columns.' # dbg
    else:
        return screen_lines_def

def page(strng, start=0, screen_lines=0, pager_cmd=None):
    """Print a string, piping through a pager after a certain length.

    The screen_lines parameter specifies the number of *usable* lines of your
    terminal screen (total lines minus lines you need to reserve to show other
    information).

    If you set screen_lines to a number <=0, page() will try to auto-determine
    your screen size and will only use up to (screen_size+screen_lines) for
    printing, paging after that. That is, if you want auto-detection but need
    to reserve the bottom 3 lines of the screen, use screen_lines = -3, and for
    auto-detection without any lines reserved simply use screen_lines = 0.

    If a string won't fit in the allowed lines, it is sent through the
    specified pager command. If none given, look for PAGER in the environment,
    and ultimately default to less.

    If no system pager works, the string is sent through a 'dumb pager'
    written in python, very simplistic.
    """

    # Some routines may auto-compute start offsets incorrectly and pass a
    # negative value.  Offset to 0 for robustness.
    start = max(0, start)

    # first, try the hook
    ip = ipapi.get()
    if ip:
        try:
            ip.hooks.show_in_pager(strng)
            return
        except TryNext:
            pass

    # Ugly kludge, but calling curses.initscr() flat out crashes in emacs
    TERM = os.environ.get('TERM','dumb')
    if TERM in ['dumb','emacs'] and os.name != 'nt':
        print strng
        return
    # chop off the topmost part of the string we don't want to see
    str_lines = strng.splitlines()[start:]
    str_toprint = os.linesep.join(str_lines)
    num_newlines = len(str_lines)
    len_str = len(str_toprint)

    # Dumb heuristics to guesstimate number of on-screen lines the string
    # takes.  Very basic, but good enough for docstrings in reasonable
    # terminals. If someone later feels like refining it, it's not hard.
    numlines = max(num_newlines,int(len_str/80)+1)

    screen_lines_def = get_terminal_size()[1]

    # auto-determine screen size
    if screen_lines <= 0:
        try:
            screen_lines += _detect_screen_size(use_curses, screen_lines_def)
        except (TypeError, UnsupportedOperation):
            print >>io.stdout, str_toprint
            return

    #print 'numlines',numlines,'screenlines',screen_lines  # dbg
    if numlines <= screen_lines :
        #print '*** normal print'  # dbg
        print >>io.stdout, str_toprint
    else:
        # Try to open pager and default to internal one if that fails.
        # All failure modes are tagged as 'retval=1', to match the return
        # value of a failed system command.  If any intermediate attempt
        # sets retval to 1, at the end we resort to our own page_dumb() pager.
        pager_cmd = get_pager_cmd(pager_cmd)
        pager_cmd += ' ' + get_pager_start(pager_cmd,start)
        if os.name == 'nt':
            if pager_cmd.startswith('type'):
                # The default WinXP 'type' command is failing on complex strings.
                retval = 1
            else:
                tmpname = tempfile.mktemp('.txt')
                tmpfile = open(tmpname,'wt')
                tmpfile.write(strng)
                tmpfile.close()
                cmd = "%s < %s" % (pager_cmd,tmpname)
                if os.system(cmd):
                  retval = 1
                else:
                  retval = None
                os.remove(tmpname)
        else:
            try:
                retval = None
                # if I use popen4, things hang. No idea why.
                #pager,shell_out = os.popen4(pager_cmd)
                pager = os.popen(pager_cmd,'w')
                pager.write(strng)
                pager.close()
                retval = pager.close()  # success returns None
            except IOError,msg:  # broken pipe when user quits
                if msg.args == (32,'Broken pipe'):
                    retval = None
                else:
                    retval = 1
            except OSError:
                # Other strange problems, sometimes seen in Win2k/cygwin
                retval = 1
        if retval is not None:
            page_dumb(strng,screen_lines=screen_lines)

def page_file(fname, start=0, pager_cmd=None):
    """Page a file, using an optional pager command and starting line.
    """

    pager_cmd = get_pager_cmd(pager_cmd)
    pager_cmd += ' ' + get_pager_start(pager_cmd,start)

    try:
        if os.environ['TERM'] in ['emacs','dumb']:
            raise EnvironmentError
        system(pager_cmd + ' ' + fname)
    except:
        try:
            if start > 0:
                start -= 1
            page(open(fname).read(),start)
        except:
            print 'Unable to show file',`fname`

def get_pager_cmd(pager_cmd=None):
    """Return a pager command.

    Makes some attempts at finding an OS-correct one.
    """
    if os.name == 'posix':
        default_pager_cmd = 'less -r'  # -r for color control sequences
    elif os.name in ['nt','dos']:
        default_pager_cmd = 'type'

    if pager_cmd is None:
        try:
            pager_cmd = os.environ['PAGER']
        except:
            pager_cmd = default_pager_cmd
    return pager_cmd

def get_pager_start(pager, start):
    """Return the string for paging files with an offset.

    This is the '+N' argument which less and more (under Unix) accept.
    """

    if pager in ['less','more']:
        if start:
            start_string = '+' + str(start)
        else:
            start_string = ''
    else:
        start_string = ''
    return start_string

# (X)emacs on win32 doesn't like to be bypassed with msvcrt.getch()
if os.name == 'nt' and os.environ.get('TERM','dumb') != 'emacs':
    import msvcrt
    def page_more():
        """ Smart pausing between pages

        @return:    True if need print more lines, False if quit
        """
        io.stdout.write('---Return to continue, q to quit--- ')
        ans = msvcrt.getch()
        if ans in ("q", "Q"):
            result = False
        else:
            result = True
        io.stdout.write("\b"*37 + " "*37 + "\b"*37)
        return result
else:
    def page_more():
        ans = raw_input('---Return to continue, q to quit--- ')
        if ans.lower().startswith('q'):
            return False
        else:
            return True

def snip_print(str,width = 75,print_full = 0,header = ''):
    """Print a string snipping the midsection to fit in width.

    print_full: mode control:
      - 0: only snip long strings
      - 1: send to page() directly.
      - 2: snip long strings and ask for full length viewing with page()
    Return 1 if snipping was necessary, 0 otherwise."""

    if print_full == 1:
        page(header+str)
        return 0

    print header,
    if len(str) < width:
        print str
        snip = 0
    else:
        whalf = int((width -5)/2)
        print str[:whalf] + ' <...> ' + str[-whalf:]
        snip = 1
    if snip and print_full == 2:
        if raw_input(header+' Snipped. View (y/n)? [N]').lower() == 'y':
            page(str)
    return snip


# encoding: utf-8
"""
Utilities for timing code execution.
"""

#-----------------------------------------------------------------------------
#  Copyright (C) 2008-2011  The IPython Development Team
#
#  Distributed under the terms of the BSD License.  The full license is in
#  the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

import time

#-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------

# If possible (Unix), use the resource module instead of time.clock()
try:
    import resource
    def clocku():
        """clocku() -> floating point number

        Return the *USER* CPU time in seconds since the start of the process.
        This is done via a call to resource.getrusage, so it avoids the
        wraparound problems in time.clock()."""

        return resource.getrusage(resource.RUSAGE_SELF)[0]

    def clocks():
        """clocks() -> floating point number

        Return the *SYSTEM* CPU time in seconds since the start of the process.
        This is done via a call to resource.getrusage, so it avoids the
        wraparound problems in time.clock()."""

        return resource.getrusage(resource.RUSAGE_SELF)[1]

    def clock():
        """clock() -> floating point number

        Return the *TOTAL USER+SYSTEM* CPU time in seconds since the start of
        the process.  This is done via a call to resource.getrusage, so it
        avoids the wraparound problems in time.clock()."""

        u,s = resource.getrusage(resource.RUSAGE_SELF)[:2]
        return u+s

    def clock2():
        """clock2() -> (t_user,t_system)

        Similar to clock(), but return a tuple of user/system times."""
        return resource.getrusage(resource.RUSAGE_SELF)[:2]
except ImportError:
    # There is no distinction of user/system time under windows, so we just use
    # time.clock() for everything...
    clocku = clocks = clock = time.clock
    def clock2():
        """Under windows, system CPU time can't be measured.

        This just returns clock() and zero."""
        return time.clock(),0.0

def timings_out(reps,func,*args,**kw):
    """timings_out(reps,func,*args,**kw) -> (t_total,t_per_call,output)

    Execute a function reps times, return a tuple with the elapsed total
    CPU time in seconds, the time per call and the function's output.

    Under Unix, the return value is the sum of user+system time consumed by
    the process, computed via the resource module.  This prevents problems
    related to the wraparound effect which the time.clock() function has.

    Under Windows the return value is in wall clock seconds. See the
    documentation for the time module for more details."""

    reps = int(reps)
    assert reps >=1, 'reps must be >= 1'
    if reps==1:
        start = clock()
        out = func(*args,**kw)
        tot_time = clock()-start
    else:
        rng = xrange(reps-1) # the last time is executed separately to store output
        start = clock()
        for dummy in rng: func(*args,**kw)
        out = func(*args,**kw)  # one last time
        tot_time = clock()-start
    av_time = tot_time / reps
    return tot_time,av_time,out

def timings(reps,func,*args,**kw):
    """timings(reps,func,*args,**kw) -> (t_total,t_per_call)

    Execute a function reps times, return a tuple with the elapsed total CPU
    time in seconds and the time per call. These are just the first two values
    in timings_out()."""

    return timings_out(reps,func,*args,**kw)[0:2]

def timing(func,*args,**kw):
    """timing(func,*args,**kw) -> t_total

    Execute a function once, return the elapsed total CPU time in
    seconds. This is just the first value in timings_out()."""

    return timings_out(1,func,*args,**kw)[0]


"""
A print function that pretty prints sympy Basic objects.

:moduleauthor: Brian Granger

Usage
=====

Once the extension is loaded, Sympy Basic objects are automatically
pretty-printed.

As of SymPy 0.7.2, maintenance of this extension has moved to SymPy under
sympy.interactive.ipythonprinting, any modifications to account for changes to
SymPy should be submitted to SymPy rather than changed here. This module is
maintained here for backwards compatablitiy with old SymPy versions.

"""
#-----------------------------------------------------------------------------
#  Copyright (C) 2008  The IPython Development Team
#
#  Distributed under the terms of the BSD License.  The full license is in
#  the file COPYING, distributed as part of this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

from IPython.lib.latextools import latex_to_png
from IPython.testing import decorators as dec
# use @dec.skipif_not_sympy to skip tests requiring sympy

try:
    from sympy import pretty, latex
except ImportError:
    pass

import warnings

#-----------------------------------------------------------------------------
# Definitions of special display functions for use with IPython
#-----------------------------------------------------------------------------

def print_basic_unicode(o, p, cycle):
    """A function to pretty print sympy Basic objects."""
    if cycle:
        return p.text('Basic(...)')
    out = pretty(o, use_unicode=True)
    if '\n' in out:
        p.text(u'\n')
    p.text(out)

def print_png(o):
    """
    A function to display sympy expression using inline style LaTeX in PNG.
    """
    s = latex(o, mode='inline')
    # mathtext does not understand certain latex flags, so we try to replace
    # them with suitable subs.
    s = s.replace('\\operatorname','')
    s = s.replace('\\overline', '\\bar')
    png = latex_to_png(s)
    return png

def print_display_png(o):
    """
    A function to display sympy expression using display style LaTeX in PNG.
    """
    s = latex(o, mode='plain')
    s = s.strip('$')
    # As matplotlib does not support display style, dvipng backend is
    # used here.
    png = latex_to_png('$$%s$$' % s, backend='dvipng')
    return png

def can_print_latex(o):
    """
    Return True if type o can be printed with LaTeX.

    If o is a container type, this is True if and only if every element of o
    can be printed with LaTeX.
    """
    import sympy
    if isinstance(o, (list, tuple, set, frozenset)):
        return all(can_print_latex(i) for i in o)
    elif isinstance(o, dict):
        return all((isinstance(i, basestring) or can_print_latex(i)) and can_print_latex(o[i]) for i in o)
    elif isinstance(o,(sympy.Basic, sympy.matrices.Matrix, int, long, float)):
        return True
    return False

def print_latex(o):
    """A function to generate the latex representation of sympy
    expressions."""
    if can_print_latex(o):
        s = latex(o, mode='plain')
        s = s.replace('\\dag','\\dagger')
        s = s.strip('$')
        return '$$%s$$' % s
    # Fallback to the string printer
    return None

_loaded = False

def load_ipython_extension(ip):
    """Load the extension in IPython."""
    import sympy

    # sympyprinting extension has been moved to SymPy as of 0.7.2, if it
    # exists there, warn the user and import it
    try:
        import sympy.interactive.ipythonprinting
    except ImportError:
        pass
    else:
        warnings.warn("The sympyprinting extension in IPython is deprecated, "
            "use sympy.interactive.ipythonprinting")
        ip.extension_manager.load_extension('sympy.interactive.ipythonprinting')
        return

    global _loaded
    if not _loaded:
        plaintext_formatter = ip.display_formatter.formatters['text/plain']

        for cls in (object, str):
            plaintext_formatter.for_type(cls, print_basic_unicode)

        printable_containers = [list, tuple]

        # set and frozen set were broken with SymPy's latex() function, but
        # was fixed in the 0.7.1-git development version. See
        # http://code.google.com/p/sympy/issues/detail?id=3062.
        if sympy.__version__ > '0.7.1':
            printable_containers += [set, frozenset]
        else:
            plaintext_formatter.for_type(cls, print_basic_unicode)

        plaintext_formatter.for_type_by_name(
            'sympy.core.basic', 'Basic', print_basic_unicode
        )
        plaintext_formatter.for_type_by_name(
            'sympy.matrices.matrices', 'Matrix', print_basic_unicode
        )

        png_formatter = ip.display_formatter.formatters['image/png']

        png_formatter.for_type_by_name(
            'sympy.core.basic', 'Basic', print_png
        )
        png_formatter.for_type_by_name(
            'sympy.matrices.matrices', 'Matrix', print_display_png
        )
        for cls in [dict, int, long, float] + printable_containers:
            png_formatter.for_type(cls, print_png)

        latex_formatter = ip.display_formatter.formatters['text/latex']
        latex_formatter.for_type_by_name(
            'sympy.core.basic', 'Basic', print_latex
        )
        latex_formatter.for_type_by_name(
            'sympy.matrices.matrices', 'Matrix', print_latex
        )

        for cls in printable_containers:
            # Use LaTeX only if every element is printable by latex
            latex_formatter.for_type(cls, print_latex)

        _loaded = True


import string
from django import template

register = template.Library()

@register.filter()
def contains(value, arg):
    """
    Usage:
    {% if link_url|contains:"http://www.youtube.com/" %}
    Stuff
    {% else %}
    Not stuff
    {% endif %}
    """

    return arg in value

@register.filter()
def str2tokens(string, delimiter):
    """
    Usage:
    {% with 'this, is a, string'|str2tokens:',' as token_list %}do something{% endwith %}
    """

    token_list = [token.strip() for token in string.split(delimiter)]
    return token_list

@register.assignment_tag()
def str2tokenstags(string, delimiter):
    """
    Usage:
    {% str2tokens 'a/b/c/d' '/' as token_list %}
    """

    token_list = [token.strip() for token in string.split(delimiter)]
    return token_list

@register.assignment_tag()
def get_python_string(*args, **kwargs):
    """
    Usage:
    {% get_python_string as pystring %}
    {% for alpha in pystring.ascii_uppercase %}{{alpha}}{% endfor %}
    """

    return string

@register.assignment_tag()
def double_quoted(keywords):
    """
    Usage:
    {% double_quoted str1 str2 as str_1_2 %}
    """

    quoted = '"{}"'.format(keywords)
    return quoted