Package cssutils :: Package css :: Module csspagerule
[hide private]
[frames] | no frames]

Source Code for Module cssutils.css.csspagerule

  1  """CSSPageRule implements DOM Level 2 CSS CSSPageRule. 
  2  """ 
  3  __all__ = ['CSSPageRule'] 
  4  __docformat__ = 'restructuredtext' 
  5  __author__ = '$LastChangedBy: cthedot $' 
  6  __date__ = '$LastChangedDate: 2007-08-20 22:07:12 +0200 (Mo, 20 Aug 2007) $' 
  7  __version__ = '$LastChangedRevision: 257 $' 
  8   
  9  import xml.dom 
 10  import cssrule 
 11  import cssstyledeclaration 
 12  import cssutils 
 13  from selector import Selector 
 14   
15 -class CSSPageRule(cssrule.CSSRule):
16 """ 17 The CSSPageRule interface represents a @page rule within a CSS style 18 sheet. The @page rule is used to specify the dimensions, orientation, 19 margins, etc. of a page box for paged media. 20 21 Properties 22 ========== 23 cssText: of type DOMString 24 The parsable textual representation of this rule 25 selectorText: of type DOMString 26 The parsable textual representation of the page selector for the rule. 27 style: of type CSSStyleDeclaration 28 The declaration-block of this rule. 29 30 cssutils only 31 ------------- 32 atkeyword: 33 the literal keyword used 34 35 Inherits properties from CSSRule 36 37 Format 38 ====== 39 :: 40 41 page 42 : PAGE_SYM S* pseudo_page? S* 43 LBRACE S* declaration [ ';' S* declaration ]* '}' S* 44 ; 45 pseudo_page 46 : ':' IDENT # :first, :left, :right in CSS 2.1 47 ; 48 49 """ 50 type = cssrule.CSSRule.PAGE_RULE 51
52 - def __init__(self, selectorText=None, style=None, readonly=False):
53 """ 54 if readonly allows setting of properties in constructor only 55 56 selectorText 57 type string 58 style 59 CSSStyleDeclaration for this CSSStyleRule 60 """ 61 super(CSSPageRule, self).__init__() 62 63 self.atkeyword = u'@page' 64 if selectorText: 65 self.selectorText = selectorText 66 self.seq.append(self.selectorText) 67 else: 68 self._selectorText = u'' 69 if style: 70 self.style = style 71 else: 72 self._style = cssstyledeclaration.CSSStyleDeclaration( 73 parentRule=self) 74 75 self._readonly = readonly
76
77 - def __parseSelectorText(self, selectorText):
78 """ 79 parses selectorText which may also be a list of tokens 80 and returns (selectorText, seq) 81 82 raises SYNTAX_ERR: 83 """ 84 tokens = self._tokenize(selectorText) 85 86 newselectortext = None 87 newseq = [] 88 89 expected = ':' # means no selector but 1 like ":first" is okay 90 i, imax = 0, len(tokens) 91 while i < imax: 92 t = tokens[i] 93 if self._ttypes.S == t.type and 'ident' != expected: # ignore 94 pass 95 96 elif self._ttypes.COMMENT == t.type and 'ident' != expected: # just add 97 newseq.append(cssutils.css.CSSComment(t)) 98 99 elif u':' == t.value and ':' == expected: # selector start : 100 expected = 'ident' 101 102 elif self._ttypes.IDENT == t.type and 'ident' == expected: # selector 103 newselectortext = u':%s' % t.value 104 newseq.append(newselectortext) 105 expected = None 106 107 else: 108 self._log.error(u'CSSPageRule: Syntax Error in selector: "%s".' % 109 self._valuestr(tokens)) 110 return None, None 111 112 i += 1 113 114 if expected and expected != ':': 115 self._log.error(u'CSSPageRule: Invalid Selector: "%s".' % 116 self._valuestr(tokens)) 117 return None, None 118 119 if newselectortext is None: 120 newselectortext = u'' 121 122 # warn only 123 if not newselectortext in (u'', u':first', u':left', u':right'): 124 self._log.warn(u'CSSPageRule: Unknown CSS 2.1 @page selector: "%s".' % 125 self._valuestr(tokens), neverraise=True) 126 127 return newselectortext, newseq
128
129 - def _getCssText(self):
130 """ 131 returns serialized property cssText 132 """ 133 return cssutils.ser.do_CSSPageRule(self)
134
135 - def _setCssText(self, cssText):
136 """ 137 DOMException on setting 138 139 - SYNTAX_ERR: (self, StyleDeclaration) 140 Raised if the specified CSS string value has a syntax error and 141 is unparsable. 142 - INVALID_MODIFICATION_ERR: (self) 143 Raised if the specified CSS string value represents a different 144 type of rule than the current one. 145 - HIERARCHY_REQUEST_ERR: (CSSStylesheet) 146 Raised if the rule cannot be inserted at this point in the 147 style sheet. 148 - NO_MODIFICATION_ALLOWED_ERR: (CSSRule) 149 Raised if the rule is readonly. 150 """ 151 super(CSSPageRule, self)._setCssText(cssText) 152 tokens = self._tokenize(cssText) 153 154 # check if right token 155 if not tokens or tokens and tokens[0].type != self._ttypes.PAGE_SYM: 156 self._log.error(u'CSSPageRule: No CSSPageRule found: %s' % 157 self._valuestr(cssText), 158 error=xml.dom.InvalidModificationErr) 159 return 160 else: 161 newatkeyword = tokens[0].value 162 163 # init 164 newstyle = cssstyledeclaration.CSSStyleDeclaration(parentRule=self) 165 166 # selector 167 selectortokens, stylestarti = self._tokensupto( 168 tokens, blockstartonly=True) 169 newselectortext, newseq = self.__parseSelectorText( 170 selectortokens[1:-1]) # without @page and { 171 172 # style 173 styletokens, styleendi = self._tokensupto( 174 tokens[stylestarti:], blockendonly=True) 175 176 if not styletokens or \ 177 styletokens[0].value != u'{' or\ 178 styletokens[-1].type not in( 179 self._ttypes.EOF, self._ttypes.RBRACE) or\ 180 len(tokens) > stylestarti + styleendi + 1: 181 self._log.error(u'CSSPageRule: Invalid style found: %s' % 182 self._valuestr(styletokens[1:-1])) 183 return 184 185 newstyle = cssstyledeclaration.CSSStyleDeclaration( 186 parentRule=self, cssText=styletokens[1:-1]) 187 188 # seems ok 189 if newstyle: 190 if newselectortext: # optional 191 self._selectorText = newselectortext 192 self.seq = newseq 193 self.style = newstyle
194 195 cssText = property(_getCssText, _setCssText, 196 doc="(DOM) The parsable textual representation of the rule.") 197
198 - def _getSelectorText(self):
199 """ 200 wrapper for cssutils Selector object 201 """ 202 return self._selectorText
203
204 - def _setSelectorText(self, selectorText):
205 """ 206 wrapper for cssutils Selector object 207 208 selector: DOM String 209 in CSS 2.1 one of 210 - :first 211 - :left 212 - :right 213 - empty 214 215 If WS or Comments are included they are ignored here! Only 216 way to add a comment is via setting ``cssText`` 217 218 DOMException on setting 219 220 - SYNTAX_ERR: 221 Raised if the specified CSS string value has a syntax error 222 and is unparsable. 223 - NO_MODIFICATION_ALLOWED_ERR: (self) 224 Raised if this rule is readonly. 225 """ 226 self._checkReadonly() 227 228 # may raise SYNTAX_ERR 229 newselectortext, newseq = self.__parseSelectorText(selectorText) 230 231 if newselectortext: 232 for i, x in enumerate(self.seq): 233 if x == self._selectorText: 234 self.seq[i] = newselectortext 235 self._selectorText = newselectortext
236 237 selectorText = property(_getSelectorText, _setSelectorText, 238 doc="""(DOM) The parsable textual representation of the page selector for the rule.""") 239
240 - def _getStyle(self):
241 return self._style
242
243 - def _setStyle(self, style):
244 """ 245 style 246 StyleDeclaration or string 247 """ 248 self._checkReadonly() 249 if isinstance(style, basestring): 250 # may raise Exception! 251 temp = cssstyledeclaration.CSSStyleDeclaration(parentRule=self) 252 temp.cssText = style 253 self._style = temp 254 else: 255 self._style = style 256 style.parentRule = self
257 258 style = property(_getStyle, _setStyle, 259 doc="(DOM) The declaration-block of this rule set.") 260
261 - def __repr__(self):
262 return "cssutils.css.%s(selectorText=%r)" % ( 263 self.__class__.__name__, self.selectorText)
264
265 - def __str__(self):
266 return "<cssutils.css.%s object selectorText=%r at 0x%x>" % ( 267 self.__class__.__name__, self.selectorText, id(self))
268 269 270 if __name__ == '__main__': 271 import property 272 cssutils.css.cssstyledeclaration.Property = property._Property 273 cssutils.css.cssstylerule.Selector = Selector # for main test 274 r = CSSPageRule() 275 r.cssText = '@page :right { margin: 0 }' 276 #r.selectorText = u':left :a' 277 print r.cssText 278