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  __version__ = '$Id: csspagerule.py 1170 2008-03-20 17:42:07Z cthedot $' 
  6   
  7  import xml.dom 
  8  import cssrule 
  9  import cssutils 
 10  from selectorlist import SelectorList 
 11  from cssstyledeclaration import CSSStyleDeclaration 
 12   
13 -class CSSPageRule(cssrule.CSSRule):
14 """ 15 The CSSPageRule interface represents a @page rule within a CSS style 16 sheet. The @page rule is used to specify the dimensions, orientation, 17 margins, etc. of a page box for paged media. 18 19 Properties 20 ========== 21 atkeyword (cssutils only) 22 the literal keyword used 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 Inherits properties from CSSRule 31 32 Format 33 ====== 34 :: 35 36 page 37 : PAGE_SYM S* pseudo_page? S* 38 LBRACE S* declaration [ ';' S* declaration ]* '}' S* 39 ; 40 pseudo_page 41 : ':' IDENT # :first, :left, :right in CSS 2.1 42 ; 43 44 """ 45 type = property(lambda self: cssrule.CSSRule.PAGE_RULE) 46 # constant but needed: 47 wellformed = True 48
49 - def __init__(self, selectorText=None, style=None, parentRule=None, 50 parentStyleSheet=None, readonly=False):
51 """ 52 if readonly allows setting of properties in constructor only 53 54 selectorText 55 type string 56 style 57 CSSStyleDeclaration for this CSSStyleRule 58 """ 59 super(CSSPageRule, self).__init__(parentRule=parentRule, 60 parentStyleSheet=parentStyleSheet) 61 self._atkeyword = u'@page' 62 tempseq = self._tempSeq() 63 if selectorText: 64 self.selectorText = selectorText 65 tempseq.append(self.selectorText, 'selectorText') 66 else: 67 self._selectorText = u'' 68 if style: 69 self.style = style 70 tempseq.append(self.style, 'style') 71 else: 72 self._style = CSSStyleDeclaration(parentRule=self) 73 self._setSeq(tempseq) 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 see _setSelectorText for details 83 """ 84 # for closures: must be a mutable 85 new = {'selector': None, 'wellformed': True} 86 87 def _char(expected, seq, token, tokenizer=None): 88 # pseudo_page, :left, :right or :first 89 val = self._tokenvalue(token) 90 if ':' == expected and u':' == val: 91 try: 92 identtoken = tokenizer.next() 93 except StopIteration: 94 self._log.error( 95 u'CSSPageRule selectorText: No IDENT found.', token) 96 else: 97 ival, ityp = self._tokenvalue(identtoken), self._type(identtoken) 98 if self._prods.IDENT != ityp: 99 self._log.error( 100 u'CSSPageRule selectorText: Expected IDENT but found: %r' % 101 ival, token) 102 else: 103 new['selector'] = val + ival 104 seq.append(new['selector'], 'selector') 105 return 'EOF' 106 return expected 107 else: 108 new['wellformed'] = False 109 self._log.error( 110 u'CSSPageRule selectorText: Unexpected CHAR: %r' % val, token) 111 return expected
112 113 def S(expected, seq, token, tokenizer=None): 114 "Does not raise if EOF is found." 115 return expected
116 117 def COMMENT(expected, seq, token, tokenizer=None): 118 "Does not raise if EOF is found." 119 seq.append(cssutils.css.CSSComment([token]), 'COMMENT') 120 return expected 121 122 newseq = self._tempSeq() 123 wellformed, expected = self._parse(expected=':', 124 seq=newseq, tokenizer=self._tokenize2(selectorText), 125 productions={'CHAR': _char, 126 'COMMENT': COMMENT, 127 'S': S}, 128 new=new) 129 wellformed = wellformed and new['wellformed'] 130 newselector = new['selector'] 131 132 # post conditions 133 if expected == 'ident': 134 self._log.error( 135 u'CSSPageRule selectorText: No valid selector: %r' % 136 self._valuestr(selectorText)) 137 138 if not newselector in (None, u':first', u':left', u':right'): 139 self._log.warn(u'CSSPageRule: Unknown CSS 2.1 @page selector: %r' % 140 newselector, neverraise=True) 141 142 return newselector, newseq 143
144 - def _getCssText(self):
145 """ 146 returns serialized property cssText 147 """ 148 return cssutils.ser.do_CSSPageRule(self)
149
150 - def _setCssText(self, cssText):
151 """ 152 DOMException on setting 153 154 - SYNTAX_ERR: (self, StyleDeclaration) 155 Raised if the specified CSS string value has a syntax error and 156 is unparsable. 157 - INVALID_MODIFICATION_ERR: (self) 158 Raised if the specified CSS string value represents a different 159 type of rule than the current one. 160 - HIERARCHY_REQUEST_ERR: (CSSStylesheet) 161 Raised if the rule cannot be inserted at this point in the 162 style sheet. 163 - NO_MODIFICATION_ALLOWED_ERR: (CSSRule) 164 Raised if the rule is readonly. 165 """ 166 super(CSSPageRule, self)._setCssText(cssText) 167 168 tokenizer = self._tokenize2(cssText) 169 if self._type(self._nexttoken(tokenizer)) != self._prods.PAGE_SYM: 170 self._log.error(u'CSSPageRule: No CSSPageRule found: %s' % 171 self._valuestr(cssText), 172 error=xml.dom.InvalidModificationErr) 173 else: 174 wellformed = True 175 selectortokens, startbrace = self._tokensupto2(tokenizer, 176 blockstartonly=True, 177 separateEnd=True) 178 styletokens, braceorEOFtoken = self._tokensupto2(tokenizer, 179 blockendonly=True, 180 separateEnd=True) 181 nonetoken = self._nexttoken(tokenizer) 182 if self._tokenvalue(startbrace) != u'{': 183 wellformed = False 184 self._log.error( 185 u'CSSPageRule: No start { of style declaration found: %r' % 186 self._valuestr(cssText), startbrace) 187 elif nonetoken: 188 wellformed = False 189 self._log.error( 190 u'CSSPageRule: Trailing content found.', token=nonetoken) 191 192 193 newselector, newselectorseq = self.__parseSelectorText(selectortokens) 194 195 newstyle = CSSStyleDeclaration() 196 val, typ = self._tokenvalue(braceorEOFtoken), self._type(braceorEOFtoken) 197 if val != u'}' and typ != 'EOF': 198 wellformed = False 199 self._log.error( 200 u'CSSPageRule: No "}" after style declaration found: %r' % 201 self._valuestr(cssText)) 202 else: 203 if 'EOF' == typ: 204 # add again as style needs it 205 styletokens.append(braceorEOFtoken) 206 newstyle.cssText = styletokens 207 208 if wellformed: 209 self._selectorText = newselector # already parsed 210 self.style = newstyle 211 self._setSeq(newselectorseq) # contains upto style only
212 213 cssText = property(_getCssText, _setCssText, 214 doc="(DOM) The parsable textual representation of the rule.") 215
216 - def _getSelectorText(self):
217 """ 218 wrapper for cssutils Selector object 219 """ 220 return self._selectorText
221
222 - def _setSelectorText(self, selectorText):
223 """ 224 wrapper for cssutils Selector object 225 226 selector: DOM String 227 in CSS 2.1 one of 228 - :first 229 - :left 230 - :right 231 - empty 232 233 If WS or Comments are included they are ignored here! Only 234 way to add a comment is via setting ``cssText`` 235 236 DOMException on setting 237 238 - SYNTAX_ERR: 239 Raised if the specified CSS string value has a syntax error 240 and is unparsable. 241 - NO_MODIFICATION_ALLOWED_ERR: (self) 242 Raised if this rule is readonly. 243 """ 244 self._checkReadonly() 245 246 # may raise SYNTAX_ERR 247 newselectortext, newseq = self.__parseSelectorText(selectorText) 248 249 if newselectortext: 250 for i, x in enumerate(self.seq): 251 if x == self._selectorText: 252 self.seq[i] = newselectortext 253 self._selectorText = newselectortext
254 255 selectorText = property(_getSelectorText, _setSelectorText, 256 doc="""(DOM) The parsable textual representation of the page selector for the rule.""") 257
258 - def _getStyle(self):
259 260 return self._style
261
262 - def _setStyle(self, style):
263 """ 264 style 265 StyleDeclaration or string 266 """ 267 self._checkReadonly() 268 269 if isinstance(style, basestring): 270 self._style.cssText = style 271 else: 272 # cssText would be serialized with optional preferences 273 # so use seq! 274 self._style.seq = style.seq
275 276 style = property(_getStyle, _setStyle, 277 doc="(DOM) The declaration-block of this rule set.") 278
279 - def __repr__(self):
280 return "cssutils.css.%s(selectorText=%r, style=%r)" % ( 281 self.__class__.__name__, self.selectorText, self.style.cssText)
282
283 - def __str__(self):
284 return "<cssutils.css.%s object selectorText=%r style=%r at 0x%x>" % ( 285 self.__class__.__name__, self.selectorText, self.style.cssText, 286 id(self))
287