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: doerwalter $'
10 __date__ = '$LastChangedDate: 2007-08-02 22:58:23 +0200 (Do, 02 Aug 2007) $'
11 __version__ = '0.9.2a1, $LastChangedRevision: 160 $'
12
13 import codecs
14 import re
15 import xml.dom
16
17 import cssrule
18 import cssutils
19
20
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
78 """ returns encoding as a string """
79 return self._encoding
80
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
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
158
159 cssText = property(fget=_getCssText, fset=_setCssText,
160 doc="(DOM) The parsable textual representation.")
161
162
163 if __name__ == '__main__':
164 p = cssutils.CSSParser()
165 s = p.parseString('@charset')
166 print s.cssRules
167
168 c = CSSCharsetRule('utf-8')
169 c.cssText = u' @charset "ascii" ;'
170