"""
$URL: svn+ssh://svn.mems-exchange.org/repos/trunk/qpy/c8.py $
$Id: c8.py 26966 2005-06-25 16:31:50Z dbinger $
"""
# This code has some unusual patterns to accomodate pyrex.
# Pyrex knows nothing about list comprehensions, and
# __new__ and class methods must be assembled in a wierd way.

def u8__new__(self, klass, s=''):
    if isinstance(s, str):
        return unicode.__new__(klass, s, 'utf-8')
    else:
        return unicode.__new__(klass, s)

def u8_quote(klass, s):
    if s is None:
        return klass('')
    else:
        return klass(s)

class u8 (unicode):
    """
    This is a subclass of unicode for which the constructor and __str__()
    always use the utf-8 encooding instead of the global default encoding.
    """
    __slots__ = []

    __new__ = classmethod(u8__new__)

    def __str__(self):
        return self.encode('utf-8')

    def __add__(self, other):
        return self.__class__(unicode.__add__(self, self.quote(other)))

    def __radd__(self, other):
        return self.__class__(unicode.__add__(self.quote(other), self))

    def __mul__(self, other):
        return self.__class__(unicode.__mul__(self, other))

    def __rmul__(self, other):
        return self.__class__(unicode.__mul__(self, other))

    def __mod__(self, other):
        quote = self.__class__.quote
        if isinstance(other, tuple):
            items = []
            for item in other:
               items.append(quote(item))
            target = tuple(items)
        elif isinstance(other, dict):
            target = {}
            for key, value in other.iteritems():
               target[key] = quote(value)
        else:
            target = quote(other)
        return self.__class__(unicode.__mod__(self, target))

    def join(self, items):
        quote = self.__class__.quote
        qitems = []
        for item in items:
            qitems.append(quote(item))
        return self.__class__(unicode.join(self, qitems))

    quote = classmethod(u8_quote)

u8.from_list = u8().join

def h8_quote(klass, s):
    if isinstance(s, h8):
        return s
    elif s is None:
        return klass('')
    else:
        return klass(s).replace("&", "&amp;").replace("<", "&lt;").replace(
            ">", "&gt;").replace('"', "&quot;")


class h8 (u8):
    """
    This subclass of u8 is designated as needing no more html quoting.
    Operations that combine this with non-h8 instances always quote
    the non-h8 instances and produce h8 instances.
    """
    __slots__ = []

    quote = classmethod(h8_quote)

h8.from_list = h8().join
