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

# Source Code for Module cssutils.css.csscharsetrule

      1  """CSSCharsetRule implements DOM Level 2 CSS CSSCharsetRule.
      2
      3  TODO:
      4      - check specific allowed syntaxes
      5      - check encoding syntax and not codecs.lookup?
      6  """
      7  __all__ = ['CSSCharsetRule']
      8  __docformat__ = 'restructuredtext'
      9  __author__ = '$LastChangedBy: cthedot $'
     10  __date__ = '$LastChangedDate: 2007-08-20 22:07:12 +0200 (Mo, 20 Aug 2007) $'
     11  __version__ = '$LastChangedRevision: 257 $'
     12
     13  import codecs
     14  import re
     15  import xml.dom
     16
     17  import cssrule
     18  import cssutils
     19
     20
     21 -class CSSCharsetRule(cssrule.CSSRule):
     22      """
     23      The CSSCharsetRule interface represents an @charset rule in a CSS style
     24      sheet. The value of the encoding attribute does not affect the encoding
     25      of text data in the DOM objects; this encoding is always UTF-16
     26      (also in Python?). After a stylesheet is loaded, the value of the
     27      encoding attribute is the value found in the @charset rule. If there
     28      was no @charset in the original document, then no CSSCharsetRule is
     29      created. The value of the encoding attribute may also be used as a hint
     30      for the encoding used on serialization of the style sheet.
     31
     32      The value of the @charset rule (and therefore of the CSSCharsetRule)
     33      may not correspond to the encoding the document actually came in;
     34      character encoding information e.g. in an HTTP header, has priority
     35      (see CSS document representation) but this is not reflected in the
     36      CSSCharsetRule.
     37
     38      Properties
     39      ==========
     40      cssText: of type DOMString
     41          The parsable textual representation of this rule
     42      encoding: of type DOMString
     43          The encoding information used in this @charset rule.
     44
     45      Inherits properties from CSSRule
     46
     47      Format
     48      ======
     49      charsetrule:
     50          CHARSET_SYM S* STRING S* ';'
     51
     52      BUT: Only valid format is:
     53          @charset "ENCODING";
     54      """
     55      type = cssrule.CSSRule.CHARSET_RULE
     56
     57 -    def __init__(self, encoding=None, readonly=False):
     58          """
     59          encoding:
     60              a valid character encoding
     61          readonly:
     62              defaults to False, not used yet
     63
     64          if readonly allows setting of properties in constructor only
     65          """
     66          super(CSSCharsetRule, self).__init__()
     67
     68          self._encoding = None
     69          if encoding:
     70              self.encoding = encoding
     71
     72          self._pat = re.compile(u'^@charset "(.+?)";$',
     73                                   re.DOTALL | re.IGNORECASE | re.UNICODE)
     74
     75          self._readonly = readonly
     76
     77 -    def _getEncoding(self):
     78          """ returns encoding as a string """
     79          return self._encoding
     80
     81 -    def _setEncoding(self, encoding):
     82          """
     83          DOMException on setting
     84
     85          - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
     86            Raised if this encoding rule is readonly.
     87          - SYNTAX_ERR: (self)
     88            Raised if the specified encoding value has a syntax error and
     89            is unparsable.
     90            Currently only valid Python encodings are allowed.
     91          """
     92          self._checkReadonly()
     93          tokens = self._tokenize(encoding)
     94          valid = True
     95
     96          if tokens and tokens[0].type != self._ttypes.IDENT or len(tokens) != 1:
     97              valid = False
     98              self._log.error(
     99                  'CSSCharsetRule: Syntax Error in encoding value "%s".' %
    100                        encoding)
    101          try:
    102              codecs.lookup(encoding)
    103          except LookupError:
    104              valid = False
    105              self._log.error('CSSCharsetRule: Unknown (Python) encoding "%s".' %
    106                        encoding)
    107          if valid:
    108              self._encoding = encoding.lower()
    109
    110      encoding = property(_getEncoding, _setEncoding,
    111          doc="(DOM)The encoding information used in this @charset rule.")
    112
    113
    114 -    def _getCssText(self):
    115          """returns serialized property cssText"""
    116          return cssutils.ser.do_CSSCharsetRule(self)
    117
    118 -    def _setCssText(self, cssText):
    119          """
    120          DOMException on setting
    121
    122          - SYNTAX_ERR: (self)
    123            Raised if the specified CSS string value has a syntax error and
    124            is unparsable.
    125          - INVALID_MODIFICATION_ERR: (self)
    126            Raised if the specified CSS string value represents a different
    127            type of rule than the current one.
    128          - HIERARCHY_REQUEST_ERR: (CSSStylesheet)
    129            Raised if the rule cannot be inserted at this point in the
    130            style sheet.
    131          - NO_MODIFICATION_ALLOWED_ERR: (CSSRule)
    132            Raised if the rule is readonly.
    133          """
    134          super(CSSCharsetRule, self)._setCssText(cssText)
    135          tokens = self._tokenize(cssText)
    136
    137          text = ''.join([t.value for t in tokens])
    138          # check if right token
    139          if not text.startswith(u'@charset'):
    140              self._log.error(
    141                  u'No CSSCharsetRule: %s' % text,
    142                  error=xml.dom.InvalidModificationErr)
    143              return
    144
    145          encoding = self._pat.match(text)
    146          if not encoding:
    147              self._log.error(u'CSSCharsetRule: Syntax Error: "%s".' % text,
    148                        tokens[0])
    149          else:
    150              encoding = encoding.group(1)
    151              if not encoding:
    152                  self._log.error(
    153                      u'CSSCharsetRule: No Encoding found: "%s".' % text,
    154                      tokens[0])
    155              else:
    156                  encoding
    157                  self.encoding = encoding # also sets self.valid
    158
    159      cssText = property(fget=_getCssText, fset=_setCssText,
    160          doc="(DOM) The parsable textual representation.")
    161
    162 -    def __repr__(self):
    163          return "cssutils.css.%s(encoding=%r)" % (
    164                  self.__class__.__name__, self.encoding)
    165
    166 -    def __str__(self):
    167          return "<cssutils.css.%s object encoding=%r at 0x%x>" % (
    168                  self.__class__.__name__, self.encoding, id(self))
    169
    170
    171  if __name__ == '__main__':
    172      p = cssutils.CSSParser()
    173      s = p.parseString('@charset')
    174      print s.cssRules
    175
    176      c = CSSCharsetRule('utf-8')
    177      c.cssText = u' @charset "ascii" ;'
    178