Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / cssutils / css / marginrule.py @ 475

History | View | Annotate | Download (7.56 KB)

1
"""MarginRule implements DOM Level 2 CSS MarginRule."""
2
__all__ = ['MarginRule']
3
__docformat__ = 'restructuredtext'
4
__version__ = '$Id$'
5

    
6
from cssutils.prodparser import *
7
from cssstyledeclaration import CSSStyleDeclaration
8
import cssrule
9
import cssutils
10
import xml.dom
11

    
12
class MarginRule(cssrule.CSSRule):
13
    """
14
    A margin at-rule consists of an ATKEYWORD that identifies the margin box
15
    (e.g. '@top-left') and a block of declarations (said to be in the margin
16
    context).
17

18
    Format::
19
        
20
        margin :
21
               margin_sym S* '{' declaration [ ';' S* declaration? ]* '}' S*
22
               ;
23
        
24
        margin_sym :
25
               TOPLEFTCORNER_SYM | 
26
               TOPLEFT_SYM | 
27
               TOPCENTER_SYM | 
28
               TOPRIGHT_SYM | 
29
               TOPRIGHTCORNER_SYM |
30
               BOTTOMLEFTCORNER_SYM | 
31
               BOTTOMLEFT_SYM | 
32
               BOTTOMCENTER_SYM | 
33
               BOTTOMRIGHT_SYM |
34
               BOTTOMRIGHTCORNER_SYM |
35
               LEFTTOP_SYM |
36
               LEFTMIDDLE_SYM |
37
               LEFTBOTTOM_SYM |
38
               RIGHTTOP_SYM |
39
               RIGHTMIDDLE_SYM |
40
               RIGHTBOTTOM_SYM 
41
               ;
42
        
43
    e.g.::
44
    
45
        @top-left {
46
            content: "123";
47
            }
48
    """
49
    margins = ['@top-left-corner',
50
               '@top-left',
51
               '@top-center',
52
               '@top-right',
53
               '@top-right-corner',
54
               '@bottom-left-corner',
55
               '@bottom-left',
56
               '@bottom-center',
57
               '@bottom-right',
58
               '@bottom-right-corner',
59
               '@left-top',
60
               '@left-middle',
61
               '@left-bottom',
62
               '@right-top',
63
               '@right-middle',
64
               '@right-bottom'
65
               ]
66
    
67
    def __init__(self, margin=None, style=None, parentRule=None, 
68
                 parentStyleSheet=None, readonly=False):
69
        """
70
        :param atkeyword:
71
            The margin area, e.g. '@top-left' for this rule
72
        :param style:
73
            CSSStyleDeclaration for this MarginRule
74
        """
75
        super(MarginRule, self).__init__(parentRule=parentRule, 
76
                                         parentStyleSheet=parentStyleSheet)
77
        
78
        self._atkeyword = self._keyword = None
79
        
80
        if margin:
81
            self.margin = margin
82
            
83
        if style:
84
            self.style = style
85
        else:
86
            self.style = CSSStyleDeclaration(parentRule=self)
87
        
88
        self._readonly = readonly
89

    
90
    def _setMargin(self, margin):
91
        """Check if new keyword fits the rule it is used for."""
92
        n = self._normalize(margin)
93
        
94
        if n not in MarginRule.margins:
95
            self._log.error(u'Invalid margin @keyword for this %s rule: %r' %
96
                            (self.margin, margin),
97
                            error=xml.dom.InvalidModificationErr)
98
    
99
        else:
100
            self._atkeyword = n
101
            self._keyword = margin
102

    
103
    margin = property(lambda self: self._atkeyword, _setMargin,
104
                      doc=u"Margin area of parent CSSPageRule. "
105
                          u"`margin` and `atkeyword` are both normalized "
106
                          u"@keyword of the @rule.")
107

    
108
    atkeyword = margin 
109

    
110
    def __repr__(self):
111
        return u"cssutils.css.%s(margin=%r, style=%r)" % (self.__class__.__name__,
112
                                                          self.margin, 
113
                                                          self.style.cssText)
114

    
115
    def __str__(self):
116
        return u"<cssutils.css.%s object margin=%r style=%r "\
117
               u"at 0x%x>" % (self.__class__.__name__,
118
                              self.margin,
119
                              self.style.cssText,
120
                              id(self))
121

    
122
    def _getCssText(self):
123
        """Return serialized property cssText."""
124
        return cssutils.ser.do_MarginRule(self)
125

    
126
    def _setCssText(self, cssText):
127
        """
128
        :exceptions:
129
            - :exc:`~xml.dom.SyntaxErr`:
130
              Raised if the specified CSS string value has a syntax error and
131
              is unparsable.
132
            - :exc:`~xml.dom.InvalidModificationErr`:
133
              Raised if the specified CSS string value represents a different
134
              type of rule than the current one.
135
            - :exc:`~xml.dom.HierarchyRequestErr`:
136
              Raised if the rule cannot be inserted at this point in the
137
              style sheet.
138
            - :exc:`~xml.dom.NoModificationAllowedErr`:
139
              Raised if the rule is readonly.
140
        """
141
        super(MarginRule, self)._setCssText(cssText)
142
                
143
        # TEMP: all style tokens are saved in store to fill styledeclaration
144
        # TODO: resolve when all generators
145
        styletokens = Prod(name='styletokens',
146
                           match=lambda t, v: v != u'}',
147
                           #toSeq=False,
148
                           toStore='styletokens',
149
                           storeToken=True 
150
                           )
151
                
152
        prods = Sequence(Prod(name='@ margin', 
153
                              match=lambda t, v: 
154
                                t == 'ATKEYWORD' and 
155
                                self._normalize(v) in MarginRule.margins,
156
                              toStore='margin'
157
                              # TODO?
158
                              #, exception=xml.dom.InvalidModificationErr 
159
                              ),
160
                         PreDef.char('OPEN', u'{'),
161
                         Sequence(Choice(PreDef.unknownrule(toStore='@'), 
162
                                         styletokens),
163
                                  minmax=lambda: (0, None)
164
                         ),
165
                         PreDef.char('CLOSE', u'}', stopAndKeep=True)
166
                )
167
        # parse
168
        ok, seq, store, unused = ProdParser().parse(cssText,
169
                                                    u'MarginRule',
170
                                                    prods)
171
        
172
        if ok:
173
            # TODO: use seq for serializing instead of fixed stuff?
174
            self._setSeq(seq)
175
            
176
            if 'margin' in store:
177
                # may raise:
178
                self.margin = store['margin'].value
179
            else:
180
                self._log.error(u'No margin @keyword for this %s rule' %
181
                                self.margin,
182
                                error=xml.dom.InvalidModificationErr)
183
            
184
            # new empty style
185
            self.style = CSSStyleDeclaration(parentRule=self)
186
            
187
            if 'styletokens' in store:
188
                # may raise:
189
                self.style.cssText = store['styletokens']
190
            
191
                
192
    cssText = property(fget=_getCssText, fset=_setCssText,
193
                       doc=u"(DOM) The parsable textual representation.")
194
    
195
    def _setStyle(self, style):
196
        """
197
        :param style: A string or CSSStyleDeclaration which replaces the
198
            current style object.
199
        """
200
        self._checkReadonly()
201
        if isinstance(style, basestring):
202
            self._style = CSSStyleDeclaration(cssText=style, parentRule=self)
203
        else:
204
            style._parentRule = self
205
            self._style = style
206

    
207
    style = property(lambda self: self._style, _setStyle,
208
                     doc=u"(DOM) The declaration-block of this rule set.")
209
    
210
    type = property(lambda self: self.MARGIN_RULE, 
211
                    doc=u"The type of this rule, as defined by a CSSRule "
212
                        u"type constant.")
213
    
214
    wellformed = property(lambda self: bool(self.atkeyword))
215