Move the Python implementation of htmltext into it ... (quixote/html.py)

Neil Schemenauer <nascheme-fVcApmY9cLvQ3/1i3zOLAti2O/[email protected]> Wed, 08 Jan 2003 14:43:25 -0500
Newsgroups gmane.comp.web.quixote.cvs
Message-ID <[email protected]>
Update of /home/cvs/quixote
In directory hewson:/tmp/cvs-serv20078

Modified Files:
	html.py 
Log Message:
Move the Python implementation of htmltext into it's own module.  That
makes it easy to override it with the C implementation.


Index: html.py
===================================================================
RCS file: /home/cvs/quixote/html.py,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- html.py	20 Nov 2002 19:43:22 -0000	1.21
+++ html.py	8 Jan 2003 19:43:23 -0000	1.22
@@ -44,205 +44,14 @@
 
 __revision__ = "$Id$"
 
-import sys
 import urllib
-from types import UnicodeType, TupleType, StringType, IntType, FloatType
-import re
-
-if sys.hexversion < 0x20200b1:
-    # inefficient 2.2 compatibility hacks
-    class object:
-        pass
-
-    class staticmethod:
-        def __init__(self, func):
-            self.__call__ = func
-
-    def zip(*args):
-        return map(None, *args)
-
-    def classof(o):
-        if hasattr(o, "__class__"):
-            return o.__class__
-        else:
-            return type(o)
-
-else:
-    classof = type
-
-_format_codes = 'diouxXeEfFgGcrs%'
-_format_re = re.compile(r'%%[^%s]*[%s]' % (_format_codes, _format_codes))
-
-class htmltext(object):
-    """
-
-    """
-
-    __slots__ = ['s']
-
-    def quote(s):
-        s = s.replace("&", "&amp;")
-        s = s.replace("<", "&lt;")
-        s = s.replace(">", "&gt;")
-        s = s.replace('"', "&quot;")
-        return s
-    quote = staticmethod(quote)
-
-    def __new__(klass, s):
-        inst = object.__new__(klass)
-        inst.s = str(s)
-        return inst
-
-    if sys.hexversion < 0x20200b1:
-        def __init__(self, s):
-            self.s = str(s)
-
-    # XXX make read-only
-    #def __setattr__(self, name, value):
-    #    raise AttributeError, 'immutable object'
-
-    def __getstate__(self):
-        raise ValueError, 'htmltext objects should not be pickled'
-
-    def __repr__(self):
-        return '<htmltext %r>' % self.s
-
-    def __str__(self):
-        return self.s
-
-    def __len__(self):
-        return len(self.s)
-
-    def __cmp__(self, other):
-        return cmp(self.s, other)
-
-    def __hash__(self):
-        return hash(self.s)
-
-    def __mod__(self, args):
-        codes = []
-        usedict = 0
-        for format in _format_re.findall(self.s):
-            if format[-1] != '%':
-                if format[1] == '(':
-                    usedict = 1
-                codes.append(format[-1])
-        def wraparg(arg):
-            if (classof(arg) is self.__class__ or
-                isinstance(arg, IntType) or
-                isinstance(arg, FloatType)):
-                # ints, floats, and htmltext are okay
-                return arg
-            else:
-                # everything is gets wrapped
-                return _QuoteWrapper(arg, self.quote)
-        if usedict:
-            for (k, v) in args.items():
-                args[k] = wraparg(v)
-        else:
-            if len(codes) == 1 and not isinstance(args, TupleType):
-                args = (args,)
-            args = tuple(map(wraparg, args))
-        return self.__class__(self.s % args)
-
-    def __add__(self, other):
-        if isinstance(other, StringType):
-            return self.__class__(self.s + self.quote(other))
-        elif classof(other) is self.__class__:
-            return self.__class__(self.s + other.s)
-        else:
-            return NotImplemented
-
-    def __radd__(self, other):
-        if isinstance(other, StringType):
-            return self.__class__(self.quote(other) + self.s)
-        else:
-            return NotImplemented
-
-    def __mul__(self, n):
-        return self.__class__(self.s * n)
-
-    def join(self, items):
-        quoted_items = []
-        for item in items:
-            if classof(item) is self.__class__:
-                quoted_items.append(str(item))
-            elif isinstance(item, StringType):
-                quoted_items.append(self.quote(item))
-            else:
-                raise TypeError(
-                    'join() requires string arguments (got %r)' % item)
-        return self.__class__(self.s.join(quoted_items))
-
-    def startswith(self, s):
-        if isinstance(s, htmltext):
-            s = s.s
-        else:
-            s = self.quote(s)
-        return self.s.startswith(s)
-
-    def endswith(self, s):
-        if isinstance(s, htmltext):
-            s = s.s
-        else:
-            s = self.quote(s)
-        return self.s.endswith(s)
-
-    def replace(self, old, new, maxsplit=-1):
-        if isinstance(old, htmltext):
-            old = old.s
-        else:
-            old = self.quote(old)
-        if isinstance(new, htmltext):
-            new = new.s
-        else:
-            new = self.quote(new)
-        return self.__class__(self.s.replace(old, new))
-
-    def lower(self):
-        return self.__class__(self.s.lower())
-
-    def upper(self):
-        return self.__class__(self.s.upper())
-
-    def capitalize(self):
-        return self.__class__(self.s.capitalize())
-
-class _QuoteWrapper:
-    # helper for htmltext class __mod__
-
-    __slots__ = ['value', 'quote']
-
-    def __init__(self, value, quote):
-        self.value = value
-        self.quote = quote
-
-    def __str__(self):
-        return self.quote(str(self.value))
-
-    def __repr__(self):
-        return self.quote(`self.value`)
-
-
-def htmlescape(s):
-    """htmlescape(s) -> htmltext
+from types import UnicodeType
 
-    Return an 'htmltext' object using the argument.  If the argument is not
-    already a 'htmltext' object then the HTML markup characters \", <, >,
-    and & are first escaped.
-    """
-    if classof(s) is htmltext:
-        return s
-    elif isinstance(s,  UnicodeType):
-        s = s.encode('iso-8859-1')
-    else:
-        s = str(s)
-    # inline htmltext.quote for speed
-    s = s.replace("&", "&amp;") # must be done first
-    s = s.replace("<", "&lt;")
-    s = s.replace(">", "&gt;")
-    s = s.replace('"', "&quot;")
-    return htmltext(s)
+try:
+    # faster C implementation
+    from quixote._c_htmltext import htmltext, htmlescape, _escape_string
+except ImportError:
+    from quixote._py_htmltext import htmltext, htmlescape, _escape_string
 
 
 ValuelessAttr = ["valueless_attr"] # magic singleton object
@@ -255,7 +64,7 @@
         if val is ValuelessAttr:
             val = attr
         if val is not None:
-            r += ' %s="%s"' % (attr, htmltext.quote(str(val)))
+            r += ' %s="%s"' % (attr, _escape_string(str(val)))
     if xml_end:
         r += " />"
     else: