Changeset 27:2221cfba1675 in livinglogic.googleappengine.lltools

Show
Ignore:
Timestamp:
02/13/09 19:31:36 (11 years ago)
Author:
Walter Doerwald <walter@…>
Branch:
default
Message:

Updated XIST to version 3.6.1.

Location:
site/ll
Files:
64 modified

Legend:

Unmodified
Added
Removed
  • site/ll/__init__.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
     
    7979## ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 
    8080## OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
     81## 
     82## 
     83## This software includes jsmin by Douglas Crockford/Baruch Even 
     84## http://www.crockford.com/javascript/jsmin.py.txt 
     85## 
     86## This code is original from jsmin by Douglas Crockford, it was translated to 
     87## Python by Baruch Even. The original code had the following copyright and 
     88## license. 
     89## 
     90## /* jsmin.c 
     91##    2007-05-22 
     92## 
     93## Copyright (c) 2002 Douglas Crockford  (www.crockford.com) 
     94## 
     95## Permission is hereby granted, free of charge, to any person obtaining a copy of 
     96## this software and associated documentation files (the "Software"), to deal in 
     97## the Software without restriction, including without limitation the rights to 
     98## use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
     99## of the Software, and to permit persons to whom the Software is furnished to do 
     100## so, subject to the following conditions: 
     101## 
     102## The above copyright notice and this permission notice shall be included in all 
     103## copies or substantial portions of the Software. 
     104## 
     105## The Software shall be used for Good, not Evil. 
     106## 
     107## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
     108## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
     109## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
     110## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
     111## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
     112## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
     113## SOFTWARE. 
    81114 
    82115try: 
  • site/ll/ansistyle.py

    r9 r27  
    22# -*- coding: utf-8 -*- 
    33 
    4 ## Copyright 2000-2008 by LivingLogic AG, Bayreuth/Germany. 
    5 ## Copyright 2000-2008 by Walter Dörwald 
     4## Copyright 2000-2009 by LivingLogic AG, Bayreuth/Germany. 
     5## Copyright 2000-2009 by Walter Dörwald 
    66## 
    77## All Rights Reserved 
  • site/ll/color.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 2004-2008 by LivingLogic AG, Bayreuth/Germany. 
    4 ## Copyright 2004-2008 by Walter Dörwald 
     3## Copyright 2004-2009 by LivingLogic AG, Bayreuth/Germany. 
     4## Copyright 2004-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
     
    99 
    1010 
     11from __future__ import division 
     12 
    1113""" 
    1214:mod:`ll.color` provides classes and functions for handling RGB colors. 
     
    2224 
    2325 
    24 class Color(object): 
     26class Color(tuple): 
    2527    """ 
    2628    A :class:`Color` object represents a color with red, green and blue 
    2729    components. 
    2830    """ 
    29     __slots__ = ("_channels", ) 
    30      
    31     def __init__(self, r=0.0, g=0.0, b=0.0): 
    32         """ 
    33         Create a :class:`Color` with the red, green, and blue components 
    34         :var:`r`, :var:`g` and :var:`b`. Values will be clipped to the range 
    35         [0; 1]. 
    36         """ 
    37         self._channels = (max(0., min(float(r), 1.0)), max(0., min(float(g), 1.0)), max(0., min(float(b), 1.0))) 
    38  
    39     @classmethod 
    40     def fromrgb(cls, r, g, b): 
    41         """ 
    42         Create a :class:`Color` object from the RGB values :var:`r`, :var:`g` and 
    43         :var:`b`. See the :prop:`rgb` property for more info. 
    44         """ 
    45         c = cls() 
    46         c.rgb = (r, g, b) 
    47         return c 
    48  
    49     @classmethod 
    50     def fromrgb4(cls, r4, g4, b4): 
    51         """ 
    52         Create a :class:`Color` object from the 4 bit RGB values :var:`r4`, 
    53         :var:`g4` and :var:`b4`. See the :prop:`rgb4` property for more info. 
    54         """ 
    55         c = cls() 
    56         c.rgb4 = (r4, g4, b4) 
    57         return c 
    58  
    59     @classmethod 
    60     def fromrgb8(cls, r8, g8, b8): 
    61         """ 
    62         Create a :class:`Color` object from the 8 bit RGB values :var:`r8`, 
    63         :var:`g8` and :var:`b8`. See the :prop:`rgb8` property for more info. 
    64         """ 
    65         c = cls() 
    66         c.rgb8 = (r8, g8, b8) 
    67         return c 
    68  
    69     @classmethod 
    70     def fromint4(cls, int4): 
    71         """ 
    72         Create a :class:`Color` object from the 12 bit RGB integer :var:`int4`. 
    73         See the :prop:`int4` property for more info. 
    74         """ 
    75         c = cls() 
    76         c.int4 = int4 
    77         return c 
    78  
    79     @classmethod 
    80     def fromint8(cls, int8): 
    81         """ 
    82         Create a :class:`Color` object from the 24 bit RGB integer :var:`int8`. 
    83         See the :prop:`int8` property for more info. 
    84         """ 
    85         c = cls() 
    86         c.int8 = int8 
    87         return c 
     31    def __new__(cls, r=0x0, g=0x0, b=0x0, a=0xff): 
     32        """ 
     33        Create a :class:`Color` with the 8 bit red, green, blue and alpha 
     34        components :var:`r`, :var:`g`, :var:`b` and :var:`a`. Values will be 
     35        clipped to the range [0; 255]. 
     36        """ 
     37        return tuple.__new__(cls, (max(0, min(int(r), 255)), max(0, min(int(g), 255)), max(0, min(int(b), 255)), max(0, min(int(a), 255)))) 
    8838 
    8939    @classmethod 
    9040    def fromcss(cls, s): 
    9141        """ 
    92         Create a :class:`Color` object from the CSS color string :var:`s`. 
    93         See the :prop:`css` property for more info. 
    94         """ 
    95         c = cls() 
    96         c.css = s 
    97         return c 
     42        Create a :class:`Color` object from the CSS__ color string :var:`s`. 
     43        All formats from CSS2 are supported (i.e. ``'#xxx'``, ``'#xxxxxx'``, 
     44        ``rgb(r, g, b)``, ``rgb(r%, g%, b%)``, ``rgba(r, g, b, a)``, 
     45        ``rgba(r%, g%, b%, a)``  and color names like ``'red'``). 
     46 
     47        __ http://www.w3.org/TR/css3-color/#colorunits 
     48        """ 
     49        if s.startswith("#"): 
     50            if len(s) == 4: 
     51                return cls(17*int(s[1], 16), 17*int(s[2], 16), 17*int(s[3], 16)) 
     52            elif len(s) == 7: 
     53                return cls(int(s[1:3], 16), int(s[3:5], 16), int(s[5:], 16)) 
     54        elif s.startswith("rgb(") and s.endswith(")"): 
     55            channels = [] 
     56            for x in s[4:-1].split(","): 
     57                x = x.strip() 
     58                if x.endswith("%"): 
     59                    v = float(x[:-1])*0xff/100 
     60                else: 
     61                    v = int(x) 
     62                channels.append(v) 
     63            return cls(*channels) 
     64        elif s.startswith("rgba(") and s.endswith(")"): 
     65            channels = [] 
     66            for x in s[5:-1].split(","): 
     67                x = x.strip() 
     68                if len(channels) == 3: # alpha value 
     69                    v = float(x)*0xff 
     70                elif x.endswith("%"): 
     71                    v = float(x[:-1])*0xff/100 
     72                else: 
     73                    v = int(x) 
     74                channels.append(v) 
     75            return cls(*channels) 
     76        elif s in csscolors: 
     77            return csscolors[s] 
     78        raise ValueError("can't interpret %s as css value" % s) 
    9879 
    9980    @classmethod 
    100     def fromhsv(cls, h, s, v): 
     81    def fromrgb(cls, r, g, b, a=1.0): 
     82        """ 
     83        Create a :class:`Color` object from the red, green, blue and alpha values 
     84        :var:`r`, :var:`g`, :var:`b` and :var:`a`. All values will be clipped 
     85        to the range [0; 1]. 
     86        """ 
     87        return cls(255*r, 255*g, 255*b, 255*a) 
     88 
     89    @classmethod 
     90    def fromhsv(cls, h, s, v, a=1.0): 
    10191        """ 
    10292        Create a :class:`Color` object from the hue, saturation and value values 
    103         :var:`h`, :var:`s` and :var:`v`. See the :prop:`hsv` property for more 
    104         info. 
    105         """ 
    106         c = cls() 
    107         c.hsv = (h, s, v) 
    108         return c 
     93        :var:`h`, :var:`s` and :var:`v` and the alpha value :var:`a`. The hue 
     94        value will be used modulo 1.0, saturation, value and alpha will be clipped 
     95        to the range [0; 1]. 
     96        """ 
     97        rgb = colorsys.hsv_to_rgb(h % 1.0, max(0., min(s, 1.)), max(0., min(v, 1.))) 
     98        return cls.fromrgb(*(rgb + (a,))) 
    10999 
    110100    @classmethod 
    111     def fromhls(cls, h, l, s): 
     101    def fromhls(cls, h, l, s, a=1.0): 
    112102        """ 
    113103        Create a :class:`Color` object from the hue, luminance and saturation 
    114         values :var:`h`, :var:`l` and :var:`s`. See the :prop:`hls` property 
    115         for more info. 
    116         """ 
    117         c = cls() 
    118         c.hls = (h, l, s) 
    119         return c 
     104        values :var:`h`, :var:`l` and :var:`s` and the alpha value :var:`a`. 
     105        The hue value will be used modulo 1.0, luminance, saturation and alpha 
     106        will be clipped to the range [0; 1]. 
     107        """ 
     108        rgb = colorsys.hls_to_rgb(h % 1.0, max(0., min(l, 1.)), max(0., min(s, 1.))) 
     109        return cls.fromrgb(*(rgb + (a,))) 
    120110 
    121111    def __repr__(self): 
    122         return "Color(%r, %r, %r)" % tuple(self._channels) 
     112        if self[3] != 0xff: 
     113            return "Color(0x%02x, 0x%02x, 0x%02x, 0x%02x)" % self 
     114        else: 
     115            return "Color(0x%02x, 0x%02x, 0x%02x)" % self[:3] 
    123116 
    124117    def __str__(self): 
    125         return self.css 
    126  
    127     class r(misc.propclass): 
    128         """ 
    129         The red value as a float between 0.0 and 1.0. The value will be clipped 
    130         on setting. 
    131         """ 
    132         def __get__(self): 
    133             return self._channels[0] 
    134         def __set__(self, r): 
    135             self._channels = (max(0., min(float(r), 1.0)), self._channels[1], self._channels[2]) 
    136  
    137     class g(misc.propclass): 
    138         """ 
    139         The green value as a float between 0.0 and 1.0. The value will be clipped 
    140         on setting. 
    141         """ 
    142         def __get__(self): 
    143             return self._channels[1] 
    144         def __set__(self, g): 
    145             self._channels = (self._channels[0], max(0., min(float(g), 1.0)), self._channels[2]) 
    146  
    147     class b(misc.propclass): 
    148         """ 
    149         The blue value as a float between 0.0 and 1.0. The value will be clipped 
    150         on setting. 
    151         """ 
    152         def __get__(self): 
    153             return self._channels[2] 
    154         def __set__(self, b): 
    155             self._channels = (self._channels[0], self._channels[1], max(0., min(float(b), 1.0))) 
    156  
    157     class r4(misc.propclass): 
    158         """ 
    159         The red value as an int between 0 and 15. The value will be clipped 
    160         on setting. 
    161         """ 
    162         def __get__(self): 
    163             return int(15.*self._channels[0]+0.5) 
    164         def __set__(self, r4): 
    165             self._channels = (max(0., min(r4/15., 1.)), self._channels[1], self._channels[2]) 
    166  
    167     class g4(misc.propclass): 
    168         """ 
    169         The green value as an int between 0 and 15. The value will be clipped 
    170         on setting. 
    171         """ 
    172         def __get__(self): 
    173             return int(15.*self._channels[1]+0.5) 
    174         def __set__(self, g4): 
    175             self._channels = (self._channels[0], max(0., min(g4/15., 1.)), self._channels[2]) 
    176  
    177     class b4(misc.propclass): 
    178         """ 
    179         The blue value as an int between 0 and 15. The value will be clipped on 
    180         setting. 
    181         """ 
    182         def __get__(self): 
    183             return int(15.*self._channels[2]+0.5) 
    184         def __set__(self, b4): 
    185             self._channels = (self._channels[0], self._channels[1], max(0., min(b4/15., 1.))) 
    186  
    187     class r8(misc.propclass): 
    188         """ 
    189         The red value as an int between 0 and 255. The value will be clipped on 
    190         setting. 
    191         """ 
    192         def __get__(self): 
    193             return int(255.*self._channels[0]+0.5) 
    194         def __set__(self, r8): 
    195             self._channels = (max(0., min(r8/255., 1.)), self._channels[1], self._channels[2]) 
    196  
    197     class g8(misc.propclass): 
    198         """ 
    199         The green value as an int between 0 and 255. The value will be clipped on 
    200         setting. 
    201         """ 
    202         def __get__(self): 
    203             return int(255.*self._channels[1]+0.5) 
    204         def __set__(self, g8): 
    205             self._channels = (self._channels[0], max(0., min(g8/255., 1.)), self._channels[2]) 
    206  
    207     class b8(misc.propclass): 
    208         """ 
    209         The blue value as an int between 0 and 255. The value will be clipped on 
    210         setting. 
    211         """ 
    212         def __get__(self): 
    213             return int(255.*self._channels[2]+0.5) 
    214         def __set__(self, b8): 
    215             self._channels = (self._channels[0], self._channels[1], max(0., min(b8/255., 1.))) 
    216  
    217     class int4(misc.propclass): 
    218         """ 
    219         The RGB value as a 12 bit integer. Red is bit 8-11, green is bit 4-7 and 
    220         blue is bit 0-3) 
    221         """ 
    222         def __get__(self): 
    223             rgb4 = self.rgb4 
    224             return (rgb4[0]<<8) + (rgb4[1]<<4) + rgb4[2] 
    225         def __set__(self, rgb4): 
    226             self.rgb4 = (rgb4>>8 & 0xf, rgb4>>4 & 0xf, rgb4&0xf) 
    227  
    228     class int8(misc.propclass): 
    229         """ 
    230         The RGB value as a 24 bit integer. Red is bit 16-23, green is bit 8-15 
    231         and blue is bit 0-7) 
    232         """ 
    233         def __get__(self): 
    234             rgb8 = self.rgb8 
    235             return (rgb8[0]<<16) + (rgb8[1]<<8) + rgb8[2] 
    236         def __set__(self, rgb8): 
    237             self.rgb8 = (rgb8>>16 & 0xff, rgb8>>8 & 0xff, rgb8&0xff) 
    238  
    239     def __getitem__(self, index): 
    240         """ 
    241         Return the red, green or blue value (depending on whether :var:`index` is 
    242         0, 1 or 2) as a float value between 0.0 and 1.0. 
    243         """ 
    244         return self._channels[index] 
    245  
    246     def __setitem__(self, index, value): 
    247         """ 
    248         Set the red, green or blue value (depending on whether :var:`index` is 
    249         0, 1 or 2). The value should be between 0.0 and 1.0. Values outside this 
    250         range will be clipped. 
    251         """ 
    252         channels = list(self._channels) 
    253         channels[index] = max(0., min(float(value), 1.)) 
    254         self._channels = tuple(channels) 
    255  
    256     def __len__(self): 
    257         """ 
    258         Always returns 3. 
    259         """ 
    260         return 3 
    261  
    262     class rgb(misc.propclass): 
    263         """ 
    264         The red, green and blue value as a float tuple with values between 0.0 
    265         and 1.0. Values will be clipped on setting. 
    266         """ 
    267         def __get__(self): 
    268             return self._channels 
    269         def __set__(self, rgb): 
    270             self._channels = tuple([max(0., min(float(x), 1.)) for x in rgb]) 
    271  
    272     class rgb4(misc.propclass): 
    273         """ 
    274         The red, green and blue value as an int tuple with values between 0 and 
    275         15. Values will be clipped on setting. 
    276         """ 
    277         def __get__(self): 
    278             return tuple([int(15.*x+0.5) for x in self._channels]) 
    279         def __set__(self, rgb4): 
    280             self._channels = tuple([max(0., min(x/15., 1.)) for x in rgb4]) 
    281  
    282     class rgb8(misc.propclass): 
    283         """ 
    284         The red, green and blue value as an int tuple with values between 0 and 
    285         255. Values will be clipped on setting. 
    286         """ 
    287         def __get__(self): 
    288             return tuple([int(255.*x+0.5) for x in self._channels]) 
    289         def __set__(self, rgb8): 
    290             self._channels = tuple([max(0., min(x/255., 1.)) for x in rgb8]) 
    291  
    292     class css(misc.propclass): 
    293         """ 
    294         :var:`self` formatted as a &css; color string. On setting all formats 
    295         from CSS2 are supported (i.e. ``'#xxx'``, ``'#xxxxxx'``, ``rgb(n, n, n)``, 
    296         ``rgb(n%, n%, n%)`` and color names like ``'red'``). 
    297         """ 
    298         def __get__(self): 
    299             s = "#%06x" % self.int8 
     118        """ 
     119        :var:`self` formatted as a CSS color string. 
     120        """ 
     121        if self[3] != 0xff: 
     122            return "rgba(%d,%d,%d,%.3f)" % (self[0], self[1], self[2], self[3]/255.) 
     123        else: 
     124            s = "#%02x%02x%02x" % (self[0], self[1], self[2]) 
    300125            if s[1]==s[2] and s[3]==s[4] and s[5]==s[6]: 
    301126                s = "#%s%s%s" % (s[1], s[3], s[5]) 
    302             return s 
    303         def __set__(self, s): 
    304             if s.startswith("#"): 
    305                 i = int(s[1:], 16) 
    306                 if len(s) == 4: 
    307                     self.int4 = i 
    308                     return 
    309                 elif len(s) == 7: 
    310                     self.int8 = i 
    311                     return 
    312             elif s.startswith("rgb(") and s.endswith(")"): 
    313                 channels = [] 
    314                 for x in s[4:-1].split(","): 
    315                     x = x.strip() 
    316                     if x.endswith("%"): 
    317                         v = float(x[:-1])/100. 
    318                     else: 
    319                         v = float(x)/255. 
    320                     channels.append(v) 
    321                 self.rgb = channels 
    322                 return 
    323             elif s in csscolors: 
    324                 self.rgb = csscolors[s].rgb 
    325                 return 
    326             raise ValueError("can't interpret %s as css value" % s) 
    327  
    328     class hsv(misc.propclass): 
    329         """ 
    330         :var:`self` as a HSV ("hue, saturation, value") triple. All three values 
    331         are between 0.0 and 1.0. On setting hue will be used modulo 1.0, 
    332         saturation and value will be clipped to the range [0; 1]. 
    333         """ 
    334         def __get__(self): 
    335             return colorsys.rgb_to_hsv(*self.rgb) 
    336         def __set__(self, (h, s, v)): 
    337             self.rgb = colorsys.hsv_to_rgb(h % 1.0, max(0., min(s, 1.)), max(0., min(v, 1.))) 
    338  
    339     class hls(misc.propclass): 
     127        return s 
     128 
     129    def r(self): 
     130        """ 
     131        The red value as an int between 0 and 255. 
     132        """ 
     133        return self[0] 
     134 
     135    def g(self): 
     136        """ 
     137        The green value as an int between 0 and 255. 
     138        """ 
     139        return self[1] 
     140 
     141    def b(self): 
     142        """ 
     143        The blue value as an int between 0 and 255. 
     144        """ 
     145        return self[2] 
     146 
     147    def a(self): 
     148        """ 
     149        The alpha value as an int between 0 and 255. 
     150        """ 
     151        return self[3] 
     152 
     153    def rgb(self): 
     154        """ 
     155        The red, green and blue value as a float tuple with values between 
     156        0.0 and 1.0. 
     157        """ 
     158        return (self[0]/255., self[1]/255., self[2]/255.) 
     159 
     160    def rgba(self): 
     161        """ 
     162        The red, green, blue and alpha value as a float tuple with values between 
     163        0.0 and 1.0. 
     164        """ 
     165        return (self[0]/255., self[1]/255., self[2]/255., self[3]/255.) 
     166 
     167    def hsv(self): 
     168        """ 
     169        :var:`self` as a HSV ("hue, saturation, value") triple. 
     170        All three values are between 0.0 and 1.0. 
     171        """ 
     172        return colorsys.rgb_to_hsv(self[0]/255., self[1]/255., self[2]/255.) 
     173 
     174    def hsva(self): 
     175        """ 
     176        :var:`self` as a HSV+alpha ("hue, saturation, value, alpha") tuple. 
     177        All four values are between 0.0 and 1.0. 
     178        """ 
     179        return self.hsv() + (self[3]/255.,) 
     180 
     181    def hls(self): 
    340182        """ 
    341183        :var:`self` as a HLS ("hue, luminance, saturation") triple. All three 
    342         values are between 0.0 and 1.0. On setting hue will be used modulo 1.0, 
    343         luminance and saturation will be clipped to the range [0; 1]. 
    344         """ 
    345         def __get__(self): 
    346             return colorsys.rgb_to_hls(*self.rgb) 
    347         def __set__(self, (h, l, s)): 
    348             self.rgb = colorsys.hls_to_rgb(h % 1.0, max(0., min(l, 1.)), max(0., min(s, 1.))) 
    349  
    350     class lum(misc.propclass): 
    351         """ 
    352         The luminance value from the :prop:`hls` property. 
    353         """ 
    354         def __get__(self): 
    355             return colorsys.rgb_to_hls(*self.rgb)[1] 
    356         def __set__(self, lum): 
    357             (h, l, s) = self.hls 
    358             self.rgb = colorsys.hls_to_rgb(h, max(0., min(lum, 1.)), s) 
     184        values are between 0.0 and 1.0. 
     185        """ 
     186        return colorsys.rgb_to_hls(self[0]/255., self[1]/255., self[2]/255.) 
     187 
     188    def hlsa(self): 
     189        """ 
     190        :var:`self` as a HLS+alpha ("hue, luminance, saturation, alpha") tuple. 
     191        All four values are between 0.0 and 1.0. 
     192        """ 
     193        return self.hls() + (self[3]/255.,) 
     194 
     195    def lum(self): 
     196        """ 
     197        The luminance value from :meth:`hls`. 
     198        """ 
     199        return colorsys.rgb_to_hls(self[0]/255., self[1]/255., self[2]/255.)[1] 
     200 
     201    def combine(self, r=None, g=None, b=None, a=None): 
     202        """ 
     203        Return a copy of :var:`self` with some of the values replaced by the 
     204        arguments. 
     205        """ 
     206        channels = list(self) 
     207        if r is not None: 
     208            channels[0] = r 
     209        if g is not None: 
     210            channels[1] = g 
     211        if b is not None: 
     212            channels[2] = b 
     213        if a is not None: 
     214            channels[3] = a 
     215        return self.__class__(*channels) 
     216 
     217    def witha(self, a): 
     218        """ 
     219        Return a copy of :var:`self` with the alpha value replaced with :var:`a`. 
     220        """ 
     221        (r, g, b, olda) = self 
     222        return self.__class__(r, g, b, a) 
     223 
     224    def withlum(self, lum): 
     225        """ 
     226        Return a copy of :var:`self` with the luminosity replaced with :var:`lum`. 
     227        """ 
     228        (h, l, s, a) = self.hlsa() 
     229        return self.fromhls(h, lum, s, a) 
    359230 
    360231    def abslum(self, f): 
     
    362233        Return a copy of :var:`self` with :var:`f` added to the luminocity. 
    363234        """ 
    364         (h, l, s) = self.hls 
    365         return self.fromhls(h, l+f, s) 
     235        (h, l, s, a) = self.hlsa() 
     236        return self.fromhlsa(h, l+f, s, a) 
    366237 
    367238    def rellum(self, f): 
    368239        """ 
    369240        Return a copy of :var:`self` where the luminocity has been modified: 
    370         If :var:`f` if positive the luminocity will be increased, with 
    371         ``f==1`` giving a luminocity of 1. If :var:`f` is negative, the 
    372         luminocity will be decreased with ``:var:`f`==-1`` giving a luminocity 
    373         of 0. ``f==0`` will leave the luminocity unchanged. 
    374         """ 
    375         (h, l, s) = self.hls 
     241        If :var:`f` if positive the luminocity will be increased, with ``f==1`` 
     242        giving a luminocity of 1. If :var:`f` is negative, the luminocity will be 
     243        decreased with ``f==-1`` giving a luminocity of 0. ``f==0`` will leave 
     244        the luminocity unchanged. 
     245        """ 
     246        (h, l, s, a) = self.hlsa 
    376247        if f > 0: 
    377248            l += (1-l)*f 
    378249        elif f < 0: 
    379250            l += l*f 
    380         return self.fromhls(h, l, s) 
     251        return self.fromhlsa(h, l, s, a) 
     252 
     253    def __add__(self, other): 
     254        return self.__class__(0.5*(self[0]+other[0]), 0.5*(self[1]+other[1]), 0.5*(self[2]+other[2]), 255-(255-self[3])*(255-other[3])/255.) 
     255 
     256    def __mul__(self, factor): 
     257        return self.__class__(factor*self[0], factor*self[1], factor*self[2], self[3]) 
     258 
     259    def __rmul__(self, factor): 
     260        return self.__class__(factor*self[0], factor*self[1], factor*self[2], self[3]) 
     261 
     262    def __div__(self, factor): 
     263        return self.__class__(self[0]/factor, self[1]/factor, self[2]/factor, self[3]) 
     264 
     265    def __mod__(self, other): 
     266        """ 
     267        Blends :var:`self` with the background color :var:`other` according to the 
     268        `SVG specification`__ 
     269 
     270        __ http://www.w3.org/TR/2003/REC-SVG11-20030114/masking.html#SimpleAlphaBlending 
     271        """ 
     272        sa = self[3]/255. 
     273        rsa = 1.-sa 
     274        return self.__class__(self[0]*sa+rsa*other[0], self[1]*sa+rsa*other[1], self[2]*sa+rsa*other[2], 255-rsa*(255-other[3])) 
    381275 
    382276 
    383277### 
    384 ### Color constants (don't modify!) 
     278### CSS color constants (see http://www.w3.org/TR/css3-color/#html4) 
    385279### 
    386280 
    387 maroon = Color.fromrgb8(0x80, 0x00, 0x00) 
    388 red = Color.fromrgb8(0xff, 0x00, 0x00) 
    389 orange = Color.fromrgb8(0xff, 0xA5, 0x00) 
    390 yellow = Color.fromrgb8(0xff, 0xff, 0x00) 
    391 olive = Color.fromrgb8(0x80, 0x80, 0x00) 
    392 purple = Color.fromrgb8(0x80, 0x00, 0x80) 
    393 fuchsia = Color.fromrgb8(0xff, 0x00, 0xff) 
    394 white = Color.fromrgb8(0xff, 0xff, 0xff) 
    395 lime = Color.fromrgb8(0x00, 0xff, 0x00) 
    396 green = Color.fromrgb8(0x00, 0x80, 0x00) 
    397 navy = Color.fromrgb8(0x00, 0x00, 0x80) 
    398 blue = Color.fromrgb8(0x00, 0x00, 0xff) 
    399 aqua = Color.fromrgb8(0x00, 0xff, 0xff) 
    400 teal = Color.fromrgb8(0x00, 0x80, 0x80) 
    401 black = Color.fromrgb8(0x00, 0x00, 0x00) 
    402 silver = Color.fromrgb8(0xc0, 0xc0, 0xc0) 
    403 gray = Color.fromrgb8(0x80, 0x80, 0x80) 
     281maroon = Color(0x80, 0x00, 0x00) 
     282red = Color(0xff, 0x00, 0x00) 
     283orange = Color(0xff, 0xa5, 0x00) 
     284yellow = Color(0xff, 0xff, 0x00) 
     285olive = Color(0x80, 0x80, 0x00) 
     286purple = Color(0x80, 0x00, 0x80) 
     287fuchsia = Color(0xff, 0x00, 0xff) 
     288white = Color(0xff, 0xff, 0xff) 
     289lime = Color(0x00, 0xff, 0x00) 
     290green = Color(0x00, 0x80, 0x00) 
     291navy = Color(0x00, 0x00, 0x80) 
     292blue = Color(0x00, 0x00, 0xff) 
     293aqua = Color(0x00, 0xff, 0xff) 
     294teal = Color(0x00, 0x80, 0x80) 
     295black = Color(0x00, 0x00, 0x00) 
     296silver = Color(0xc0, 0xc0, 0xc0) 
     297gray = Color(0x80, 0x80, 0x80) 
     298 
     299# aliases 
     300magenta = purple 
     301cyan = aqua 
     302 
     303transparent = Color(0, 0, 0, 0) 
    404304 
    405305 
     
    422322    "silver": silver, 
    423323    "gray": gray, 
     324    "magenta": magenta, 
     325    "cyan": cyan, 
    424326} 
    425327 
    426328 
     329def css(value): 
     330    return Color.fromcss(value) 
     331 
     332 
     333def dist(c1, c2): 
     334    """ 
     335    Return the distance between two colors. 
     336    """ 
     337 
     338    d0 = c1[0]-c2[0] 
     339    d1 = c1[1]-c2[1] 
     340    d2 = c1[2]-c2[2] 
     341    return d0*d0+d1*d1+d2*d2 
     342 
     343 
    427344def multiply(c1, c2): 
    428345    """ 
    429346    Multiplies the colors :var:`c1` and :var:`c2`. 
    430347    """ 
    431     c1 = c1.rgb 
    432     c2 = c2.rgb 
    433     return Color(c1[0]*c2[0], c1[1]*c2[1], c1[2]*c2[2]) 
     348    return Color(c1[0]*c2[0], c1[1]*c2[1], c1[2]*c2[2], 1.-(1.-c1[3])*(1.-c2[3])) 
    434349 
    435350 
     
    438353    Does a negative multiplication of the colors :var:`c1` and :var:`c2`. 
    439354    """ 
    440     c1 = c1.rgb 
    441     c2 = c2.rgb 
    442     return Color(1.-(1.-c1[0])*(1.-c2[0]), 1.-(1.-c1[1])*(1.-c2[1]), 1.-(1.-c1[2])*(1.-c2[2])) 
     355    return Color(*(1.-(1.-x)*(1.-y) for (x, y) in zip(c1, c2))) 
    443356 
    444357 
     
    446359    """ 
    447360    Calculates a weighted mix of the colors from :var:`args`. Items in 
    448     :var:`args` are either colors (in which case the weight will be 1) or 
    449     (color, weight) tuples. 
    450     """ 
    451     channels = [0., 0., 0.] 
    452     sum = 0. 
     361    :var:`args` are either colors or weights. 
     362    """ 
     363    channels = [0., 0., 0., 0.] 
     364    weight = 1. 
     365    sumweights = 0. 
    453366    for arg in args: 
    454367        if isinstance(arg, Color): 
    455             (c, w) = (arg, 1.) 
     368            sumweights += weight 
     369            for i in xrange(3): 
     370                channels[i] += weight*arg[i] 
     371            channels[3] += weight*(255-arg[3]) 
     372        elif isinstance(arg, tuple): 
     373            sumweights += arg[1] 
     374            for i in xrange(3): 
     375                channels[i] += arg[1]*arg[0][i] 
     376            channels[3] += weight*(255-arg[0][3]) 
    456377        else: 
    457             (c, w) = arg 
    458         for j in xrange(3): 
    459             channels[j] += w*c[j] 
    460         sum += w 
    461     if not sum: 
     378            weight = arg 
     379    if not sumweights: 
    462380        raise ValueError("at least one of the weights must be >0") 
    463     for j in xrange(3): 
    464         channels[j] /= sum 
    465     return Color.fromrgb(*channels) 
     381    return Color(channels[0]/sumweights, channels[1]/sumweights, channels[2]/sumweights, 255-sumweights*channels[3]) 
  • site/ll/daemon.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 2007-2008 by LivingLogic AG, Bayreuth/Germany. 
    4 ## Copyright 2007-2008 by Walter Dörwald 
     3## Copyright 2007-2009 by LivingLogic AG, Bayreuth/Germany. 
     4## Copyright 2007-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/make.py

    r9 r27  
    22# -*- coding: utf-8 -*- 
    33 
    4 ## Copyright 2002-2008 by LivingLogic AG, Bayreuth/Germany. 
    5 ## Copyright 2002-2008 by Walter Dörwald 
     4## Copyright 2002-2009 by LivingLogic AG, Bayreuth/Germany. 
     5## Copyright 2002-2009 by Walter Dörwald 
    66## 
    77## All Rights Reserved 
     
    5353from __future__ import with_statement 
    5454 
    55 import sys, os, os.path, optparse, warnings, re, datetime, cStringIO, errno, tempfile, operator, types, cPickle, gc, contextlib, locale 
     55import sys, os, os.path, optparse, warnings, re, datetime, cStringIO, errno, tempfile, operator, types, cPickle, gc, contextlib, locale, gzip 
    5656 
    5757from ll import misc, url 
     
    231231    containing: 
    232232 
    233     *   An object (:var:`data`) of the same structure as :var:`input` where every 
     233    *   An object (:var:`data`) of the same structure as :var:`input`, where every 
    234234        action object encountered is replacd with the output of that action; 
    235235 
     
    237237        change timestamps of the actions encountered. 
    238238 
    239     *   If none of the actions has any data newer than :var:`since` (i.e. none 
    240         of the actions produces any new data) :var:`data` will be :const:`nodata`. 
     239    If none of the actions has any data newer than :var:`since` (i.e. none of 
     240    the actions produced any new data) :var:`data` will be :const:`nodata`. 
    241241    """ 
    242242    if isinstance(input, Action): 
     
    382382                return "=%r" % (arg,) 
    383383 
    384         output = ["%d%s" % (i, format(arg)) for (i, arg) in enumerate(self.getargs())] 
     384        output = ["arg %d%s" % (i, format(arg)) for (i, arg) in enumerate(self.getargs())] 
    385385        for (argname, arg) in self.getkwargs().iteritems(): 
    386             output.append("%s%s" % (argname, format(arg))) 
     386            output.append("arg %s%s" % (argname, format(arg))) 
    387387             
    388388        if output: 
     
    718718 
    719719    def execute(self, project, inputs): 
    720         project.writestep(self, "Joining data from ", len(data), " inputs") 
    721         return "".join(data) 
     720        project.writestep(self, "Joining data from ", len(inputs), " inputs") 
     721        return "".join(inputs) 
    722722 
    723723 
     
    768768            self.since = since 
    769769            self.buildno = project.buildno 
    770         if since < self.changed: 
     770        if since < self.changed or since is bigbang: 
    771771            project.writenote(self, "Reusing cached data") 
    772772            return self.data 
     
    11331133    def execute(self, project, data, compresslevel): 
    11341134        project.writestep(self, "Compressing ", len(data), " bytes with level " % compresslevel) 
    1135         import gzip, cStringIO 
    11361135        stream = cStringIO.StringIO() 
    11371136        compressor = gzip.GzipFile(filename="", mode="wb", fileobj=stream, compresslevel=compresslevel) 
     
    11481147    def execute(self, project, data): 
    11491148        project.writestep(self, "Uncompressing ", len(data), " bytes") 
    1150         import gzip, cStringIO 
    11511149        stream = cStringIO.StringIO(data) 
    11521150        compressor = gzip.GzipFile(filename="", mode="rb", fileobj=stream) 
    11531151        return compressor.read(data) 
     1152 
     1153 
     1154class JSMinUnterminatedComment(Exception): 
     1155    pass 
     1156 
     1157class JSMinUnterminatedStringLiteral(Exception): 
     1158    pass 
     1159 
     1160class JSMinUnterminatedRegularExpression(Exception): 
     1161    pass 
     1162 
     1163 
     1164class JavascriptMinifyAction(PipeAction): 
     1165    """ 
     1166    This action minimizes Javascript code. 
     1167    """ 
     1168    def execute(self, project, data): 
     1169        project.writestep(self, "Minimizing ", len(data), " ", ("bytes" if isinstance(data, str) else "characters"), " of Javascript code") 
     1170        indata = iter(data.replace("\r", "\n")) 
     1171 
     1172        # Copy the input to the output, deleting the characters which are 
     1173        # insignificant to JavaScript. Comments will be removed. Tabs will be 
     1174        # replaced with spaces. Carriage returns will be replaced with linefeeds. 
     1175        # Most spaces and linefeeds will be removed. 
     1176 
     1177        self.a = "\n" 
     1178        self.b = None 
     1179        self.lookahead = None 
     1180        outdata = [] 
     1181     
     1182        def _get(): 
     1183            # Return the next character from the input. Watch out for lookahead. If 
     1184            # the character is a control character, translate it to a space or linefeed. 
     1185            c = self.lookahead 
     1186            self.lookahead = None 
     1187            if c is None: 
     1188                try: 
     1189                    c = indata.next() 
     1190                except StopIteration: 
     1191                    return "" # EOF 
     1192            if c >= " " or c == "\n": 
     1193                return c 
     1194            return " " 
     1195 
     1196        def _peek(): 
     1197            self.lookahead = _get() 
     1198            return self.lookahead 
     1199 
     1200        def isalphanum(c): 
     1201            # Return true if the character is a letter, digit, underscore, dollar sign, or non-ASCII character. 
     1202            return ('a' <= c <= 'z') or ('0' <= c <= '9') or ('A' <= c <= 'Z') or c in "_$\\" or (c is not None and ord(c) > 126) 
     1203 
     1204        def _next(): 
     1205            # Get the next character, excluding comments. peek() is used to see if an unescaped '/' is followed by a '/' or '*'. 
     1206            c = _get() 
     1207            if c == "/" and self.a != "\\": 
     1208                p = _peek() 
     1209                if p == "/": 
     1210                    c = _get() 
     1211                    while c > "\n": 
     1212                        c = _get() 
     1213                    return c 
     1214                if p == "*": 
     1215                    c = _get() 
     1216                    while 1: 
     1217                        c = _get() 
     1218                        if c == "*": 
     1219                            if _peek() == "/": 
     1220                                _get() 
     1221                                return " " 
     1222                        if not c: 
     1223                            raise JSMinUnterminatedComment() 
     1224            return c 
     1225 
     1226        def _action(action): 
     1227            """ 
     1228            Do something! What you do is determined by the argument: 
     1229               1   Output A. Copy B to A. Get the next B. 
     1230               2   Copy B to A. Get the next B. (Delete A). 
     1231               3   Get the next B. (Delete B). 
     1232            action treats a string as a single character. Wow! 
     1233            action recognizes a regular expression if it is preceded by ( or , or =. 
     1234            """ 
     1235            if action <= 1: 
     1236                outdata.append(self.a) 
     1237 
     1238            if action <= 2: 
     1239                self.a = self.b 
     1240                if self.a in "'\"": 
     1241                    while True: 
     1242                        outdata.append(self.a) 
     1243                        self.a = _get() 
     1244                        if self.a == self.b: 
     1245                            break 
     1246                        if self.a <= "\n": 
     1247                            raise JSMinUnterminatedStringLiteral() 
     1248                        if self.a == "\\": 
     1249                            outdata.append(self.a) 
     1250                            self.a = _get() 
     1251 
     1252            if action <= 3: 
     1253                self.b = _next() 
     1254                if self.b == "/" and self.a in "(,=:[?!&|;{}\n": 
     1255                    outdata.append(self.a) 
     1256                    outdata.append(self.b) 
     1257                    while True: 
     1258                        self.a = _get() 
     1259                        if self.a == "/": 
     1260                            break 
     1261                        elif self.a == "\\": 
     1262                            outdata.append(self.a) 
     1263                            self.a = _get() 
     1264                        elif self.a <= "\n": 
     1265                            raise JSMinUnterminatedRegularExpression() 
     1266                        outdata.append(self.a) 
     1267                    self.b = _next() 
     1268 
     1269        _action(3) 
     1270 
     1271        while self.a: 
     1272            if self.a == " ": 
     1273                _action(1 if isalphanum(self.b) else 2) 
     1274            elif self.a == "\n": 
     1275                if self.b in "{[(+-": 
     1276                    _action(1) 
     1277                elif self.b == " ": 
     1278                    _action(3) 
     1279                else: 
     1280                    _action(1 if isalphanum(self.b) else 2) 
     1281            else: 
     1282                if self.b == " ": 
     1283                    _action(1 if isalphanum(self.a) else 3) 
     1284                elif self.b == "\n": 
     1285                    _action(1 if isalphanum(self.a) or self.a in "}])+-\"'" else 3) 
     1286                else: 
     1287                    _action(1) 
     1288        return "".join(outdata).lstrip() 
    11541289 
    11551290 
     
    12841419 
    12851420 
    1286 class XPITAction(PipeAction): 
    1287     """ 
    1288     This action transform an input string via :mod:`ll.xpit`. 
    1289     """ 
    1290  
    1291     def __init__(self, input=None, nsinput=None): 
    1292         PipeAction.__init__(self, input) 
    1293         self.nsinput = nsinput 
    1294  
    1295     def addnsinput(self, input): 
    1296         """ 
    1297         Register :var:`input` as the namespace action. This action must return 
    1298         a namespace to be used in evaluating the input string from the normal 
    1299         input action. 
    1300         """ 
    1301         self.nsinput = input 
    1302         return self 
    1303  
    1304     def __iter__(self): 
    1305         for input in PipeAction.__iter__(self): 
    1306             yield input 
    1307         yield self.nsinput 
    1308  
    1309     def getkwargs(self): 
    1310         return dict(ns=self.nsinput, data=self.input) 
    1311  
    1312     def execute(self, project, ns, data): 
    1313         from ll import xpit 
    1314         globals = dict(makeaction=self, makeproject=project) 
    1315         project.writestep(self, "Converting XPIT input") 
    1316         return xpit.convert(data, globals, ns) 
    1317  
    1318  
    13191421class UL4CompileAction(PipeAction): 
    13201422    """ 
     
    13321434    This action renders a UL4 template to a string. 
    13331435    """ 
    1334     def __init__(self, input=None, templates={}, **vars): 
     1436    def __init__(self, input=None, **vars): 
    13351437        PipeAction.__init__(self, input) 
    1336         self.templates = templates 
    13371438        self.vars = vars 
    13381439 
     
    13401441        for input in PipeAction.__iter__(self): 
    13411442            yield input 
    1342         for input in self.templates.itervalues(): 
    1343             yield input 
    13441443        for input in self.vars.itervalues(): 
    13451444            yield input 
    13461445 
    13471446    def getargs(self): 
    1348         return (self.input, self.templates) 
     1447        return (self.input,) 
    13491448 
    13501449    def getkwargs(self): 
    13511450        return self.vars 
    13521451 
    1353     def execute(self, project, data, templates, **vars): 
     1452    def execute(self, project, data, **vars): 
    13541453        project.writestep(self, "Rendering UL4 template with ", len(self.opcodes), " opcodes") 
    1355         return data.renders(templates, **vars) 
     1454        return data.renders(**vars) 
    13561455 
    13571456 
     
    14881587        These actions must be :class:`ModuleAction` objects too. 
    14891588 
    1490         Normally it isn't neccessary to call the method explicitely. Instead 
     1589        Normally it isn't neccessary to call the method explicitly. Instead 
    14911590        fetch the required module inside your module like this:: 
    14921591 
     
    18031902 
    18041903s4indent = astyle.Style.fromenv("LL_MAKE_REPRANSI_INDENT", "black:black:bold") 
    1805 s4key = astyle.Style.fromenv("LL_MAKE_REPRANSI_KEY", "green:black") 
    1806 s4action = astyle.Style.fromenv("LL_MAKE_REPRANSI_ACTION", "yellow:black") 
     1904s4key = astyle.Style.fromenv("LL_MAKE_REPRANSI_KEY", "yellow:black") 
     1905s4action = astyle.Style.fromenv("LL_MAKE_REPRANSI_ACTION", "green:black") 
    18071906s4time = astyle.Style.fromenv("LL_MAKE_REPRANSI_TIME", "magenta:black") 
    18081907s4data = astyle.Style.fromenv("LL_MAKE_REPRANSI_DATA", "cyan:black") 
     
    18491948        self.showtimestamps = self._getenvbool("LL_MAKE_SHOWTIMESTAMPS", False) 
    18501949        self.showdata = self._getenvbool("LL_MAKE_SHOWDATA", False) 
     1950        self.growl = self._getenvbool("LL_MAKE_GROWL", False) 
    18511951 
    18521952    def __repr__(self): 
     
    18961996    class showstep(misc.propclass): 
    18971997        """ 
    1898         This property specifies which for which actions tranformation steps 
    1899         should be reported during the build process. For allowed values on 
    1900         setting see :prop:`showaction`. 
     1998        This property specifies for which actions tranformation steps should be 
     1999        reported during the build process. For allowed values on setting see 
     2000        :prop:`showaction`. 
    19012001        """ 
    19022002        def __get__(self): 
     
    21672267        This can be overwritten in subclasses to add more options. 
    21682268        """ 
     2269 
     2270        def action2name(action): 
     2271            if action is None: 
     2272                return "none" 
     2273            elif action is Action: 
     2274                return "all" 
     2275            elif issubclass(FileAction, action) and issubclass(PhonyAction, action): 
     2276                return "filephony" 
     2277            elif issubclass(FileAction, action): 
     2278                return "file" 
     2279            elif issubclass(PhonyAction, action): 
     2280                return "phony" 
     2281            else: 
     2282                return "all" 
     2283 
     2284        actions = ["all", "file", "phony", "filephony", "none"] 
    21692285        p = optparse.OptionParser(usage="usage: %prog [options] [targets]") 
    21702286        p.add_option("-x", "--ignore", dest="ignoreerrors", help="Ignore errors", action="store_true", default=None) 
     
    21722288        p.add_option("-c", "--color", dest="color", help="Use colored output", action="store_true", default=None) 
    21732289        p.add_option("-C", "--nocolor", dest="color", help="No colored output", action="store_false", default=None) 
    2174         p.add_option("-a", "--showaction", dest="showaction", help="Show actions?", choices=["all", "file", "filephony", "none"], default="filephony") 
    2175         p.add_option("-s", "--showstep", dest="showstep", help="Show steps?", choices=["all", "file", "filephony", "none"], default="all") 
    2176         p.add_option("-n", "--shownote", dest="shownote", help="Show steps?", choices=["all", "file", "filephony", "none"], default="none") 
    2177         p.add_option("-i", "--showidle", dest="showidle", help="Show actions that didn't produce data?", action="store_true", default=False) 
    2178         p.add_option("-d", "--showdata", dest="showdata", help="Show data?", action="store_true", default=False) 
     2290        p.add_option("-g", "--growl", dest="growl", help="Issue growl notification after the build?", action="store_true", default=None) 
     2291        p.add_option("-a", "--showaction", dest="showaction", help="Show actions (%s)?" % ", ".join(actions), choices=actions, default=action2name(self.showaction)) 
     2292        p.add_option("-s", "--showstep", dest="showstep", help="Show steps (%s)?" % ", ".join(actions), choices=actions, default=action2name(self.showstep)) 
     2293        p.add_option("-n", "--shownote", dest="shownote", help="Show notes (%s)?" % ", ".join(actions), choices=actions, default=action2name(self.shownote)) 
     2294        p.add_option("-r", "--showregistration", dest="showregistration", help="Show registration (%s)?" % ", ".join(actions), choices=actions, default=action2name(self.showregistration)) 
     2295        p.add_option("-i", "--showidle", dest="showidle", help="Show actions that didn't produce data?", action="store_true", default=self.showidle) 
     2296        p.add_option("-d", "--showdata", dest="showdata", help="Show data?", action="store_true", default=self.showdata) 
    21792297        return p 
    21802298 
     
    21912309        if options.color is not None: 
    21922310            self.color = options.color 
    2193         if options.showaction is not None: 
    2194             self.showaction = options.showaction 
    2195         if options.showstep is not None: 
    2196             self.showstep = options.showstep 
    2197         if options.shownote is not None: 
    2198             self.shownote = options.shownote 
     2311        if self.growl is not None: 
     2312            self.growl = options.growl 
     2313        self.showaction = options.showaction 
     2314        self.showstep = options.showstep 
     2315        self.shownote = options.shownote 
     2316        self.showregistration = options.showregistration 
    21992317        self.showidle = options.showidle 
    22002318        self.showdata = options.showdata 
     
    22832401                    self.write(" [t+", self.strtimedelta(now-self.starttime), "]") 
    22842402                self.writeln() 
     2403            if self.growl: 
     2404                filename = os.path.abspath(sys.modules[self.__class__.__module__].__file__) 
     2405                cmd = "growlnotify -i py -n ll.make 'll.make done in %s'" % self.strtimedelta(now-self.starttime) 
     2406                import subprocess 
     2407                pipe = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE).stdin 
     2408                pipe.write("%s\n" % filename) 
     2409                pipe.write("%s.%s\n" % (self.__class__.__module__, self.__class__.__name__)) 
     2410                pipe.write("%d registered targets, " % len(self)) 
     2411                pipe.write("%d actions called, " % self.actionscalled) 
     2412                pipe.write("%d steps executed, " % self.stepsexecuted) 
     2413                pipe.write("%d files/%d bytes read, " % (self.filesread, self.bytesread)) 
     2414                pipe.write("%d files/%d bytes written, " % (self.fileswritten, self.byteswritten)) 
     2415                pipe.write("%d actions failed" % self.actionsfailed) 
     2416                pipe.close() 
    22852417 
    22862418    def buildwithargs(self, commandline=None): 
  • site/ll/misc.py

    r9 r27  
    22# -*- coding: utf-8 -*- 
    33 
    4 ## Copyright 2004-2008 by LivingLogic AG, Bayreuth/Germany. 
    5 ## Copyright 2004-2008 by Walter Dörwald 
     4## Copyright 2004-2009 by LivingLogic AG, Bayreuth/Germany. 
     5## Copyright 2004-2009 by Walter Dörwald 
    66## 
    77## All Rights Reserved 
  • site/ll/scripts/__init__.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/scripts/ucp.py

    r9 r27  
    33 
    44 
    5 ## Copyright 2007-2008 by LivingLogic AG, Bayreuth/Germany. 
    6 ## Copyright 2007-2008 by Walter Dörwald 
     5## Copyright 2007-2009 by LivingLogic AG, Bayreuth/Germany. 
     6## Copyright 2007-2009 by Walter Dörwald 
    77## 
    88## All Rights Reserved 
  • site/ll/sisyphus.py

    r9 r27  
    22# -*- coding: utf-8 -*- 
    33 
    4 ## Copyright 2000-2008 by LivingLogic AG, Bayreuth/Germany. 
    5 ## Copyright 2000-2008 by Walter Dörwald 
     4## Copyright 2000-2009 by LivingLogic AG, Bayreuth/Germany. 
     5## Copyright 2000-2009 by Walter Dörwald 
    66## 
    77## All Rights Reserved 
  • site/ll/toxicc.py

    r9 r27  
    22# -*- coding: utf-8 -*- 
    33 
    4 ## Copyright 2004-2008 by LivingLogic AG, Bayreuth/Germany. 
    5 ## Copyright 2004-2008 by Walter Dörwald 
     4## Copyright 2004-2009 by LivingLogic AG, Bayreuth/Germany. 
     5## Copyright 2004-2009 by Walter Dörwald 
    66## 
    77## All Rights Reserved 
  • site/ll/ul4c.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 2008 by Walter Dörwald 
     3## Copyright 2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
     
    2626import re, datetime, StringIO, locale 
    2727 
    28 from ll import spark 
     28from ll import spark, color 
    2929 
    3030 
     
    8585        return "<%s.%s %s at 0x%x>" % (self.__class__.__module__, self.__class__.__name__, self, id(self)) 
    8686 
    87     def __str__(self): 
     87    def pos(self): 
    8888        lastlinefeed = self.source.rfind("\n", 0, self.starttag) 
    8989        if lastlinefeed >= 0: 
    90             line = self.source.count("\n", 0, self.starttag)+1 
    91             col = self.starttag - lastlinefeed 
     90            return (self.source.count("\n", 0, self.starttag)+1, self.starttag-lastlinefeed) 
    9291        else: 
    93             line = 1 
    94             col = self.starttag + 1 
     92            return (1, self.starttag + 1) 
     93 
     94    def __str__(self): 
     95        (line, col) = self.pos() 
    9596        return "%r at %d (line %d, col %d)" % (self.tag, self.starttag+1, line, col) 
    9697 
     
    169170    """ 
    170171    Exception that is raised by the renderer if the function to be executed by 
    171     the ``callfunc0``, ``callfunc1``, ``callfunc2`` or ``callfunc3`` opcodes is 
    172     unknown. 
     172    the ``callfunc0``, ``callfunc1``, ``callfunc2``, ``callfunc3`` or 
     173    ``callfunc4`` opcodes is unknown. 
    173174    """ 
    174175 
     
    268269        Load the date value :attr:`arg` into register :attr:`r1`. :attr:`arg` must 
    269270        be in ISO format (e.g. ``2008-07-02T11:05:55.460464``). 
     271 
     272    ``"loadcolor"``: 
     273        Load the color value :attr:`arg` into register :attr:`r1`. :attr:`arg` must 
     274        be in the format ``rrggbbaa``). 
    270275 
    271276    ``"buildlist"``: 
     
    415420        :attr:`r2`, :attr:`r3` and :attr:`r4` as the three arguments and store 
    416421        the return value in register :attr:`r1`. 
     422 
     423    ``"callfunc4"``: 
     424        Call the function named :attr:`arg` with the contents of register 
     425        :attr:`r2`, :attr:`r3`, :attr:`r4` and :attr:`r5` as the four arguments 
     426        and store the return value in register :attr:`r1`. 
    417427 
    418428    ``"callmeth0"``: 
     
    485495        elif self.code == "loaddate": 
    486496            return "r%r = %s" % (self.r1, self.arg) 
     497        elif self.code == "loadcolor": 
     498            return "r%r = #%s" % (self.r1, self.arg) 
    487499        elif self.code == "buildlist": 
    488500            return "r%r = []" % (self.r1) 
     
    571583        elif self.code == "mod": 
    572584            return "r%r = r%r %% r%r" % (self.r1, self.r2, self.r3) 
     585        elif self.code == "neg": 
     586            return "r%r = -r%r" % (self.r1, self.r2) 
    573587        elif self.code == "callfunc0": 
    574588            return "r%r = %s()" % (self.r1, self.arg) 
     
    579593        elif self.code == "callfunc3": 
    580594            return "r%r = %s(r%r, r%r, r%r)" % (self.r1, self.arg, self.r2, self.r3, self.r4) 
     595        elif self.code == "callfunc4": 
     596            return "r%r = %s(r%r, r%r, r%r, r%r)" % (self.r1, self.arg, self.r2, self.r3, self.r4, self.r5) 
    581597        elif self.code == "callmeth0": 
    582598            return "r%r = r%r.%s()" % (self.r1, self.r2, self.arg) 
     
    604620 
    605621    Rendering the template can be done with the methods :meth:`render` (which 
    606     returns a generator) or :meth:`renders` (which returns a string). 
    607     """ 
    608     version = "6" 
     622    is a generator) or :meth:`renders` (which returns a string). 
     623    """ 
     624    version = "7" 
    609625 
    610626    def __init__(self): 
     
    775791        return "".join(self.iterdump()) 
    776792 
     793    def _pythonsource_dispatch_None(self, opcode): 
     794        self.lines.append("%syield %r" % (self.indent, opcode.location.code)) 
     795 
     796    def _pythonsource_dispatch_loadstr(self, opcode): 
     797        self.lines.append("%sreg%d = %r" % (self.indent, opcode.r1, opcode.arg)) 
     798 
     799    def _pythonsource_dispatch_loadint(self, opcode): 
     800        self.lines.append("%sreg%d = %s" % (self.indent, opcode.r1, opcode.arg)) 
     801 
     802    def _pythonsource_dispatch_loadfloat(self, opcode): 
     803        self.lines.append("%sreg%d = %s" % (self.indent, opcode.r1, opcode.arg)) 
     804 
     805    def _pythonsource_dispatch_loadnone(self, opcode): 
     806        self.lines.append("%sreg%d = None" % (self.indent, opcode.r1)) 
     807 
     808    def _pythonsource_dispatch_loadfalse(self, opcode): 
     809        self.lines.append("%sreg%d = False" % (self.indent, opcode.r1)) 
     810 
     811    def _pythonsource_dispatch_loadtrue(self, opcode): 
     812        self.lines.append("%sreg%d = True" % (self.indent, opcode.r1)) 
     813 
     814    def _pythonsource_dispatch_loaddate(self, opcode): 
     815        self.lines.append("%sreg%d = datetime.datetime(%s)" % (self.indent, opcode.r1, ", ".join(str(int(p)) for p in datesplitter.split(opcode.arg)))) 
     816 
     817    def _pythonsource_dispatch_loadcolor(self, opcode): 
     818        self.lines.append("%sreg%d = color.Color(0x%s, 0x%s, 0x%s, 0x%s)" % (self.indent, opcode.r1, opcode.arg[:2], opcode.arg[2:4], opcode.arg[4:6], opcode.arg[6:])) 
     819 
     820    def _pythonsource_dispatch_buildlist(self, opcode): 
     821        self.lines.append("%sreg%d = []" % (self.indent, opcode.r1)) 
     822 
     823    def _pythonsource_dispatch_builddict(self, opcode): 
     824        self.lines.append("%sreg%d = {}" % (self.indent, opcode.r1)) 
     825 
     826    def _pythonsource_dispatch_addlist(self, opcode): 
     827        self.lines.append("%sreg%d.append(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     828 
     829    def _pythonsource_dispatch_adddict(self, opcode): 
     830        self.lines.append("%sreg%d[reg%d] = reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     831 
     832    def _pythonsource_dispatch_updatedict(self, opcode): 
     833        self.lines.append("%sreg%d.update(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     834 
     835    def _pythonsource_dispatch_loadvar(self, opcode): 
     836        self.lines.append("%sreg%d = variables[%r]" % (self.indent, opcode.r1, opcode.arg)) 
     837 
     838    def _pythonsource_dispatch_storevar(self, opcode): 
     839        self.lines.append("%svariables[%r] = reg%d" % (self.indent, opcode.arg, opcode.r1)) 
     840 
     841    def _pythonsource_dispatch_addvar(self, opcode): 
     842        self.lines.append("%svariables[%r] += reg%d" % (self.indent, opcode.arg, opcode.r1)) 
     843 
     844    def _pythonsource_dispatch_subvar(self, opcode): 
     845        self.lines.append("%svariables[%r] -= reg%d" % (self.indent, opcode.arg, opcode.r1)) 
     846 
     847    def _pythonsource_dispatch_mulvar(self, opcode): 
     848        self.lines.append("%svariables[%r] *= reg%d" % (self.indent, opcode.arg, opcode.r1)) 
     849 
     850    def _pythonsource_dispatch_truedivvar(self, opcode): 
     851        self.lines.append("%svariables[%r] /= reg%d" % (self.indent, opcode.arg, opcode.r1)) 
     852 
     853    def _pythonsource_dispatch_floordivvar(self, opcode): 
     854        self.lines.append("%svariables[%r] //= reg%d" % (self.indent, opcode.arg, opcode.r1)) 
     855 
     856    def _pythonsource_dispatch_modvar(self, opcode): 
     857        self.lines.append("%svariables[%r] %%= reg%d" % (self.indent, opcode.arg, opcode.r1)) 
     858 
     859    def _pythonsource_dispatch_delvar(self, opcode): 
     860        self.lines.append("%sdel variables[%r]" % (self.indent, opcode.arg)) 
     861 
     862    def _pythonsource_dispatch_getattr(self, opcode): 
     863        self.lines.append("%sreg%d = reg%d[%r]" % (self.indent, opcode.r1, opcode.r2, opcode.arg)) 
     864 
     865    def _pythonsource_dispatch_getitem(self, opcode): 
     866        self.lines.append("%sreg%d = reg%d[reg%d]" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     867 
     868    def _pythonsource_dispatch_getslice12(self, opcode): 
     869        self.lines.append("%sreg%d = reg%d[reg%d:reg%d]" % (self.indent, opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     870 
     871    def _pythonsource_dispatch_getslice1(self, opcode): 
     872        self.lines.append("%sreg%d = reg%d[reg%d:]" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     873 
     874    def _pythonsource_dispatch_getslice2(self, opcode): 
     875        self.lines.append("%sreg%d = reg%d[:reg%d]" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     876 
     877    def _pythonsource_dispatch_print(self, opcode): 
     878        self.lines.append("%sif reg%d is not None: yield unicode(reg%d)" % (self.indent, opcode.r1, opcode.r1)) 
     879 
     880    def _pythonsource_dispatch_printx(self, opcode): 
     881        self.lines.append("%sif reg%d is not None: yield xmlescape(unicode(reg%d))" % (self.indent, opcode.r1, opcode.r1)) 
     882 
     883    def _pythonsource_dispatch_for(self, opcode): 
     884        self.lines.append("%sfor reg%d in reg%d:" % (self.indent, opcode.r1, opcode.r2)) 
     885        self.indent += "\t" 
     886 
     887    def _pythonsource_dispatch_endfor(self, opcode): 
     888        # we don't have to check for empty loops here, as a ``<?for?>`` tag always generates at least one ``storevar`` opcode inside the loop 
     889        self.indent = self.indent[:-1] 
     890        self.lines.append("%s# end for" % self.indent) 
     891 
     892    def _pythonsource_dispatch_break(self, opcode): 
     893        self.lines.append("%sbreak" % self.indent) 
     894 
     895    def _pythonsource_dispatch_continue(self, opcode): 
     896        self.lines.append("%scontinue" % self.indent) 
     897 
     898    def _pythonsource_dispatch_not(self, opcode): 
     899        self.lines.append("%sreg%d = not reg%d" % (self.indent, opcode.r1, opcode.r2)) 
     900 
     901    def _pythonsource_dispatch_neg(self, opcode): 
     902        self.lines.append("%sreg%d = -reg%d" % (self.indent, opcode.r1, opcode.r2)) 
     903 
     904    def _pythonsource_dispatch_contains(self, opcode): 
     905        self.lines.append("%sreg%d = reg%d in reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     906 
     907    def _pythonsource_dispatch_notcontains(self, opcode): 
     908        self.lines.append("%sreg%d = reg%d not in reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     909 
     910    def _pythonsource_dispatch_eq(self, opcode): 
     911        self.lines.append("%sreg%d = reg%d == reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     912 
     913    def _pythonsource_dispatch_ne(self, opcode): 
     914        self.lines.append("%sreg%d = reg%d != reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     915 
     916    def _pythonsource_dispatch_lt(self, opcode): 
     917        self.lines.append("%sreg%d = reg%d < reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     918 
     919    def _pythonsource_dispatch_le(self, opcode): 
     920        self.lines.append("%sreg%d = reg%d <= reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     921 
     922    def _pythonsource_dispatch_gt(self, opcode): 
     923        self.lines.append("%sreg%d = reg%d > reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     924 
     925    def _pythonsource_dispatch_ge(self, opcode): 
     926        self.lines.append("%sreg%d = reg%d >= reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     927 
     928    def _pythonsource_dispatch_add(self, opcode): 
     929        self.lines.append("%sreg%d = reg%d + reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     930 
     931    def _pythonsource_dispatch_sub(self, opcode): 
     932        self.lines.append("%sreg%d = reg%d - reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     933 
     934    def _pythonsource_dispatch_mul(self, opcode): 
     935        self.lines.append("%sreg%d = reg%d * reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     936 
     937    def _pythonsource_dispatch_floordiv(self, opcode): 
     938        self.lines.append("%sreg%d = reg%d // reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     939 
     940    def _pythonsource_dispatch_truediv(self, opcode): 
     941        self.lines.append("%sreg%d = reg%d / reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     942 
     943    def _pythonsource_dispatch_and(self, opcode): 
     944        self.lines.append("%sreg%d = reg%d and reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     945 
     946    def _pythonsource_dispatch_or(self, opcode): 
     947        self.lines.append("%sreg%d = reg%d or reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     948 
     949    def _pythonsource_dispatch_mod(self, opcode): 
     950        self.lines.append("%sreg%d = reg%d %% reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     951 
     952    def _pythonsource_dispatch_mod(self, opcode): 
     953        self.lines.append("%sreg%d = reg%d %% reg%d" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     954 
     955    def _pythonsource_dispatch_callfunc0(self, opcode): 
     956        try: 
     957            getattr(self, "_pythonsource_dispatch_callfunc0_%s" % opcode.arg)(opcode) 
     958        except AttributeError: 
     959            raise UnknownFunctionError(opcode.arg) 
     960 
     961    def _pythonsource_dispatch_callfunc1(self, opcode): 
     962        try: 
     963            getattr(self, "_pythonsource_dispatch_callfunc1_%s" % opcode.arg)(opcode) 
     964        except AttributeError: 
     965            raise UnknownFunctionError(opcode.arg) 
     966 
     967    def _pythonsource_dispatch_callfunc2(self, opcode): 
     968        try: 
     969            getattr(self, "_pythonsource_dispatch_callfunc2_%s" % opcode.arg)(opcode) 
     970        except AttributeError: 
     971            raise UnknownFunctionError(opcode.arg) 
     972 
     973    def _pythonsource_dispatch_callfunc3(self, opcode): 
     974        try: 
     975            getattr(self, "_pythonsource_dispatch_callfunc3_%s" % opcode.arg)(opcode) 
     976        except AttributeError: 
     977            raise UnknownFunctionError(opcode.arg) 
     978 
     979    def _pythonsource_dispatch_callfunc4(self, opcode): 
     980        try: 
     981            getattr(self, "_pythonsource_dispatch_callfunc4_%s" % opcode.arg)(opcode) 
     982        except AttributeError: 
     983            raise UnknownFunctionError(opcode.arg) 
     984 
     985    def _pythonsource_dispatch_callmeth0(self, opcode): 
     986        if opcode.arg in ("split", "rsplit", "strip", "lstrip", "rstrip", "upper", "lower", "capitalize", "isoformat", "r", "g", "b", "a", "hls", "hlsa", "hsv", "hsva", "lum"): 
     987            self.lines.append("%sreg%d = reg%d.%s()" % (self.indent, opcode.r1, opcode.r2, opcode.arg)) 
     988        elif opcode.arg == "items": 
     989            self.lines.append("%sreg%d = reg%d.iteritems()" % (self.indent, opcode.r1, opcode.r2)) 
     990        elif opcode.arg == "render": 
     991            self.lines.append('%sreg%d = "".join(reg%d())' % (self.indent, opcode.r1, opcode.r2)) 
     992        else: 
     993            raise UnknownMethodError(opcode.arg) 
     994 
     995    def _pythonsource_dispatch_callmeth1(self, opcode): 
     996        if opcode.arg in ("split", "rsplit", "strip", "lstrip", "rstrip", "startswith", "endswith", "find", "get", "withlum", "witha"): 
     997            self.lines.append("%sreg%d = reg%d.%s(reg%d)" % (self.indent, opcode.r1, opcode.r2, opcode.arg, opcode.r3)) 
     998        elif opcode.arg == "format": 
     999            self.lines.append("%sreg%d = ul4c._format(reg%d, reg%d)" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     1000        elif opcode.arg == "render": 
     1001            self.lines.append('%sreg%d = "".join(reg%d(**dict((key.encode("utf-8"), value) for (key, value) in reg%d.iteritems())))' % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     1002        else: 
     1003            raise UnknownMethodError(opcode.arg) 
     1004 
     1005    def _pythonsource_dispatch_callmeth2(self, opcode): 
     1006        if opcode.arg in ("split", "rsplit", "find", "replace", "get"): 
     1007            self.lines.append("%sreg%d = reg%d.%s(reg%d, reg%d)" % (self.indent, opcode.r1, opcode.r2, opcode.arg, opcode.r3, opcode.r4)) 
     1008        else: 
     1009            raise UnknownMethodError(opcode.arg) 
     1010 
     1011    def _pythonsource_dispatch_callmeth3(self, opcode): 
     1012        if opcode.arg == "find": 
     1013            self.lines.append("%sreg%d = reg%d.%s(reg%d, reg%d, reg%d)" % (self.indent, opcode.r1, opcode.r2, opcode.arg, opcode.r3, opcode.r4, opcode.r5)) 
     1014        else: 
     1015            raise UnknownMethodError(opcode.arg) 
     1016 
     1017    def _pythonsource_dispatch_if(self, opcode): 
     1018        self.lines.append("%sif reg%d:" % (self.indent, opcode.r1)) 
     1019        self.indent += "\t" 
     1020 
     1021    def _pythonsource_dispatch_else(self, opcode): 
     1022        if self.lastopcode == "if": 
     1023            self.lines[-1] += " pass" 
     1024        self.indent = self.indent[:-1] 
     1025        self.lines.append("%selse:" % self.indent) 
     1026        self.indent += "\t" 
     1027 
     1028    def _pythonsource_dispatch_endif(self, opcode): 
     1029        if self.lastopcode in ("if", "else"): 
     1030            self.lines[-1] += " pass" 
     1031        self.indent = self.indent[:-1] 
     1032        self.lines.append("%s# end if" % self.indent) 
     1033 
     1034    def _pythonsource_dispatch_render(self, opcode): 
     1035        self.lines.append('%sfor chunk in reg%d(**dict((key.encode("utf-8"), value) for (key, value) in reg%d.iteritems())): yield chunk' % (self.indent, opcode.r1, opcode.r2)) 
     1036 
     1037    def _pythonsource_dispatch_callfunc0_now(self, opcode): 
     1038        self.lines.append("%sreg%d = datetime.datetime.now()" % (self.indent, opcode.r1)) 
     1039 
     1040    def _pythonsource_dispatch_callfunc0_vars(self, opcode): 
     1041        self.lines.append("%sreg%d = variables" % (self.indent, opcode.r1)) 
     1042 
     1043    def _pythonsource_dispatch_callfunc1_xmlescape(self, opcode): 
     1044        self.lines.append("%sreg%d = xmlescape(unicode(reg%d)) if reg%d is not None else u''" % (self.indent, opcode.r1, opcode.r2, opcode.r2)) 
     1045 
     1046    def _pythonsource_dispatch_callfunc1_csv(self, opcode): 
     1047        self.lines.append("%sreg%d = ul4c._csv(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1048 
     1049    def _pythonsource_dispatch_callfunc1_json(self, opcode): 
     1050        self.lines.append("%sreg%d = json.dumps(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1051 
     1052    def _pythonsource_dispatch_callfunc1_str(self, opcode): 
     1053        self.lines.append("%sreg%d = unicode(reg%d) if reg%d is not None else u''" % (self.indent, opcode.r1, opcode.r2, opcode.r2)) 
     1054 
     1055    def _pythonsource_dispatch_callfunc1_int(self, opcode): 
     1056        self.lines.append("%sreg%d = int(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1057 
     1058    def _pythonsource_dispatch_callfunc1_bool(self, opcode): 
     1059        self.lines.append("%sreg%d = bool(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1060 
     1061    def _pythonsource_dispatch_callfunc1_len(self, opcode): 
     1062        self.lines.append("%sreg%d = len(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1063 
     1064    def _pythonsource_dispatch_callfunc1_enumerate(self, opcode): 
     1065        self.lines.append("%sreg%d = enumerate(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1066 
     1067    def _pythonsource_dispatch_callfunc1_isnone(self, opcode): 
     1068        self.lines.append("%sreg%d = reg%d is None" % (self.indent, opcode.r1, opcode.r2)) 
     1069 
     1070    def _pythonsource_dispatch_callfunc1_isstr(self, opcode): 
     1071        self.lines.append("%sreg%d = isinstance(reg%d, basestring)" % (self.indent, opcode.r1, opcode.r2)) 
     1072 
     1073    def _pythonsource_dispatch_callfunc1_isint(self, opcode): 
     1074        self.lines.append("%sreg%d = isinstance(reg%d, (int, long)) and not isinstance(reg%d, bool)" % (self.indent, opcode.r1, opcode.r2, opcode.r2)) 
     1075 
     1076    def _pythonsource_dispatch_callfunc1_isfloat(self, opcode): 
     1077        self.lines.append("%sreg%d = isinstance(reg%d, float)" % (self.indent, opcode.r1, opcode.r2)) 
     1078 
     1079    def _pythonsource_dispatch_callfunc1_isbool(self, opcode): 
     1080        self.lines.append("%sreg%d = isinstance(reg%d, bool)" % (self.indent, opcode.r1, opcode.r2)) 
     1081 
     1082    def _pythonsource_dispatch_callfunc1_isdate(self, opcode): 
     1083        self.lines.append("%sreg%d = isinstance(reg%d, datetime.datetime)" % (self.indent, opcode.r1, opcode.r2)) 
     1084 
     1085    def _pythonsource_dispatch_callfunc1_islist(self, opcode): 
     1086        self.lines.append("%sreg%d = isinstance(reg%d, (list, tuple))" % (self.indent, opcode.r1, opcode.r2)) 
     1087 
     1088    def _pythonsource_dispatch_callfunc1_isdict(self, opcode): 
     1089        self.lines.append("%sreg%d = isinstance(reg%d, dict)" % (self.indent, opcode.r1, opcode.r2)) 
     1090 
     1091    def _pythonsource_dispatch_callfunc1_istemplate(self, opcode): 
     1092        self.lines.append("%sreg%d = hasattr(reg%d, '__call__')" % (self.indent, opcode.r1, opcode.r2)) # this supports normal generators too 
     1093 
     1094    def _pythonsource_dispatch_callfunc1_repr(self, opcode): 
     1095        self.lines.append("%sreg%d = ul4c._repr(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1096 
     1097    def _pythonsource_dispatch_callfunc1_get(self, opcode): 
     1098        self.lines.append("%sreg%d = variables.get(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1099 
     1100    def _pythonsource_dispatch_callfunc1_chr(self, opcode): 
     1101        self.lines.append("%sreg%d = unichr(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1102 
     1103    def _pythonsource_dispatch_callfunc1_ord(self, opcode): 
     1104        self.lines.append("%sreg%d = ord(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1105 
     1106    def _pythonsource_dispatch_callfunc1_hex(self, opcode): 
     1107        self.lines.append("%sreg%d = hex(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1108 
     1109    def _pythonsource_dispatch_callfunc1_oct(self, opcode): 
     1110        self.lines.append("%sreg%d = ul4c._oct(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1111 
     1112    def _pythonsource_dispatch_callfunc1_bin(self, opcode): 
     1113        self.lines.append("%sreg%d = ul4c._bin(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1114 
     1115    def _pythonsource_dispatch_callfunc1_sorted(self, opcode): 
     1116        self.lines.append("%sreg%d = sorted(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1117 
     1118    def _pythonsource_dispatch_callfunc1_range(self, opcode): 
     1119        self.lines.append("%sreg%d = xrange(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1120 
     1121    def _pythonsource_dispatch_callfunc1_type(self, opcode): 
     1122        self.lines.append("%sreg%d = ul4c._type(reg%d)" % (self.indent, opcode.r1, opcode.r2)) 
     1123 
     1124    def _pythonsource_dispatch_callfunc2_range(self, opcode): 
     1125        self.lines.append("%sreg%d = xrange(reg%d, reg%d)" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     1126 
     1127    def _pythonsource_dispatch_callfunc2_get(self, opcode): 
     1128        self.lines.append("%sreg%d = variables.get(reg%d, reg%d)" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     1129 
     1130    def _pythonsource_dispatch_callfunc2_zip(self, opcode): 
     1131        self.lines.append("%sreg%d = itertools.izip(reg%d, reg%d)" % (self.indent, opcode.r1, opcode.r2, opcode.r3)) 
     1132 
     1133    def _pythonsource_dispatch_callfunc3_range(self, opcode): 
     1134        self.lines.append("%sreg%d = xrange(reg%d, reg%d, reg%d)" % (self.indent, opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     1135 
     1136    def _pythonsource_dispatch_callfunc3_zip(self, opcode): 
     1137        self.lines.append("%sreg%d = itertools.izip(reg%d, reg%d, reg%d)" % (self.indent, opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     1138 
     1139    def _pythonsource_dispatch_callfunc3_rgb(self, opcode): 
     1140        self.lines.append("%sreg%d = color.Color.fromrgb(reg%d, reg%d, reg%d)" % (self.indent, opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     1141 
     1142    def _pythonsource_dispatch_callfunc3_hls(self, opcode): 
     1143        self.lines.append("%sreg%d = color.Color.fromhls(reg%d, reg%d, reg%d)" % (self.indent, opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     1144 
     1145    def _pythonsource_dispatch_callfunc3_hsv(self, opcode): 
     1146        self.lines.append("%sreg%d = color.Color.fromhsv(reg%d, reg%d, reg%d)" % (self.indent, opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     1147 
     1148    def _pythonsource_dispatch_callfunc4_rgb(self, opcode): 
     1149        self.lines.append("%sreg%d = color.Color.fromrgb(reg%d, reg%d, reg%d, reg%d)" % (self.indent, opcode.r1, opcode.r2, opcode.r3, opcode.r4, opcode.r5)) 
     1150 
     1151    def _pythonsource_dispatch_callfunc4_hls(self, opcode): 
     1152        self.lines.append("%sreg%d = color.Color.fromhls(reg%d, reg%d, reg%d, reg%d)" % (self.indent, opcode.r1, opcode.r2, opcode.r3, opcode.r4, opcode.r5)) 
     1153 
     1154    def _pythonsource_dispatch_callfunc4_hsv(self, opcode): 
     1155        self.lines.append("%sreg%d = color.Color.fromhsv(reg%d, reg%d, reg%d, reg%d)" % (self.indent, opcode.r1, opcode.r2, opcode.r3, opcode.r4, opcode.r5)) 
     1156 
    7771157    def pythonsource(self, function=None): 
    7781158        """ 
     
    7801160        the code will be wrapped in a function with this name. 
    7811161        """ 
    782         indent = 0 
    783         output = [] 
    784  
    785         def _code(code): 
    786             output.append("%s%s" % ("\t"*indent, code)) 
     1162        self.indent = "" 
     1163        self.lines = [] 
    7871164 
    7881165        if function is not None: 
    789             _code("def %s(**variables):" % function) 
    790             indent += 1 
    791         _code("import sys, datetime, itertools") 
    792         _code("from ll.misc import xmlescape") 
    793         _code("from ll import ul4c") 
    794         _code("source = %r" % self.source) 
    795         _code('variables = dict((key.decode("utf-8"), value) for (key, value) in variables.iteritems())') # FIXME: This can be dropped in Python 3.0 where strings are unicode 
     1166            self.lines.append("%sdef %s(**variables):" % (self.indent, function)) 
     1167            self.indent += "\t" 
     1168        self.lines.append("%simport sys, datetime, itertools" % self.indent) 
     1169        self.lines.append("%stry:" % self.indent) 
     1170        self.indent += "\t" 
     1171        self.lines.append("%simport json" % self.indent) 
     1172        self.indent = self.indent[:-1] 
     1173        self.lines.append("%sexcept ImportError:" % self.indent) 
     1174        self.indent += "\t" 
     1175        self.lines.append("%simport simplejson as json" % self.indent) 
     1176        self.indent = self.indent[:-1] 
     1177        self.lines.append("%sfrom ll.misc import xmlescape" % self.indent) 
     1178        self.lines.append("%sfrom ll import ul4c, color" % self.indent) 
     1179        self.lines.append("%ssource = %r" % (self.indent, self.source)) 
     1180        self.lines.append('%svariables = dict((key.decode("utf-8"), value) for (key, value) in variables.iteritems())' % self.indent) # FIXME: This can be dropped in Python 3.0 where strings are unicode 
    7961181        locations = [] 
    7971182        lines2locs = [] 
     
    8051190        locations = tuple(locations) 
    8061191        lines2locs = tuple(lines2locs) 
    807         _code("".join("reg%d = " % i for i in xrange(10)) + "None") 
    808  
    809         _code("try:") 
    810         indent += 1 
    811         _code("startline = sys._getframe().f_lineno+1") # The source line of the first opcode 
     1192        self.lines.append("%sreg0 = reg1 = reg2 = reg3 = reg4 = reg5 = reg6 = reg7 = reg8 = reg9 = None" % self.indent) 
     1193        self.lines.append("%stry:" % self.indent) 
     1194        self.indent += "\t" 
     1195        self.lines.append("%sstartline = sys._getframe().f_lineno+1" % self.indent) # The source line of the first opcode 
    8121196        try: 
    813             lastopcode = None 
     1197            self.lastopcode = None 
    8141198            for opcode in self.opcodes: 
    8151199                # The following code ensures that each opcode outputs exactly one source code line 
    8161200                # This makes it possible in case of an error to find out which opcode produced the error 
    817                 if opcode.code is None: 
    818                     _code("yield %r" % opcode.location.code) 
    819                 elif opcode.code == "loadstr": 
    820                     _code("reg%d = %r" % (opcode.r1, opcode.arg)) 
    821                 elif opcode.code == "loadint": 
    822                     _code("reg%d = %s" % (opcode.r1, opcode.arg)) 
    823                 elif opcode.code == "loadfloat": 
    824                     _code("reg%d = %s" % (opcode.r1, opcode.arg)) 
    825                 elif opcode.code == "loadnone": 
    826                     _code("reg%d = None" % opcode.r1) 
    827                 elif opcode.code == "loadfalse": 
    828                     _code("reg%d = False" % opcode.r1) 
    829                 elif opcode.code == "loadtrue": 
    830                     _code("reg%d = True" % opcode.r1) 
    831                 elif opcode.code == "loaddate": 
    832                     _code("reg%d = datetime.datetime(%s)" % (opcode.r1, ", ".join(str(int(p)) for p in datesplitter.split(opcode.arg)))) 
    833                 elif opcode.code == "buildlist": 
    834                     _code("reg%d = []" % opcode.r1) 
    835                 elif opcode.code == "builddict": 
    836                     _code("reg%d = {}" % opcode.r1) 
    837                 elif opcode.code == "addlist": 
    838                     _code("reg%d.append(reg%d)" % (opcode.r1, opcode.r2)) 
    839                 elif opcode.code == "adddict": 
    840                     _code("reg%d[reg%d] = reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    841                 elif opcode.code == "updatedict": 
    842                     _code("reg%d.update(reg%d)" % (opcode.r1, opcode.r2)) 
    843                 elif opcode.code == "loadvar": 
    844                     _code("reg%d = variables[%r]" % (opcode.r1, opcode.arg)) 
    845                 elif opcode.code == "storevar": 
    846                     _code("variables[%r] = reg%d" % (opcode.arg, opcode.r1)) 
    847                 elif opcode.code == "addvar": 
    848                     _code("variables[%r] += reg%d" % (opcode.arg, opcode.r1)) 
    849                 elif opcode.code == "subvar": 
    850                     _code("variables[%r] -= reg%d" % (opcode.arg, opcode.r1)) 
    851                 elif opcode.code == "mulvar": 
    852                     _code("variables[%r] *= reg%d" % (opcode.arg, opcode.r1)) 
    853                 elif opcode.code == "truedivvar": 
    854                     _code("variables[%r] /= reg%d" % (opcode.arg, opcode.r1)) 
    855                 elif opcode.code == "floordivvar": 
    856                     _code("variables[%r] //= reg%d" % (opcode.arg, opcode.r1)) 
    857                 elif opcode.code == "modvar": 
    858                     _code("variables[%r] %%= reg%d" % (opcode.arg, opcode.r1)) 
    859                 elif opcode.code == "delvar": 
    860                     _code("del variables[%r]" % opcode.arg) 
    861                 elif opcode.code == "getattr": 
    862                     _code("reg%d = reg%d[%r]" % (opcode.r1, opcode.r2, opcode.arg)) 
    863                 elif opcode.code == "getitem": 
    864                     _code("reg%d = reg%d[reg%d]" % (opcode.r1, opcode.r2, opcode.r3)) 
    865                 elif opcode.code == "getslice12": 
    866                     _code("reg%d = reg%d[reg%d:reg%d]" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
    867                 elif opcode.code == "getslice1": 
    868                     _code("reg%d = reg%d[reg%d:]" % (opcode.r1, opcode.r2, opcode.r3)) 
    869                 elif opcode.code == "getslice2": 
    870                     _code("reg%d = reg%d[:reg%d]" % (opcode.r1, opcode.r2, opcode.r3)) 
    871                 elif opcode.code == "print": 
    872                     _code("if reg%d is not None: yield unicode(reg%d)" % (opcode.r1, opcode.r1)) 
    873                 elif opcode.code == "printx": 
    874                     _code("if reg%d is not None: yield xmlescape(unicode(reg%d))" % (opcode.r1, opcode.r1)) 
    875                 elif opcode.code == "for": 
    876                     _code("for reg%d in reg%d:" % (opcode.r1, opcode.r2)) 
    877                     indent += 1 
    878                 elif opcode.code == "endfor": 
    879                     # we don't have to check for empty loops here, as a ``<?for?>`` tag always generates at least one ``storevar`` opcode inside the loop 
    880                     indent -= 1 
    881                     _code("# end for") 
    882                 elif opcode.code == "break": 
    883                     _code("break") 
    884                 elif opcode.code == "continue": 
    885                     _code("continue") 
    886                 elif opcode.code == "not": 
    887                     _code("reg%d = not reg%d" % (opcode.r1, opcode.r2)) 
    888                 elif opcode.code == "neg": 
    889                     _code("reg%d = -reg%d" % (opcode.r1, opcode.r2)) 
    890                 elif opcode.code == "contains": 
    891                     _code("reg%d = reg%d in reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    892                 elif opcode.code == "notcontains": 
    893                     _code("reg%d = reg%d not in reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    894                 elif opcode.code == "eq": 
    895                     _code("reg%d = reg%d == reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    896                 elif opcode.code == "ne": 
    897                     _code("reg%d = reg%d != reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    898                 elif opcode.code == "lt": 
    899                     _code("reg%d = reg%d < reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    900                 elif opcode.code == "le": 
    901                     _code("reg%d = reg%d <= reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    902                 elif opcode.code == "gt": 
    903                     _code("reg%d = reg%d > reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    904                 elif opcode.code == "ge": 
    905                     _code("reg%d = reg%d >= reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    906                 elif opcode.code == "add": 
    907                     _code("reg%d = reg%d + reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    908                 elif opcode.code == "sub": 
    909                     _code("reg%d = reg%d - reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    910                 elif opcode.code == "mul": 
    911                     _code("reg%d = reg%d * reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    912                 elif opcode.code == "floordiv": 
    913                     _code("reg%d = reg%d // reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    914                 elif opcode.code == "truediv": 
    915                     _code("reg%d = reg%d / reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    916                 elif opcode.code == "and": 
    917                     _code("reg%d = reg%d and reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    918                 elif opcode.code == "or": 
    919                     _code("reg%d = reg%d or reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    920                 elif opcode.code == "mod": 
    921                     _code("reg%d = reg%d %% reg%d" % (opcode.r1, opcode.r2, opcode.r3)) 
    922                 elif opcode.code == "callfunc0": 
    923                     if opcode.arg == "now": 
    924                         _code("reg%d = datetime.datetime.now()" % opcode.r1) 
    925                     elif opcode.arg == "vars": 
    926                         _code("reg%d = variables" % opcode.r1) 
    927                     else: 
    928                         raise UnknownFunctionError(opcode.arg) 
    929                 elif opcode.code == "callfunc1": 
    930                     if opcode.arg == "xmlescape": 
    931                         _code("reg%d = xmlescape(unicode(reg%d)) if reg%d is not None else u''" % (opcode.r1, opcode.r2, opcode.r2)) 
    932                     elif opcode.arg == "csvescape": 
    933                         _code("reg%d = ul4c._csvescape(reg%d)" % (opcode.r1, opcode.r2)) 
    934                     elif opcode.arg == "str": 
    935                         _code("reg%d = unicode(reg%d) if reg%d is not None else u''" % (opcode.r1, opcode.r2, opcode.r2)) 
    936                     elif opcode.arg == "int": 
    937                         _code("reg%d = int(reg%d)" % (opcode.r1, opcode.r2)) 
    938                     elif opcode.arg == "bool": 
    939                         _code("reg%d = bool(reg%d)" % (opcode.r1, opcode.r2)) 
    940                     elif opcode.arg == "len": 
    941                         _code("reg%d = len(reg%d)" % (opcode.r1, opcode.r2)) 
    942                     elif opcode.arg == "enumerate": 
    943                         _code("reg%d = enumerate(reg%d)" % (opcode.r1, opcode.r2)) 
    944                     elif opcode.arg == "isnone": 
    945                         _code("reg%d = reg%d is None" % (opcode.r1, opcode.r2)) 
    946                     elif opcode.arg == "isstr": 
    947                         _code("reg%d = isinstance(reg%d, basestring)" % (opcode.r1, opcode.r2)) 
    948                     elif opcode.arg == "isint": 
    949                         _code("reg%d = isinstance(reg%d, (int, long)) and not isinstance(reg%d, bool)" % (opcode.r1, opcode.r2, opcode.r2)) 
    950                     elif opcode.arg == "isfloat": 
    951                         _code("reg%d = isinstance(reg%d, float)" % (opcode.r1, opcode.r2)) 
    952                     elif opcode.arg == "isbool": 
    953                         _code("reg%d = isinstance(reg%d, bool)" % (opcode.r1, opcode.r2)) 
    954                     elif opcode.arg == "isdate": 
    955                         _code("reg%d = isinstance(reg%d, datetime.datetime)" % (opcode.r1, opcode.r2)) 
    956                     elif opcode.arg == "islist": 
    957                         _code("reg%d = isinstance(reg%d, (list, tuple))" % (opcode.r1, opcode.r2)) 
    958                     elif opcode.arg == "isdict": 
    959                         _code("reg%d = isinstance(reg%d, dict)" % (opcode.r1, opcode.r2)) 
    960                     elif opcode.arg == "istemplate": 
    961                         _code("reg%d = hasattr(reg%d, '__call__')" % (opcode.r1, opcode.r2)) # this supports normal generators too. 
    962                     elif opcode.arg == "repr": 
    963                         _code("reg%d = ul4c._repr(reg%d)" % (opcode.r1, opcode.r2)) 
    964                     elif opcode.arg == "get": 
    965                         _code("reg%d = variables.get(reg%d)" % (opcode.r1, opcode.r2)) 
    966                     elif opcode.arg == "chr": 
    967                         _code("reg%d = unichr(reg%d)" % (opcode.r1, opcode.r2)) 
    968                     elif opcode.arg == "ord": 
    969                         _code("reg%d = ord(reg%d)" % (opcode.r1, opcode.r2)) 
    970                     elif opcode.arg == "hex": 
    971                         _code("reg%d = hex(reg%d)" % (opcode.r1, opcode.r2)) 
    972                     elif opcode.arg == "oct": 
    973                         _code('reg%d = ul4c._oct(reg%d)' % (opcode.r1, opcode.r2)) 
    974                     elif opcode.arg == "bin": 
    975                         _code('reg%d = ul4c._bin(reg%d)' % (opcode.r1, opcode.r2)) 
    976                     elif opcode.arg == "sorted": 
    977                         _code("reg%d = sorted(reg%d)" % (opcode.r1, opcode.r2)) 
    978                     elif opcode.arg == "range": 
    979                         _code("reg%d = xrange(reg%d)" % (opcode.r1, opcode.r2)) 
    980                     elif opcode.arg == "type": 
    981                         _code("reg%d = ul4c._type(reg%d)" % (opcode.r1, opcode.r2)) 
    982                     else: 
    983                         raise UnknownFunctionError(opcode.arg) 
    984                 elif opcode.code == "callfunc2": 
    985                     if opcode.arg == "range": 
    986                         _code("reg%d = xrange(reg%d, reg%d)" % (opcode.r1, opcode.r2, opcode.r3)) 
    987                     elif opcode.arg == "get": 
    988                         _code("reg%d = variables.get(reg%d, reg%d)" % (opcode.r1, opcode.r2, opcode.r3)) 
    989                     elif opcode.arg == "zip": 
    990                         _code("reg%d = itertools.izip(reg%d, reg%d)" % (opcode.r1, opcode.r2, opcode.r3)) 
    991                     else: 
    992                         raise UnknownFunctionError(opcode.arg) 
    993                 elif opcode.code == "callfunc3": 
    994                     if opcode.arg == "range": 
    995                         _code("reg%d = xrange(reg%d, reg%d, reg%d)" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
    996                     elif opcode.arg == "zip": 
    997                         _code("reg%d = itertools.izip(reg%d, reg%d, reg%d)" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
    998                     else: 
    999                         raise UnknownFunctionError(opcode.arg) 
    1000                 elif opcode.code == "callmeth0": 
    1001                     if opcode.arg in ("split", "rsplit", "strip", "lstrip", "rstrip", "upper", "lower", "capitalize", "isoformat"): 
    1002                         _code("reg%d = reg%d.%s()" % (opcode.r1, opcode.r2, opcode.arg)) 
    1003                     elif opcode.arg == "items": 
    1004                         _code("reg%d = reg%d.iteritems()" % (opcode.r1, opcode.r2)) 
    1005                     else: 
    1006                         raise UnknownMethodError(opcode.arg) 
    1007                 elif opcode.code == "callmeth1": 
    1008                     if opcode.arg in ("split", "rsplit", "strip", "lstrip", "rstrip", "startswith", "endswith", "find", "get"): 
    1009                         _code("reg%d = reg%d.%s(reg%d)" % (opcode.r1, opcode.r2, opcode.arg, opcode.r3)) 
    1010                     elif opcode.arg == "format": 
    1011                         _code("reg%d = ul4c._format(reg%d, reg%d)" % (opcode.r1, opcode.r2, opcode.r3)) 
    1012                     else: 
    1013                         raise UnknownMethodError(opcode.arg) 
    1014                 elif opcode.code == "callmeth2": 
    1015                     if opcode.arg in ("split", "rsplit", "find", "replace", "get"): 
    1016                         _code("reg%d = reg%d.%s(reg%d, reg%d)" % (opcode.r1, opcode.r2, opcode.arg, opcode.r3, opcode.r4)) 
    1017                     else: 
    1018                         raise UnknownMethodError(opcode.arg) 
    1019                 elif opcode.code == "callmeth3": 
    1020                     if opcode.arg == "find": 
    1021                         _code("reg%d = reg%d.%s(reg%d, reg%d, reg%d)" % (opcode.r1, opcode.r2, opcode.arg, opcode.r3, opcode.r4, opcode.r5)) 
    1022                     else: 
    1023                         raise UnknownMethodError(opcode.arg) 
    1024                 elif opcode.code == "if": 
    1025                     _code("if reg%d:" % opcode.r1) 
    1026                     indent += 1 
    1027                 elif opcode.code == "else": 
    1028                     if lastopcode == "if": 
    1029                         output[-1] += " pass" 
    1030                     indent -= 1 
    1031                     _code("else:") 
    1032                     indent += 1 
    1033                 elif opcode.code == "endif": 
    1034                     if lastopcode in ("if", "else"): 
    1035                         output[-1] += " pass" 
    1036                     indent -= 1 
    1037                     _code("# end if") 
    1038                 elif opcode.code == "render": 
    1039                     _code('for chunk in reg%d(**dict((key.encode("utf-8"), value) for (key, value) in reg%d.iteritems())): yield chunk' % (opcode.r1, opcode.r2)) 
    1040                 else: 
     1201                try: 
     1202                    getattr(self, "_pythonsource_dispatch_%s" % opcode.code)(opcode) 
     1203                except AttributeError: 
    10411204                    raise UnknownOpcodeError(opcode.code) 
    1042                 lastopcode = opcode.code 
     1205                self.lastopcode = opcode.code 
    10431206        except Exception, exc: 
    1044             raise Error(opcode.location, exc) 
    1045         indent -= 1 
    1046         _code("except Exception, exc:") 
    1047         indent += 1 
    1048         _code("locations = %r" % (locations,)) 
    1049         _code("lines2locs = %r" % (lines2locs,)) 
    1050         _code("raise ul4c.Error(ul4c.Location(source, *locations[lines2locs[sys.exc_info()[2].tb_lineno-startline]]), exc)") 
    1051         return "\n".join(output) 
     1207            raise #Error(opcode.location, exc) 
     1208        self.indent = self.indent[:-1] 
     1209        self.lines.append("%sexcept Exception, exc:" % self.indent) 
     1210        self.indent += "\t" 
     1211        self.lines.append("%slocations = %r" % (self.indent, locations)) 
     1212        self.lines.append("%slines2locs = %r" % (self.indent, lines2locs)) 
     1213        self.lines.append("%sraise ul4c.Error(ul4c.Location(source, *locations[lines2locs[sys.exc_info()[2].tb_lineno-startline]]), exc)" % self.indent) 
     1214        result = "\n".join(self.lines) 
     1215        del self.lines 
     1216        del self.indent 
     1217        return result 
    10521218 
    10531219    def pythonfunction(self): 
     
    13581524 
    13591525 
     1526class Color(Value): 
     1527    type = "color" 
     1528 
     1529    def compile(self, template): 
     1530        r = template._allocreg() 
     1531        template.opcode("load%s" % self.type, r1=r, arg="%02x%02x%02x%02x" % self.value) 
     1532        return r 
     1533 
     1534 
    13601535class List(AST): 
    13611536    def __init__(self, start, end, *items): 
     
    16721847            template.opcode("callfunc0", r1=r, arg=self.name.name) 
    16731848            return r 
    1674         elif len(self.args) > 3: 
    1675             raise ValueError("%d arguments not supported" % len(self.args)) 
     1849        elif len(self.args) > 4: 
     1850            raise ValueError("%d function arguments not supported" % len(self.args)) 
    16761851        else: 
    16771852            rs = [arg.compile(template) for arg in self.args] 
    1678             template.opcode("callfunc%d" % len(self.args), rs[0], *rs, **dict(arg=self.name.name)) # Replace **dict(arg=) with arg= in Python 2.6? 
     1853            template.opcode("callfunc%d" % len(self.args), rs[0], *rs, **dict(arg=self.name.name)) # FIXME: Replace **dict(arg=) with arg= in Python 2.6? 
    16791854            for i in xrange(1, len(self.args)): 
    16801855                template._freereg(rs[i]) 
     
    16971872    def compile(self, template): 
    16981873        if len(self.args) > 3: 
    1699             raise ValueError("%d arguments not supported" % len(self.args)) 
     1874            raise ValueError("%d method arguments not supported" % len(self.args)) 
    17001875        ro = self.obj.compile(template) 
    17011876        rs = [arg.compile(template) for arg in self.args] 
     
    17561931        return self.rv 
    17571932 
     1933    # Color tokens must be in the order of decreasing length 
     1934    @spark.token("\\#[0-9a-fA-F]{8}", "default") 
     1935    def color8(self, start, end, s): 
     1936        self.rv.append(Color(start, end, color.Color(int(s[1:3], 16), int(s[3:5], 16), int(s[5:7], 16), int(s[7:], 16)))) 
     1937 
     1938    @spark.token("\\#[0-9a-fA-F]{6}", "default") 
     1939    def color6(self, start, end, s): 
     1940        self.rv.append(Color(start, end, color.Color(int(s[1:3], 16), int(s[3:5], 16), int(s[5:], 16)))) 
     1941 
     1942    @spark.token("\\#[0-9a-fA-F]{4}", "default") 
     1943    def color4(self, start, end, s): 
     1944        self.rv.append(Color(start, end, color.Color(17*int(s[1], 16), 17*int(s[2], 16), 17*int(s[3], 16), 17*int(s[4], 16)))) 
     1945 
     1946    @spark.token("\\#[0-9a-fA-F]{3}", "default") 
     1947    def color3(self, start, end, s): 
     1948        self.rv.append(Color(start, end, color.Color(17*int(s[1], 16), 17*int(s[2], 16), 17*int(s[3], 16)))) 
     1949 
    17581950    # Must be before the int and float constants 
    17591951    @spark.token("\\d{4}-\\d{2}-\\d{2}T(\\d{2}:\\d{2}(:\\d{2}(\\.\\d{6})?)?)?", "default") 
     
    19292121        elif isinstance(value, basestring): 
    19302122            return Str(start, end, value) 
     2123        elif isinstance(value, color.Color): 
     2124            return Color(start, end, value) 
    19312125        else: 
    19322126            raise TypeError("can't convert %r" % value) 
     
    19342128    # To implement operator precedence, each expression rule has the precedence in its name. The highest precedence is 11 for atomic expressions. 
    19352129    # Each expression can have only expressions as parts which have the some or a higher precedence with two exceptions: 
    1936     #    1) Expressions where there's no ambiguity, like the index for a getitem/getslice or function/method arguments; 
    1937     #    2) Brackets, which can be used to boost the precedence of an expression to the level of an atomic expression. 
     2130    #    1. Expressions where there's no ambiguity, like the index for a getitem/getslice or function/method arguments; 
     2131    #    2. Brackets, which can be used to boost the precedence of an expression to the level of an atomic expression. 
    19382132 
    19392133    @spark.production('expr11 ::= none') 
     
    19442138    @spark.production('expr11 ::= float') 
    19452139    @spark.production('expr11 ::= date') 
     2140    @spark.production('expr11 ::= color') 
    19462141    @spark.production('expr11 ::= name') 
    19472142    def expr_atom(self, atom): 
     
    20252220    def expr_callfunc3(self, name, _0, arg0, _1, arg1, _2, arg2, _3): 
    20262221        return CallFunc(name.start, _3.end, name, [arg0, arg1, arg2]) 
     2222 
     2223    @spark.production('expr10 ::= name ( expr0 , expr0 , expr0 , expr0 )') 
     2224    def expr_callfunc4(self, name, _0, arg0, _1, arg1, _2, arg2, _3, arg3, _4): 
     2225        return CallFunc(name.start, _4.end, name, [arg0, arg1, arg2, arg3]) 
    20272226 
    20282227    @spark.production('expr9 ::= expr9 . name') 
     
    23002499 
    23012500### 
    2302 ### Helper functions use at template runtime 
     2501### Helper functions used at template runtime 
    23032502### 
    23042503 
     
    23542553    if isinstance(obj, unicode): 
    23552554        return unicode(repr(obj)[1:]) 
     2555    elif isinstance(obj, str): 
     2556        return unicode(repr(obj)) 
    23562557    elif isinstance(obj, datetime.datetime): 
    23572558        return unicode(obj.isoformat()) 
     2559    elif isinstance(obj, color.Color): 
     2560        if obj[3] == 0xff: 
     2561            s = "#%02x%02x%02x" % (obj[0], obj[1], obj[2]) 
     2562            if s[1]==s[2] and s[3]==s[4] and s[5]==s[6]: 
     2563                return "#%s%s%s" % (s[1], s[3], s[5]) 
     2564            return s 
     2565        else: 
     2566            s = "#%02x%02x%02x%02x" % obj 
     2567            if s[1]==s[2] and s[3]==s[4] and s[5]==s[6] and s[7]==s[8]: 
     2568                return "#%s%s%s%s" % (s[1], s[3], s[5], s[7]) 
     2569            return s 
    23582570    elif isinstance(obj, list): 
    23592571        return u"[%s]" % u", ".join(_repr(item) for item in obj) 
     
    23642576 
    23652577 
    2366 def _csvescape(obj): 
    2367     """ 
    2368     Helper for the ``csvescape`` function. 
     2578def _csv(obj): 
     2579    """ 
     2580    Helper for the ``csv`` function. 
    23692581    """ 
    23702582    if obj is None: 
     
    23932605    elif isinstance(obj, (datetime.datetime, datetime.date)): 
    23942606        return u"date" 
     2607    elif isinstance(obj, color.Color): 
     2608        return u"color" 
    23952609    elif isinstance(obj, (list, tuple)): 
    23962610        return u"list" 
  • site/ll/url.py

    r9 r27  
    22# -*- coding: utf-8 -*- 
    33 
    4 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany. 
    5 ## Copyright 1999-2008 by Walter Dörwald 
     4## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany. 
     5## Copyright 1999-2009 by Walter Dörwald 
    66## 
    77## All Rights Reserved 
     
    157157 
    158158 
    159 contextstack = threading.local() 
    160  
    161159class Context(object): 
    162160    """ 
     
    183181 
    184182    def __enter__(self): 
    185         try: 
    186             stack  = getattr(contextstack, "ll.url.contexts") 
    187         except AttributeError: 
    188             stack = [] 
    189             setattr(contextstack, "ll.url.contexts", stack) 
    190         stack.append(self) 
     183        self.prev = threadlocalcontext.context 
     184        threadlocalcontext.context = self 
    191185 
    192186    def __exit__(self, type, value, traceback): 
    193         stack = getattr(contextstack, "ll.url.contexts") 
    194         stack.pop() 
     187        threadlocalcontext.context = self.prev 
     188        del self.prev 
    195189        self.closeall() 
    196190 
    197191 
    198 defaultcontext = Context() 
     192class ThreadLocalContext(threading.local): 
     193    context = Context() 
     194 
     195threadlocalcontext = ThreadLocalContext() 
    199196 
    200197 
    201198def getcontext(context): 
    202199    if context is None: 
    203         try: 
    204             stack  = getattr(contextstack, "ll.url.contexts") 
    205         except AttributeError: 
    206             return defaultcontext 
    207         try: 
    208             return stack[-1] 
    209         except IndexError: 
    210             return defaultcontext 
     200        return threadlocalcontext.context 
    211201    return context 
    212202 
     
    15281518 
    15291519class LocalSchemeDefinition(SchemeDefinition): 
    1530     # Use a different connection then the base class (but still one single 
    1531     # connection for all URLs) 
     1520    # Use a different connection than the base class (but still one single connection for all URLs) 
    15321521    _connection = LocalConnection() 
    15331522 
     
    15471536             
    15481537        context = getcontext(context) 
    1549         if context is defaultcontext: 
     1538        if context is threadlocalcontext.__class__.context: 
    15501539            raise ValueError("ssh URLs need a custom context") 
    15511540        # Use one :class:`SshConnection` for each user/host/remotepython combination 
  • site/ll/xist/__init__.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/converters.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/css.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
     
    147147        for cssnode in node.walknode(_isstyle): 
    148148            if isinstance(cssnode, html.style): 
    149                 href = str(self.base) if base is not None else None 
     149                href = str(base) if base is not None else None 
    150150                if matchstyle(cssnode): 
    151151                    stylesheet = cssutils.parseString(unicode(cssnode.content), href=href, media=unicode(cssnode.attrs.media)) 
     
    203203            for (spec, sel, style) in iterstyles(path[-1], rules): 
    204204                if sel.matchpath(path): 
    205                     for prop in style.seq: 
    206                         if not isinstance(prop, css.CSSComment): 
    207                             styles[prop.value.name] = (count, prop.value.cssText) 
    208                             count += 1 
     205                    for prop in style: 
     206                        styles[prop.name] = (count, prop.cssText) 
     207                        count += 1 
    209208            style = " ".join("%s;" % value for (count, value) in sorted(styles.itervalues())) 
    210209            if style: 
  • site/ll/xist/ns/__init__.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/abbr.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/atom.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 2007-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 2007-2008 by Walter Dörwald 
     3## Copyright 2007-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 2007-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/chars.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/code.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/detox.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/doc.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
     
    384384 
    385385            self.emattrs = dict( 
     386                font_style=u"italic", 
     387            ) 
     388 
     389            self.strongattrs = dict( 
    386390                font_weight=u"bold", 
    387391            ) 
     
    14261430            self.content, 
    14271431            converter[self].emattrs 
     1432        ) 
     1433        return e.convert(converter) 
     1434 
     1435 
     1436class strong(inline): 
     1437    """ 
     1438    Emphasized text. 
     1439    """ 
     1440    xmlns = xmlns 
     1441    model = sims.ElementsOrText(inline) 
     1442 
     1443    def convert_docbook(self, converter): 
     1444        e = converter.target.emphasis(self.content) 
     1445        return e.convert(converter) 
     1446 
     1447    def convert_html(self, converter): 
     1448        e = converter.target.strong(self.content) 
     1449        return e.convert(converter) 
     1450 
     1451    def convert_fo(self, converter): 
     1452        e = converter.target.inline( 
     1453            self.content, 
     1454            converter[self].strongattrs 
    14281455        ) 
    14291456        return e.convert(converter) 
  • site/ll/xist/ns/docbook.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/fo.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/form.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/html.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/htmlspecials.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/ihtml.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/jsp.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
     
    162162                return node.publish(publisher) # return a generator-iterator 
    163163        return super(directive_page, self).publish(publisher) # return a generator-iterator 
     164 
     165 
     166def fromul4(template, variables="variables", indent=0): 
     167    """ 
     168    Return the UL4 template :var:`template` as JSP source code. :var:`variables` 
     169    is the variable name of the map object containing the top level variables. 
     170    :var:`indent` is the initial indentation of the source code. 
     171 
     172    The code produced requires the `UL4 Java package`__. 
     173 
     174    __ http://hg.livinglogic.de/LivingLogic.Java.ul4 
     175    """ 
     176    from ll import ul4c 
     177    from ll.xist.ns import specials 
     178 
     179    # Turn a Python string into a Java string literal 
     180    def _string(s): 
     181        v = [] 
     182        specialchars = {"\r": "\\r", "\n": "\\n", "\t": "\\t", '"': '\\"'} 
     183        for c in s: 
     184            try: 
     185                v.append(specialchars[c]) 
     186            except KeyError: 
     187                oc = ord(c) 
     188                v.append("\\u%04x" % oc if oc >= 128 else c) 
     189        return '"%s"' % "".join(s) 
     190 
     191    def make_literal(content): 
     192        result.append(specials.literal(content)) 
     193 
     194    def make_expression(content): 
     195        result.append(expression(content)) 
     196 
     197    def make_scriptlet(content): 
     198        line = "%s%s\n" % ("\t"*indent, content) 
     199        if result and isinstance(result[-1], scriptlet): 
     200            result[-1] += "%s%s\n" % ("\t"*indent, content) 
     201        else: 
     202            result.append(scriptlet("\n%s%s\n" % ("\t"*indent, content))) 
     203 
     204    loopcounter = 0 # Used to number loop iterators 
     205    result = xsc.Frag() 
     206 
     207    make_scriptlet("//@@@ BEGIN template source") 
     208 
     209    lines = template.source.splitlines(False) 
     210    width = len(str(len(lines)+1)) 
     211    for (i, line) in enumerate(lines): 
     212        make_scriptlet("// %*d %s" % (width, i+1, line)) 
     213 
     214    make_scriptlet("//@@@ BEGIN template code") 
     215 
     216    for i in xrange(10): 
     217        make_scriptlet("Object r%d = null;" % i) 
     218 
     219    lastloc = None 
     220    for opcode in template.opcodes: 
     221        if opcode.code is not None and opcode.location is not lastloc: 
     222            lastloc = opcode.location 
     223            (line, col) = lastloc.pos() 
     224            tag = lastloc.tag 
     225            make_scriptlet("// Location %d (line %d, col %d): %s" % (lastloc.starttag+1, line, col, repr(tag)[1+isinstance(tag, unicode):-1])) 
     226        if opcode.code is None: 
     227            make_literal(opcode.location.code) 
     228        elif opcode.code == "loadstr": 
     229            make_scriptlet('r%d = %s;' % (opcode.r1, _string(opcode.arg))) 
     230        elif opcode.code == "loadint": 
     231            make_scriptlet("r%d = new Integer(%s);" % (opcode.r1, opcode.arg)) 
     232        elif opcode.code == "loadfloat": 
     233            make_scriptlet("r%d = new Double(%s);" % (opcode.r1, opcode.arg)) 
     234        elif opcode.code == "loadnone": 
     235            make_scriptlet("r%d = null;" % opcode.r1) 
     236        elif opcode.code == "loadfalse": 
     237            make_scriptlet("r%d = Boolean.FALSE;" % opcode.r1) 
     238        elif opcode.code == "loadtrue": 
     239            make_scriptlet("r%d = Boolean.TRUE;" % opcode.r1) 
     240        elif opcode.code == "loaddate": 
     241            make_scriptlet("r%d = com.livinglogic.ul4.Utils.isoDateFormatter.parse(%s);" % (opcode.r1, _string(opcode.arg))) 
     242        elif opcode.code == "loadcolor": 
     243            make_scriptlet("r%d = new com.livinglogic.ul4.Color(0x%s, 0x%s, 0x%s, 0x%s)" % (opcode.r1, opcode.arg[:2], opcode.arg[2:4], opcode.arg[4:6], opcode.arg[6:])) 
     244        elif opcode.code == "buildlist": 
     245            make_scriptlet("r%d = new java.util.ArrayList();" % opcode.r1) 
     246        elif opcode.code == "builddict": 
     247            make_scriptlet("r%d = new java.util.HashMap();" % opcode.r1) 
     248        elif opcode.code == "addlist": 
     249            make_scriptlet("((java.util.List)r%d).add(r%d)" % (opcode.r1, opcode.r2)) 
     250        elif opcode.code == "adddict": 
     251            make_scriptlet("((java.util.Map)r%d).put(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     252        elif opcode.code == "updatedict": 
     253            make_scriptlet("((java.util.Map)r%d).putAll((java.util.Map)r%d);" % (opcode.r1, opcode.r2)) 
     254        elif opcode.code == "loadvar": 
     255            make_scriptlet("r%d = %s.get(%s);" % (opcode.r1, variables, _string(opcode.arg))) 
     256        elif opcode.code == "storevar": 
     257            make_scriptlet("%s.put(%s, r%d);" % (variables, _string(opcode.arg), opcode.r1)) 
     258        elif opcode.code == "addvar": 
     259            name = _string(opcode.arg) 
     260            make_scriptlet("%s.put(%s, com.livinglogic.ul4.Utils.add(%s.get(%s), r%d));" % (variables, name, variables, name, opcode.r1)) 
     261        elif opcode.code == "addvar": 
     262            name = _string(opcode.arg) 
     263            make_scriptlet("%s.put(%s, com.livinglogic.ul4.Utils.sub(%s.get(%s), r%d));" % (variables, name, variables, name, opcode.r1)) 
     264        elif opcode.code == "addvar": 
     265            name = _string(opcode.arg) 
     266            make_scriptlet("%s.put(%s, com.livinglogic.ul4.Utils.mul(%s.get(%s), r%d));" % (variables, name, variables, name, opcode.r1)) 
     267        elif opcode.code == "truedivvar": 
     268            name = _string(opcode.arg) 
     269            make_scriptlet("%s.put(%s, com.livinglogic.ul4.Utils.truediv(%s.get(%s), r%d));" % (variables, name, variables, name, opcode.r1)) 
     270        elif opcode.code == "floordivvar": 
     271            name = _string(opcode.arg) 
     272            make_scriptlet("%s.put(%s, com.livinglogic.ul4.Utils.floordiv(%s.get(%s), r%d));" % (variables, name, variables, name, opcode.r1)) 
     273        elif opcode.code == "modvar": 
     274            name = _string(opcode.arg) 
     275            make_scriptlet("%s.put(%s, com.livinglogic.ul4.Utils.mod(%s.get(%s), r%d));" % (variables, name, variables, name, opcode.r1)) 
     276        elif opcode.code == "delvar": 
     277            make_scriptlet("%s.remove(%s);" % (variables, _string(opcode.arg))) 
     278        elif opcode.code == "getattr": 
     279            make_scriptlet("r%d = com.livinglogic.ul4.Utils.getItem(r%d, %s);" % (opcode.r1, opcode.r2, _string(opcode.arg))) 
     280        elif opcode.code == "getitem": 
     281            make_scriptlet("r%d = com.livinglogic.ul4.Utils.getItem(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     282        elif opcode.code == "getslice12": 
     283            make_scriptlet("r%d = com.livinglogic.ul4.Utils.getSlice(r%d, r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     284        elif opcode.code == "getslice1": 
     285            make_scriptlet("r%d = com.livinglogic.ul4.Utils.getSlice(r%d, r%d, null);" % (opcode.r1, opcode.r2, opcode.r3)) 
     286        elif opcode.code == "getslice2": 
     287            make_scriptlet("r%d = com.livinglogic.ul4.Utils.getSlice(r%d, null, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     288        elif opcode.code == "print": 
     289            make_expression("org.apache.commons.lang.ObjectUtils.toString(r%d)" % opcode.r1) 
     290        elif opcode.code == "printx": 
     291            make_expression("com.livinglogic.ul4.Utils.xmlescape(org.apache.commons.lang.ObjectUtils.toString(r%d))" % opcode.r1) 
     292        elif opcode.code == "for": 
     293            loopcounter += 1 
     294            make_scriptlet("for (java.util.Iterator iterator%d = com.livinglogic.ul4.Utils.iterator(r%d); iterator%d.hasNext();)" % (loopcounter, opcode.r2, loopcounter)) 
     295            make_scriptlet("{") 
     296            indent += 1 
     297            make_scriptlet("r%d = iterator%d.next();" % (opcode.r1, loopcounter)) 
     298        elif opcode.code == "endfor": 
     299            indent -= 1 
     300            make_scriptlet("}") 
     301        elif opcode.code == "break": 
     302            make_scriptlet("break;") 
     303        elif opcode.code == "continue": 
     304            make_scriptlet("continue;") 
     305        elif opcode.code == "not": 
     306            make_scriptlet("r%d = com.livinglogic.ul4.Utils.getBool(r%d) ? Boolean.FALSE : Boolean.TRUE;" % (opcode.r1, opcode.r2)) 
     307        elif opcode.code == "neg": 
     308            make_scriptlet("r%d = com.livinglogic.ul4.Utils.neg(r%d);" % (opcode.r1, opcode.r2)) 
     309        elif opcode.code == "contains": 
     310            make_scriptlet("r%d = com.livinglogic.ul4.Utils.contains(r%d, r%d) ? Boolean.TRUE : Boolean.FALSE;" % (opcode.r1, opcode.r2, opcode.r3)) 
     311        elif opcode.code == "notcontains": 
     312            make_scriptlet("r%d = com.livinglogic.ul4.Utils.contains(r%d, r%d) ? Boolean.FALSE : Boolean.TRUE;" % (opcode.r1, opcode.r2, opcode.r3)) 
     313        elif opcode.code == "eq": 
     314            make_scriptlet("r%d = org.apache.commons.lang.ObjectUtils.equals(r%d, r%d) ? Boolean.TRUE : Boolean.FALSE;" % (opcode.r1, opcode.r2, opcode.r3)) 
     315        elif opcode.code == "ne": 
     316            make_scriptlet("r%d = org.apache.commons.lang.ObjectUtils.equals(r%d, r%d) ? Boolean.FALSE : Boolean.TRUE;" % (opcode.r1, opcode.r2, opcode.r3)) 
     317        elif opcode.code == "lt": 
     318            make_scriptlet("r%d = com.livinglogic.ul4.Utils.lt(r%d, r%d) ? Boolean.TRUE : Boolean.FALSE;" % (opcode.r1, opcode.r2, opcode.r3)) 
     319        elif opcode.code == "le": 
     320            make_scriptlet("r%d = com.livinglogic.ul4.Utils.le(r%d, r%d) ? Boolean.TRUE : Boolean.FALSE;" % (opcode.r1, opcode.r2, opcode.r3)) 
     321        elif opcode.code == "gt": 
     322            make_scriptlet("r%d = com.livinglogic.ul4.Utils.le(r%d, r%d) ? Boolean.FALSE : Boolean.TRUE;" % (opcode.r1, opcode.r2, opcode.r3)) 
     323        elif opcode.code == "ge": 
     324            make_scriptlet("r%d = com.livinglogic.ul4.Utils.lt(r%d, r%d) ? Boolean.FALSE : Boolean.TRUE;" % (opcode.r1, opcode.r2, opcode.r3)) 
     325        elif opcode.code == "add": 
     326            make_scriptlet("r%d = com.livinglogic.ul4.Utils.add(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     327        elif opcode.code == "sub": 
     328            make_scriptlet("r%d = com.livinglogic.ul4.Utils.sub(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     329        elif opcode.code == "mul": 
     330            make_scriptlet("r%d = com.livinglogic.ul4.Utils.mul(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     331        elif opcode.code == "floordiv": 
     332            make_scriptlet("r%d = com.livinglogic.ul4.Utils.floordiv(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     333        elif opcode.code == "truediv": 
     334            make_scriptlet("r%d = com.livinglogic.ul4.Utils.truediv(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     335        elif opcode.code == "and": 
     336            make_scriptlet("r%d = com.livinglogic.ul4.Utils.getBool(r%d) ? r%d : r%d;" % (opcode.r1, opcode.r3, opcode.r2, opcode.r3)) 
     337        elif opcode.code == "or": 
     338            make_scriptlet("r%d = com.livinglogic.ul4.Utils.getBool(r%d) ? r%d : r%d;" % (opcode.r1, opcode.r2, opcode.r2, opcode.r3)) 
     339        elif opcode.code == "mod": 
     340            make_scriptlet("r%d = com.livinglogic.ul4.Utils.mod(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     341        elif opcode.code == "callfunc0": 
     342            if opcode.arg == "now": 
     343                make_scriptlet("r%d = new java.util.Date();" % opcode.r1) 
     344            elif opcode.arg == "vars": 
     345                make_scriptlet("r%d = %s;" % (opcode.r1, variables)) 
     346            else: 
     347                raise ul4c.UnknownFunctionError(opcode.arg) 
     348        elif opcode.code == "callfunc1": 
     349            if opcode.arg == "xmlescape": 
     350                make_scriptlet("r%d = com.livinglogic.ul4.Utils.xmlescape(r%d);" % (opcode.r1, opcode.r2)) 
     351            elif opcode.arg == "csv": 
     352                make_scriptlet("r%d = com.livinglogic.ul4.Utils.csv(r%d);" % (opcode.r1, opcode.r2)) 
     353            elif opcode.arg == "str": 
     354                make_scriptlet("r%d = org.apache.commons.lang.ObjectUtils.toString(r%d);" % (opcode.r1, opcode.r2)) 
     355            elif opcode.arg == "repr": 
     356                make_scriptlet("r%d = com.livinglogic.ul4.Utils.repr(r%d);" % (opcode.r1, opcode.r2)) 
     357            elif opcode.arg == "int": 
     358                make_scriptlet("r%d = com.livinglogic.ul4.Utils.toInteger(r%d);" % (opcode.r1, opcode.r2)) 
     359            elif opcode.arg == "bool": 
     360                make_scriptlet("r%d = com.livinglogic.ul4.Utils.getBool(r%d) ? Boolean.TRUE : Boolean.FALSE;" % (opcode.r1, opcode.r2)) 
     361            elif opcode.arg == "len": 
     362                make_scriptlet("r%d = com.livinglogic.ul4.Utils.length(r%d);" % (opcode.r1, opcode.r2)) 
     363            elif opcode.arg == "enumerate": 
     364                make_scriptlet("r%d = com.livinglogic.ul4.Utils.enumerate(r%d);" % (opcode.r1, opcode.r2)) 
     365            elif opcode.arg == "isnone": 
     366                make_scriptlet("r%d = (r%d == null) ? Boolean.TRUE : Boolean.FALSE;" % (opcode.r1, opcode.r2)) 
     367            elif opcode.arg == "isstr": 
     368                make_scriptlet("r%d = ((r%d != null) && (r%d instanceof String)) ? Boolean.TRUE : Boolean.FALSE;" % (opcode.r1, opcode.r2, opcode.r2)) 
     369            elif opcode.arg == "isint": 
     370                make_scriptlet("r%d = ((r%d != null) && (r%d instanceof Integer)) ? Boolean.TRUE : Boolean.FALSE;" % (opcode.r1, opcode.r2, opcode.r2)) 
     371            elif opcode.arg == "isfloat": 
     372                make_scriptlet("r%d = ((r%d != null) && (r%d instanceof Double)) ? Boolean.TRUE : Boolean.FALSE;" % (opcode.r1, opcode.r2, opcode.r2)) 
     373            elif opcode.arg == "isbool": 
     374                make_scriptlet("r%d = ((r%d != null) && (r%d instanceof Boolean)) ? Boolean.TRUE : Boolean.FALSE;" % (opcode.r1, opcode.r2, opcode.r2)) 
     375            elif opcode.arg == "isdate": 
     376                make_scriptlet("r%d = ((r%d != null) && (r%d instanceof java.util.Date)) ? Boolean.TRUE : Boolean.FALSE;" % (opcode.r1, opcode.r2, opcode.r2)) 
     377            elif opcode.arg == "islist": 
     378                make_scriptlet("r%d = ((r%d != null) && (r%d instanceof java.util.List)) ? Boolean.TRUE : Boolean.FALSE;" % (opcode.r1, opcode.r2, opcode.r2)) 
     379            elif opcode.arg == "isdict": 
     380                make_scriptlet("r%d = ((r%d != null) && (r%d instanceof java.util.Map)) ? Boolean.TRUE : Boolean.FALSE;" % (opcode.r1, opcode.r2, opcode.r2)) 
     381            elif opcode.arg == "istemplate": 
     382                make_scriptlet("r%d = ((r%d != null) && (r%d instanceof .livinglogic.ul4.Template)) ? Boolean.TRUE : Boolean.FALSE;" % (opcode.r1, opcode.r2, opcode.r2)) 
     383            elif opcode.arg == "chr": 
     384                make_scriptlet("r%d = com.livinglogic.ul4.Utils.chr(r%d);" % (opcode.r1, opcode.r2)) 
     385            elif opcode.arg == "ord": 
     386                make_scriptlet("r%d = com.livinglogic.ul4.Utils.ord(r%d);" % (opcode.r1, opcode.r2)) 
     387            elif opcode.arg == "hex": 
     388                make_scriptlet("r%d = com.livinglogic.ul4.Utils.hex(r%d);" % (opcode.r1, opcode.r2)) 
     389            elif opcode.arg == "oct": 
     390                make_scriptlet("r%d = com.livinglogic.ul4.Utils.oct(r%d);" % (opcode.r1, opcode.r2)) 
     391            elif opcode.arg == "bin": 
     392                make_scriptlet("r%d = com.livinglogic.ul4.Utils.bin(r%d);" % (opcode.r1, opcode.r2)) 
     393            elif opcode.arg == "sorted": 
     394                make_scriptlet("r%d = com.livinglogic.ul4.Utils.sorted(r%d);" % (opcode.r1, opcode.r2)) 
     395            elif opcode.arg == "range": 
     396                make_scriptlet("r%d = com.livinglogic.ul4.Utils.range(r%d);" % (opcode.r1, opcode.r2)) 
     397            elif opcode.arg == "type": 
     398                make_scriptlet("r%d = com.livinglogic.ul4.Utils.type(r%d);" % (opcode.r1, opcode.r2)) 
     399            elif opcode.arg == "get": 
     400                make_scriptlet("r%d = %s.get(r%d);" % (opcode.r1, variables, opcode.r2)) 
     401            elif opcode.arg == "json": 
     402                make_scriptlet("r%d = com.livinglogic.ul4.Utils.json(r%d);" % (opcode.r1, opcode.r2)) 
     403            else: 
     404                raise ul4c.UnknownFunctionError(opcode.arg) 
     405        elif opcode.code == "callfunc2": 
     406            if opcode.arg == "range": 
     407                make_scriptlet("r%d = com.livinglogic.ul4.Utils.range(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     408            elif opcode.arg == "get": 
     409                make_scriptlet("r%d = %s.containsKey(r%d) ? %s.get(r%d) : r%d;" % (opcode.r1, variables, opcode.r2, variables, opcode.r2, opcode.r3)) 
     410            elif opcode.arg == "zip": 
     411                make_scriptlet("r%d = com.livinglogic.ul4.Utils.zip(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     412            else: 
     413                raise ul4c.UnknownFunctionError(opcode.arg) 
     414        elif opcode.code == "callfunc3": 
     415            if opcode.arg == "range": 
     416                make_scriptlet("r%d = com.livinglogic.ul4.Utils.range(r%d, r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     417            elif opcode.arg == "zip": 
     418                make_scriptlet("r%d = com.livinglogic.ul4.Utils.zip(r%d, r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     419            elif opcode.arg == "rgb": 
     420                make_scriptlet("r%d = com.livinglogic.ul4.Utils.rgb(r%d, r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     421            elif opcode.arg == "hls": 
     422                make_scriptlet("r%d = com.livinglogic.ul4.Utils.hls(r%d, r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     423            elif opcode.arg == "hsv": 
     424                make_scriptlet("r%d = com.livinglogic.ul4.Utils.hsv(r%d, r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     425            else: 
     426                raise ul4c.UnknownFunctionError(opcode.arg) 
     427        elif opcode.code == "callfunc4": 
     428            if opcode.arg == "rgb": 
     429                make_scriptlet("r%d = com.livinglogic.ul4.Utils.rgb(r%d, r%d, r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4, opcode.r5)) 
     430            elif opcode.arg == "hls": 
     431                make_scriptlet("r%d = com.livinglogic.ul4.Utils.hls(r%d, r%d, r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4, opcode.r5)) 
     432            elif opcode.arg == "hsv": 
     433                make_scriptlet("r%d = com.livinglogic.ul4.Utils.hsv(r%d, r%d, r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4, opcode.r5)) 
     434            else: 
     435                raise ul4c.UnknownFunctionError(opcode.arg) 
     436        elif opcode.code == "callmeth0": 
     437            if opcode.arg == "split": 
     438                make_scriptlet("r%d = com.livinglogic.ul4.Utils.split(r%d);" % (opcode.r1, opcode.r2)) 
     439            elif opcode.arg == "strip": 
     440                make_scriptlet("r%d = com.livinglogic.ul4.Utils.strip(r%d);" % (opcode.r1, opcode.r2)) 
     441            elif opcode.arg == "lstrip": 
     442                make_scriptlet("r%d = com.livinglogic.ul4.Utils.lstrip(r%d);" % (opcode.r1, opcode.r2)) 
     443            elif opcode.arg == "rstrip": 
     444                make_scriptlet("r%d = com.livinglogic.ul4.Utils.rstrip(r%d);" % (opcode.r1, opcode.r2)) 
     445            elif opcode.arg == "upper": 
     446                make_scriptlet("r%d = com.livinglogic.ul4.Utils.upper(r%d);" % (opcode.r1, opcode.r2)) 
     447            elif opcode.arg == "lower": 
     448                make_scriptlet("r%d = com.livinglogic.ul4.Utils.lower(r%d);" % (opcode.r1, opcode.r2)) 
     449            elif opcode.arg == "capitalize": 
     450                make_scriptlet("r%d = com.livinglogic.ul4.Utils.capitalize(r%d);" % (opcode.r1, opcode.r2)) 
     451            elif opcode.arg == "items": 
     452                make_scriptlet("r%d = com.livinglogic.ul4.Utils.items(r%d);" % (opcode.r1, opcode.r2)) 
     453            elif opcode.arg == "isoformat": 
     454                make_scriptlet("r%d = com.livinglogic.ul4.Utils.isoformat(r%d);" % (opcode.r1, opcode.r2)) 
     455            elif opcode.arg == "r": 
     456                make_scriptlet("r%d = ((com.livinglogic.ul4.Color)r%d).r();" % (opcode.r1, opcode.r2)) 
     457            elif opcode.arg == "g": 
     458                make_scriptlet("r%d = ((com.livinglogic.ul4.Color)r%d).g();" % (opcode.r1, opcode.r2)) 
     459            elif opcode.arg == "b": 
     460                make_scriptlet("r%d = ((com.livinglogic.ul4.Color)r%d).b();" % (opcode.r1, opcode.r2)) 
     461            elif opcode.arg == "a": 
     462                make_scriptlet("r%d = ((com.livinglogic.ul4.Color)r%d).a();" % (opcode.r1, opcode.r2)) 
     463            elif opcode.arg == "hls": 
     464                make_scriptlet("r%d = ((com.livinglogic.ul4.Color)r%d).hls();" % (opcode.r1, opcode.r2)) 
     465            elif opcode.arg == "hlsa": 
     466                make_scriptlet("r%d = ((com.livinglogic.ul4.Color)r%d).hlsa();" % (opcode.r1, opcode.r2)) 
     467            elif opcode.arg == "hsv": 
     468                make_scriptlet("r%d = ((com.livinglogic.ul4.Color)r%d).hsv();" % (opcode.r1, opcode.r2)) 
     469            elif opcode.arg == "hsva": 
     470                make_scriptlet("r%d = ((com.livinglogic.ul4.Color)r%d).hsva();" % (opcode.r1, opcode.r2)) 
     471            elif opcode.arg == "lum": 
     472                make_scriptlet("r%d = new Double(((com.livinglogic.ul4.Color)r%d).lum());" % (opcode.r1, opcode.r2)) 
     473            else: 
     474                raise ul4c.UnknownMethodError(opcode.arg) 
     475        elif opcode.code == "callmeth1": 
     476            if opcode.arg == "split": 
     477                make_scriptlet("r%d = com.livinglogic.ul4.Utils.split(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     478            elif opcode.arg == "rsplit": 
     479                make_scriptlet("r%d = com.livinglogic.ul4.Utils.rsplit(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     480            elif opcode.arg == "strip": 
     481                make_scriptlet("r%d = com.livinglogic.ul4.Utils.strip(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     482            elif opcode.arg == "lstrip": 
     483                make_scriptlet("r%d = com.livinglogic.ul4.Utils.lstrip(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     484            elif opcode.arg == "rstrip": 
     485                make_scriptlet("r%d = com.livinglogic.ul4.Utils.rstrip(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     486            elif opcode.arg == "startswith": 
     487                make_scriptlet("r%d = com.livinglogic.ul4.Utils.startswith(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     488            elif opcode.arg == "endswith": 
     489                make_scriptlet("r%d = com.livinglogic.ul4.Utils.endswith(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     490            elif opcode.arg == "find": 
     491                make_scriptlet("r%d = com.livinglogic.ul4.Utils.find(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     492            elif opcode.arg == "rfind": 
     493                make_scriptlet("r%d = com.livinglogic.ul4.Utils.rfind(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     494            elif opcode.arg == "format": 
     495                make_scriptlet("r%d = com.livinglogic.ul4.Utils.format(r%d, r%d, defaultLocale);" % (opcode.r1, opcode.r2, opcode.r3)) 
     496            elif opcode.arg == "get": 
     497                make_scriptlet("r%d = ((java.util.Map)r%d).get(r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     498            elif opcode.arg == "withlum": 
     499                make_scriptlet("r%d = com.livinglogic.ul4.Utils.withlum(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     500            elif opcode.arg == "witha": 
     501                make_scriptlet("r%d = com.livinglogic.ul4.Utils.witha(r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3)) 
     502            else: 
     503                raise ul4c.UnknownMethodError(opcode.arg) 
     504        elif opcode.code == "callmeth2": 
     505            if opcode.arg == "split": 
     506                make_scriptlet("r%d = com.livinglogic.ul4.Utils.split(r%d, r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     507            elif opcode.arg == "rsplit": 
     508                make_scriptlet("r%d = com.livinglogic.ul4.Utils.rsplit(r%d, r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     509            elif opcode.arg == "find": 
     510                make_scriptlet("r%d = com.livinglogic.ul4.Utils.find(r%d, r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     511            elif opcode.arg == "replace": 
     512                make_scriptlet("r%d = com.livinglogic.ul4.Utils.replace(r%d, r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4)) 
     513            elif opcode.arg == "get": 
     514                make_scriptlet("r%d = ((java.util.Map)r%d).containsKey(r%d) ? ((java.util.Map)r%d).get(r%d) : r%d;" % (opcode.r1, opcode.r2, opcode.r3, opcode.r2, opcode.r3, opcode.r4)) 
     515            else: 
     516                raise ul4c.UnknownMethodError(opcode.arg) 
     517        elif opcode.code == "callmeth3": 
     518            if opcode.arg == "find": 
     519                make_scriptlet("r%d = com.livinglogic.ul4.Utils.find(r%d, r%d, r%d, r%d);" % (opcode.r1, opcode.r2, opcode.r3, opcode.r4, opcode.r5)) 
     520            else: 
     521                raise ul4c.UnknownMethodError(opcode.arg) 
     522        elif opcode.code == "if": 
     523            make_scriptlet("if (com.livinglogic.ul4.Utils.getBool(r%d))" % opcode.r1) 
     524            make_scriptlet("{") 
     525            indent += 1 
     526        elif opcode.code == "else": 
     527            indent -= 1 
     528            make_scriptlet("}") 
     529            make_scriptlet("else") 
     530            make_scriptlet("{") 
     531            indent += 1 
     532        elif opcode.code == "endif": 
     533            indent -= 1 
     534            make_scriptlet("}") 
     535        elif opcode.code == "render": 
     536            make_scriptlet("((com.livinglogic.ul4.JSPTemplate)r%d).execute(out, (Map)r%d);" % (opcode.r1, opcode.r2)) 
     537        else: 
     538            raise ul4c.UnknownOpcodeError(opcode.code) 
     539    make_scriptlet("//@@@ END template code") 
     540    return result 
  • site/ll/xist/ns/kid.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 2005-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 2005-2008 by Walter Dörwald 
     3## Copyright 2005-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 2005-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/meta.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/metal.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/php.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/rest.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 2008 by Walter Dörwald 
     3## Copyright 2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/rng.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 2005-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 2005-2008 by Walter Dörwald 
     3## Copyright 2005-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 2005-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/rss091.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 2007-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 2007-2008 by Walter Dörwald 
     3## Copyright 2007-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 2007-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/rss20.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 2007-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 2007-2008 by Walter Dörwald 
     3## Copyright 2007-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 2007-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/ruby.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/specials.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/struts_config.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/struts_html.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/svg.py

    r9 r27  
    22 
    33 
    4 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    5 ## Copyright 1999-2008 by Walter Dörwald 
     4## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     5## Copyright 1999-2009 by Walter Dörwald 
    66## 
    77## All Rights Reserved 
  • site/ll/xist/ns/sxtl.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 2008 by Walter Dörwald 
     3## Copyright 2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/tal.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/tld.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/toxic.py

    r9 r27  
    22# -*- coding: utf-8 -*- 
    33 
    4 ## Copyright 2004-2008 by LivingLogic AG, Bayreuth/Germany. 
    5 ## Copyright 2004-2008 by Walter Dörwald 
     4## Copyright 2004-2009 by LivingLogic AG, Bayreuth/Germany. 
     5## Copyright 2004-2009 by Walter Dörwald 
    66## 
    77## All Rights Reserved 
  • site/ll/xist/ns/ul4.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 2008 by Walter Dörwald 
     3## Copyright 2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/wml.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/xlink.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/ns/xml.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/options.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/parsers.py

    r11 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
     
    361361            return newnode 
    362362 
    363         self.base = base 
     363        self.base = url.URL(base) 
    364364 
    365365        try: 
  • site/ll/xist/presenters.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/publishers.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/scripts/__init__.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/scripts/doc2txt.py

    r9 r27  
    22# -*- coding: utf-8 -*- 
    33 
    4 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    5 ## Copyright 1999-2008 by Walter Dörwald 
     4## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     5## Copyright 1999-2009 by Walter Dörwald 
    66## 
    77## All Rights Reserved 
  • site/ll/xist/scripts/dtd2xsc.py

    r9 r27  
    22# -*- coding: utf-8 -*- 
    33 
    4 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    5 ## Copyright 1999-2008 by Walter Dörwald 
     4## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     5## Copyright 1999-2009 by Walter Dörwald 
    66## 
    77## All Rights Reserved 
  • site/ll/xist/scripts/tld2xsc.py

    r9 r27  
    22# -*- coding: utf-8 -*- 
    33 
    4 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    5 ## Copyright 1999-2008 by Walter Dörwald 
     4## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     5## Copyright 1999-2009 by Walter Dörwald 
    66## 
    77## All Rights Reserved 
  • site/ll/xist/scripts/xml2xsc.py

    r9 r27  
    22# -*- coding: utf-8 -*- 
    33 
    4 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    5 ## Copyright 1999-2008 by Walter Dörwald 
     4## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     5## Copyright 1999-2009 by Walter Dörwald 
    66## 
    77## All Rights Reserved 
  • site/ll/xist/sims.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/xfind.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
     
    10631063    :class:`nthchild` :class:`nthoftype` supports negative and positive indices 
    10641064    as well as ``"even"`` and ``"odd"``. Which types are checked can be passed 
    1065     explicitely. If no types are passed the type of the node itself is used:: 
     1065    explicitly. If no types are passed the type of the node itself is used:: 
    10661066 
    10671067        >>> from ll.xist import parsers, xfind 
  • site/ll/xist/xnd.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
  • site/ll/xist/xsc.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 ## Copyright 1999-2008 by LivingLogic AG, Bayreuth/Germany 
    4 ## Copyright 1999-2008 by Walter Dörwald 
     3## Copyright 1999-2009 by LivingLogic AG, Bayreuth/Germany 
     4## Copyright 1999-2009 by Walter Dörwald 
    55## 
    66## All Rights Reserved 
     
    8383 
    8484 
    85 threadlocalnodehandler = threading.local() 
    86 threadlocalnodehandler.handler = None 
     85class ThreadLocalNodeHander(threading.local): 
     86    handler = None 
     87 
     88threadlocalnodehandler = ThreadLocalNodeHander() 
    8789 
    8890 
     
    103105            self.stack[-1](node) 
    104106        self.stack.append(node) 
     107        return node 
    105108 
    106109    def exit(self): 
     
    117120    """ 
    118121    threadlocalnodehandler.handler.add(*args, **kwargs) 
     122 
     123 
     124class addattr(object): 
     125    """ 
     126    An :class:`addattr` object can be used as a ``with`` block handler to modify 
     127    an attribute of an element:: 
     128 
     129        with xsc.build(): 
     130            with html.div() as e: 
     131                with xsc.addattr("align"): 
     132                    +xsc.Text("right") 
     133    """ 
     134    def __init__(self, attrname): 
     135        """ 
     136        Create an :class:`addattr` object for adding to the attribute named 
     137        :var:`attrname` (which can be the Python name of an attribute or an 
     138        attribute class). 
     139        """ 
     140        self.attr = threadlocalnodehandler.handler.stack[-1][attrname] 
     141 
     142    def __enter__(self): 
     143        threadlocalnodehandler.handler.stack.append(self.attr) 
     144        return self.attr 
     145 
     146    def __exit__(self, type, value, traceback): 
     147        threadlocalnodehandler.handler.stack.pop() 
     148 
     149    def add(self, *args): 
     150        self.attr(*args) 
    119151 
    120152 
     
    12831315 
    12841316    def __enter__(self): 
    1285         threadlocalnodehandler.handler.enter(self) 
    1286         return self 
     1317        return threadlocalnodehandler.handler.enter(self) 
    12871318 
    12881319    def __exit__(self, type, value, traceback): 
     
    37613792 
    37623793# Default pool (can be temporarily changed via ``with xsc.Pool() as pool:``) 
    3763 threadlocalpool = threading.local() 
    3764 threadlocalpool.pool = Pool() 
     3794class ThreadLocalPool(threading.local): 
     3795    pool = Pool() 
     3796 
     3797threadlocalpool = ThreadLocalPool() 
    37653798 
    37663799 
  • site/ll/xml_codec.py

    r9 r27  
    11# -*- coding: utf-8 -*- 
    22 
    3 # Copyright 2007-2008 by LivingLogic AG, Bayreuth/Germany. 
    4 # Copyright 2007-2008 by Walter Dörwald 
     3# Copyright 2007-2009 by LivingLogic AG, Bayreuth/Germany. 
     4# Copyright 2007-2009 by Walter Dörwald 
    55# 
    66# All Rights Reserved 
     
    1010 
    1111""" 
    12 Python Codec for XML decoding 
     12This module implements a codec that can be used for encoding and decoding XML. 
     13Once the encoding has been determined the decoding/encoding process falls back 
     14to using the codec for that particular encoding to do the rest of the work, so 
     15this XML codec supports all encodings supported by Python itself. 
     16 
     17On decoding the XML codec determines the encoding by either inspecting the 
     18first few bytes of the byte stream/string or by extracting the encoding from 
     19the XML declaration. If the encoding can't be determined from the first few 
     20bytes and there is no XML declaration the codec falls back to using UTF-8. 
     21When the encoding is specified by an external source (e.g. a Content-Type 
     22header in an HTTP response), this encoding can be passed as an argument to the 
     23codec, which will then bypass encoding detection. If there's an XML declaration 
     24in the input, the XML declaration passed to the application then will contain 
     25the externally specified encoding instead of the original one. 
     26 
     27On encoding the XML codec extracts the encoding from the XML declaration and 
     28will encode the output in that encoding. If there's no XML declaration UTF-8 
     29will be used. It's possible to pass an external encoding to the encoder too. 
     30The encoder will then encode the output in that encoding and put the correct 
     31encoding into the XML declaration (if there is one). 
    1332""" 
    1433