diff options
Diffstat (limited to 'system/python/spyce/modules/transform.py')
-rw-r--r-- | system/python/spyce/modules/transform.py | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/system/python/spyce/modules/transform.py b/system/python/spyce/modules/transform.py new file mode 100644 index 0000000000..1ca4f62a42 --- /dev/null +++ b/system/python/spyce/modules/transform.py @@ -0,0 +1,155 @@ +################################################## +# SPYCE - Python-based HTML Scripting +# Copyright (c) 2002 Rimon Barr. +# +# Refer to spyce.py +# CVS: $Id$ +################################################## + +from spyceModule import spyceModule +import types, re, string + +__doc__ = '''Transform module intercepts different kinds of Spyce ouput, and +can install functions to perform processing. It also includes some standard +Spyce transformation functions.''' + +OUTPUT_POSITON = 20 + +class transform(spyceModule): + def start(self): + self.ident = lambda x, **kwargs: x + self._filter = FilterFn(self.ident, self.ident, self.ident) + # install filter functions into response module + self._prevfilter = self._api.getModule('response').addFilter(OUTPUT_POSITON, self._filter) + def finish(self, theError=None): + self._prevfilter = self._api.getModule('response').addFilter(OUTPUT_POSITON, self._prevfilter) + # set filters + def dynamic(self, fn=None): + if not fn: fn = self.ident + self._filter.dynamicFilter = self.create(fn) + def static(self, fn=None): + if not fn: fn = self.ident + self._filter.staticFilter = self.create(fn) + def expr(self, fn=None): + if not fn: fn = self.ident + self._filter.exprFilter = self.create(fn) + # create filter + def create(self, fn): + '''Create filter function.''' + if fn==None or fn==() or fn==[]: + # identity + return self.ident + elif type(fn) == types.FunctionType: + # function type + return fn + elif type(fn) == type(''): + # string + file_name = string.split(fn, ':') + if len(file_name)==1: file, name = None, file_name[0] + else: file, name = file_name[:2] + if file: fn = loadModule(name, file, self._api.getFilename()) + else: fn = eval(name) + return fn + elif type(fn) == type(()) or type(fn) == type([]): + # tuple or array + fn0 = self.create(fn[0]) + fn1 = self.create(fn[1:]) + def filterfn(x, _fn0=fn0, _fn1=fn1, **kwargs): + x = apply(_fn0, (x,), kwargs) + return apply(_fn1, (x,), kwargs) + return filterfn + # commonly used transformations + def html_encode(self, s, also='', **kwargs): + '''Return HTML-encoded string.''' + return html_encode(s, also) + def url_encode(self, s, **kwargs): + '''Return url-encoded string.''' + return url_encode(s) + def __repr__(self): + return 'static: %s, expr: %s, dynamic: %s' % ( + str(self._filter.staticFilter!=self.ident), + str(self._filter.exprFilter!=self.ident), + str(self._filter.dynamicFilter!=self.ident), + ) + +class FilterFn(Filter): + def __init__(self, dynamicFilter=None, staticFilter=None, exprFilter=None): + ident = lambda x: x + if not dynamicFilter: dynamicFilter = ident + if not staticFilter: staticFilter = ident + if not exprFilter: exprFilter = ident + self.dynamicFilter = dynamicFilter + self.staticFilter = staticFilter + self.exprFilter = exprFilter + def dynamicImpl(self, s, *args, **kwargs): + return apply(self.dynamicFilter, (s,)+args, kwargs) + def staticImpl(self, s, *args, **kwargs): + return apply(self.staticFilter, (s,)+args, kwargs) + def exprImpl(self, s, *args, **kwargs): + return apply(self.exprFilter, (s,)+args, kwargs) + def flushImpl(self): + pass + def clearImpl(self): + pass + +# standard transformation functions +def ignore_none(o, **kwargs): + '''Does not print None.''' + if o==None: return '' + else: return o + +def silence(o, **kwargs): + '''Gobbles anything.''' + return '' + +def truncate(o, maxlen=None, **kwargs): + '''Limits output to a maximum string length.''' + if maxlen!=None: return str(o)[:maxlen] + else: return o + +_html_enc = { + chr(34): '"', chr(38): '&', chr(60): '<', chr(62): '>', + chr(160): ' ', chr(161): '¡', chr(162): '¢', chr(163): '£', + chr(164): '¤', chr(165): '¥', chr(166): '¦', chr(167): '§', + chr(168): '¨', chr(169): '©', chr(170): 'ª', chr(171): '«', + chr(172): '¬', chr(173): '­', chr(174): '®', chr(175): '¯', + chr(176): '°', chr(177): '±', chr(178): '²', chr(179): '³', + chr(180): '´', chr(181): 'µ', chr(182): '¶', chr(183): '·', + chr(184): '¸', chr(185): '¹', chr(186): 'º', chr(187): '»', + chr(188): '¼', chr(189): '½', chr(190): '¾', chr(191): '¿', + chr(192): 'À', chr(193): 'Á', chr(194): 'Â', chr(195): 'Ã', + chr(196): 'Ä', chr(197): 'Å', chr(198): 'Æ', chr(199): 'Ç', + chr(200): 'È', chr(201): 'É', chr(202): 'Ê', chr(203): 'Ë', + chr(204): 'Ì', chr(205): 'Í', chr(206): 'Î', chr(207): 'Ï', + chr(208): 'Ð', chr(209): 'Ñ', chr(210): 'Ò', chr(211): 'Ó', + chr(212): 'Ô', chr(213): 'Õ', chr(214): 'Ö', chr(215): '×', + chr(216): 'Ø', chr(217): 'Ù', chr(218): 'Ú', chr(219): 'Û', + chr(220): 'Ü', chr(221): 'Ý', chr(222): 'Þ', chr(223): 'ß', + chr(224): 'à', chr(225): 'á', chr(226): 'â', chr(227): 'ã', + chr(228): 'ä', chr(229): 'å', chr(230): 'æ', chr(231): 'ç', + chr(232): 'è', chr(233): 'é', chr(234): 'ê', chr(235): 'ë', + chr(236): 'ì', chr(237): 'í', chr(238): 'î', chr(239): 'ï', + chr(240): 'ð', chr(241): 'ñ', chr(242): 'ò', chr(243): 'ó', + chr(244): 'ô', chr(245): 'õ', chr(246): 'ö', chr(247): '÷', + chr(248): 'ø', chr(249): 'ù', chr(250): 'ú', chr(251): 'û', + chr(252): 'ü', chr(253): 'ý', chr(254): 'þ', chr(255): 'ÿ', +} +_html_ch = re.compile(r'['+reduce(lambda n, i: n+i, _html_enc.keys())+']') +def html_encode(o, also='', **kwargs): + '''Return HTML-encoded string.''' + o = _html_ch.sub(lambda match: _html_enc[match.group(0)], str(o)) + for c in also: + try: r=_html_enc[c] + except: r='&#%d;' % ord(c) + o=o.replace(c, r) + return o + +_url_ch = re.compile(r'[^A-Za-z0-9_.!~*()-]') # RFC 2396 section 2.3 +def url_encode(o, **kwargs): + '''Return URL-encoded string.''' + return _url_ch.sub(lambda match: "%%%02X" % ord(match.group(0)), str(o)) + +_nb_space_ch = re.compile(' ') +def nb_space(o, **kwargs): + '''Return string with spaces converted to be non-breaking.''' + return _nb_space_ch.sub(lambda match: ' ', str(o)) |