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("&", "&")
- s = s.replace("<", "<")
- s = s.replace(">", ">")
- s = s.replace('"', """)
- 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("&", "&") # must be done first
- s = s.replace("<", "<")
- s = s.replace(">", ">")
- s = s.replace('"', """)
- 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: