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