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 |
|