Server IP : 127.0.0.2 / Your IP : 3.144.82.191 Web Server : Apache/2.4.18 (Ubuntu) System : User : www-data ( ) PHP Version : 7.0.33-0ubuntu0.16.04.16 Disable Function : disk_free_space,disk_total_space,diskfreespace,dl,exec,fpaththru,getmyuid,getmypid,highlight_file,ignore_user_abord,leak,listen,link,opcache_get_configuration,opcache_get_status,passthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,php_uname,phpinfo,posix_ctermid,posix_getcwd,posix_getegid,posix_geteuid,posix_getgid,posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid,posix,_getppid,posix_getpwnam,posix_getpwuid,posix_getrlimit,posix_getsid,posix_getuid,posix_isatty,posix_kill,posix_mkfifo,posix_setegid,posix_seteuid,posix_setgid,posix_setpgid,posix_setsid,posix_setuid,posix_times,posix_ttyname,posix_uname,pclose,popen,proc_open,proc_close,proc_get_status,proc_nice,proc_terminate,shell_exec,source,show_source,system,virtual MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/lib/python2.7/dist-packages/chameleon/ |
Upload File : |
############################################################################## # # Copyright (c) 2001, 2002 Zope Foundation and Contributors. # All Rights Reserved. # # This software is subject to the provisions of the Zope Public License, # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ############################################################################## import re import copy from .exc import LanguageError from .utils import descriptorint from .utils import descriptorstr from .namespaces import XMLNS_NS from .parser import groups try: next except NameError: from chameleon.py25 import next try: # optional library: `zope.interface` from chameleon import interfaces import zope.interface except ImportError: interfaces = None NAME = r"[a-zA-Z_][-a-zA-Z0-9_]*" DEFINE_RE = re.compile(r"(?s)\s*(?:(global|local)\s+)?" + r"(%s|\(%s(?:,\s*%s)*\))\s+(.*)\Z" % (NAME, NAME, NAME), re.UNICODE) SUBST_RE = re.compile(r"\s*(?:(text|structure)\s+)?(.*)\Z", re.S | re.UNICODE) ATTR_RE = re.compile(r"\s*([^\s{}'\"]+)\s+([^\s].*)\Z", re.S | re.UNICODE) ENTITY_RE = re.compile(r'(&(#?)(x?)(\d{1,5}|\w{1,8});)') WHITELIST = frozenset([ "define", "comment", "condition", "content", "replace", "repeat", "attributes", "on-error", "omit-tag", "script", "switch", "case", "xmlns", "xml" ]) def split_parts(arg): # Break in pieces at undoubled semicolons and # change double semicolons to singles: i = 0 while i < len(arg): m = ENTITY_RE.search(arg[i:]) if m is None: break arg = arg[:i + m.end()] + ';' + arg[i + m.end():] i += m.end() arg = arg.replace(";;", "\0") parts = arg.split(';') parts = [p.replace("\0", ";") for p in parts] if len(parts) > 1 and not parts[-1].strip(): del parts[-1] # It ended in a semicolon return parts def parse_attributes(clause): attrs = [] seen = set() for part in split_parts(clause): m = ATTR_RE.match(part) if not m: name, expr = None, part.strip() else: name, expr = groups(m, part) if name in seen: raise LanguageError( "Duplicate attribute name in attributes.", part) seen.add(name) attrs.append((name, expr)) return attrs def parse_substitution(clause): m = SUBST_RE.match(clause) if m is None: raise LanguageError( "Invalid content substitution syntax.", clause) key, expression = groups(m, clause) if not key: key = "text" return key, expression def parse_defines(clause): """ Parses a tal:define value. # Basic syntax, implicit local >>> parse_defines('hello lovely') [('local', ('hello',), 'lovely')] # Explicit local >>> parse_defines('local hello lovely') [('local', ('hello',), 'lovely')] # With global >>> parse_defines('global hello lovely') [('global', ('hello',), 'lovely')] # Multiple expressions >>> parse_defines('hello lovely; tea time') [('local', ('hello',), 'lovely'), ('local', ('tea',), 'time')] # With multiple names >>> parse_defines('(hello, howdy) lovely') [('local', ['hello', 'howdy'], 'lovely')] # With unicode whitespace >>> try: ... s = '\xc2\xa0hello lovely'.decode('utf-8') ... except AttributeError: ... s = '\xa0hello lovely' >>> from chameleon.utils import unicode_string >>> parse_defines(s) == [ ... ('local', ('hello',), 'lovely') ... ] True """ defines = [] for part in split_parts(clause): m = DEFINE_RE.match(part) if m is None: raise LanguageError("Invalid define syntax", part) context, name, expr = groups(m, part) context = context or "local" if name.startswith('('): names = [n.strip() for n in name.strip('()').split(',')] else: names = (name,) defines.append((context, names, expr)) return defines def prepare_attributes(attrs, dyn_attributes, i18n_attributes, ns_attributes, drop_ns): drop = set([attribute['name'] for attribute, (ns, value) in zip(attrs, ns_attributes) if ns in drop_ns or ( ns == XMLNS_NS and attribute['value'] in drop_ns ) ]) attributes = [] normalized = {} computed = [] for attribute in attrs: name = attribute['name'] if name in drop: continue attributes.append(( name, attribute['value'], attribute['quote'], attribute['space'], attribute['eq'], None, )) normalized[name.lower()] = len(attributes) - 1 for name, expr in dyn_attributes: index = normalized.get(name.lower()) if name else None if index is not None: _, text, quote, space, eq, _ = attributes[index] add = attributes.__setitem__ else: text = None quote = '"' space = " " eq = "=" index = len(attributes) add = attributes.insert if name is not None: normalized[name.lower()] = len(attributes) - 1 attribute = name, text, quote, space, eq, expr add(index, attribute) for name in i18n_attributes: attr = name.lower() if attr not in normalized: attributes.append((name, name, '"', " ", "=", None)) normalized[attr] = len(attributes) - 1 return attributes class RepeatItem(object): __slots__ = "length", "_iterator" __allow_access_to_unprotected_subobjects__ = True def __init__(self, iterator, length): self.length = length self._iterator = iterator def __iter__(self): return self._iterator try: iter(()).__len__ except AttributeError: @descriptorint def index(self): try: remaining = self._iterator.__length_hint__() except AttributeError: remaining = len(tuple(copy.copy(self._iterator))) return self.length - remaining - 1 else: @descriptorint def index(self): remaining = self._iterator.__len__() return self.length - remaining - 1 @descriptorint def start(self): return self.index == 0 @descriptorint def end(self): return self.index == self.length - 1 @descriptorint def number(self): return self.index + 1 @descriptorstr def odd(self): """Returns a true value if the item index is odd. >>> it = RepeatItem(iter(("apple", "pear")), 2) >>> next(it._iterator) 'apple' >>> it.odd() '' >>> next(it._iterator) 'pear' >>> it.odd() 'odd' """ return self.index % 2 == 1 and 'odd' or '' @descriptorstr def even(self): """Returns a true value if the item index is even. >>> it = RepeatItem(iter(("apple", "pear")), 2) >>> next(it._iterator) 'apple' >>> it.even() 'even' >>> next(it._iterator) 'pear' >>> it.even() '' """ return self.index % 2 == 0 and 'even' or '' @descriptorstr def parity(self): """Return 'odd' or 'even' depending on the position's parity Useful for assigning CSS class names to table rows. """ return self.index % 2 == 0 and 'even' or 'odd' def next(self): raise NotImplementedError( "Method not implemented (can't update local variable).") def _letter(self, base=ord('a'), radix=26): """Get the iterator position as a lower-case letter >>> it = RepeatItem(iter(("apple", "pear", "orange")), 3) >>> next(it._iterator) 'apple' >>> it.letter() 'a' >>> next(it._iterator) 'pear' >>> it.letter() 'b' >>> next(it._iterator) 'orange' >>> it.letter() 'c' """ index = self.index if index < 0: raise TypeError("No iteration position") s = "" while 1: index, off = divmod(index, radix) s = chr(base + off) + s if not index: return s letter = descriptorstr(_letter) @descriptorstr def Letter(self): """Get the iterator position as an upper-case letter >>> it = RepeatItem(iter(("apple", "pear", "orange")), 3) >>> next(it._iterator) 'apple' >>> it.Letter() 'A' >>> next(it._iterator) 'pear' >>> it.Letter() 'B' >>> next(it._iterator) 'orange' >>> it.Letter() 'C' """ return self._letter(base=ord('A')) @descriptorstr def Roman(self, rnvalues=( (1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I'))): """Get the iterator position as an upper-case roman numeral >>> it = RepeatItem(iter(("apple", "pear", "orange")), 3) >>> next(it._iterator) 'apple' >>> it.Roman() 'I' >>> next(it._iterator) 'pear' >>> it.Roman() 'II' >>> next(it._iterator) 'orange' >>> it.Roman() 'III' """ n = self.index + 1 s = "" for v, r in rnvalues: rct, n = divmod(n, v) s = s + r * rct return s @descriptorstr def roman(self): """Get the iterator position as a lower-case roman numeral >>> it = RepeatItem(iter(("apple", "pear", "orange")), 3) >>> next(it._iterator) 'apple' >>> it.roman() 'i' >>> next(it._iterator) 'pear' >>> it.roman() 'ii' >>> next(it._iterator) 'orange' >>> it.roman() 'iii' """ return self.Roman().lower() if interfaces is not None: zope.interface.classImplements(RepeatItem, interfaces.ITALESIterator) class RepeatDict(dict): """Repeat dictionary implementation. >>> repeat = RepeatDict({}) >>> iterator, length = repeat('numbers', range(5)) >>> length 5 >>> repeat['numbers'] <chameleon.tal.RepeatItem object at ...> >>> repeat.numbers <chameleon.tal.RepeatItem object at ...> >>> getattr(repeat, 'missing_key', None) is None True >>> try: ... from chameleon import interfaces ... interfaces.ITALESIterator(repeat,None) is None ... except ImportError: ... True ... True """ __slots__ = "__setitem__", "__getitem__" def __init__(self, d): self.__setitem__ = d.__setitem__ self.__getitem__ = d.__getitem__ def __getattr__(self,key): try: return self[key] except KeyError: raise AttributeError(key) def __call__(self, key, iterable): """We coerce the iterable to a tuple and return an iterator after registering it in the repeat dictionary.""" iterable = list(iterable) if iterable is not None else () length = len(iterable) iterator = iter(iterable) # Insert as repeat item self[key] = RepeatItem(iterator, length) return iterator, length class ErrorInfo(object): """Information about an exception passed to an on-error handler.""" def __init__(self, err, position=(None, None)): if isinstance(err, Exception): self.type = err.__class__ self.value = err else: self.type = err self.value = None self.lineno = position[0] self.offset = position[1] if interfaces is not None: zope.interface.classImplements(ErrorInfo, interfaces.ITALExpressionErrorInfo)