Statistics
| Revision:

gvsig-scripting / org.gvsig.scripting / trunk / org.gvsig.scripting / org.gvsig.scripting.app / org.gvsig.scripting.app.mainplugin / src / main / resources-plugin / scripting / lib / cssutils / stylesheets / mediaquery.py @ 475

History | View | Annotate | Download (8 KB)

1
"""Implements a DOM for MediaQuery, see 
2
http://www.w3.org/TR/css3-mediaqueries/.
3

4
A cssutils implementation, not defined in official DOM.
5
"""
6
__all__ = ['MediaQuery']
7
__docformat__ = 'restructuredtext'
8
__version__ = '$Id$'
9

    
10
from cssutils.prodparser import *
11
from cssutils.helper import normalize, pushtoken
12
import cssutils
13
import re
14
import xml.dom
15

    
16
class MediaQuery(cssutils.util._NewBase):#cssutils.util.Base):
17
    """
18
    A Media Query consists of one of :const:`MediaQuery.MEDIA_TYPES`
19
    and one or more expressions involving media features.
20

21
    Format::
22
  
23
        media_query
24
         : [ONLY | NOT]? S* media_type S* [ AND S* expression ]*
25
         | expression [ AND S* expression ]*
26
         ;
27
        media_type
28
         : IDENT
29
         ;
30
        expression
31
         : '(' S* media_feature S* [ ':' S* expr ]? ')' S*
32
         ;
33
        media_feature
34
         : IDENT
35
         ;
36
          
37
    """
38
    MEDIA_TYPES = ['all', 'braille', 'handheld', 'print', 'projection', 
39
                'speech', 'screen', 'tty', 'tv', 'embossed']
40

    
41

    
42
    def __init__(self, mediaText=None, readonly=False, _partof=False):
43
        """
44
        :param mediaText:
45
            unicodestring of parsable media
46

47
        # _standalone: True if new from ML parser
48
        """
49
        super(MediaQuery, self).__init__()
50

    
51
        self._wellformed = False
52
        self._mediaType = u''
53
        self._partof = _partof
54
        if mediaText:
55
            self.mediaText = mediaText # sets self._mediaType too
56
            self._partof = False
57

    
58
        self._readonly = readonly
59

    
60
    def __repr__(self):
61
        return "cssutils.stylesheets.%s(mediaText=%r)" % (
62
                self.__class__.__name__, self.mediaText)
63

    
64
    def __str__(self):
65
        return "<cssutils.stylesheets.%s object mediaText=%r at 0x%x>" % (
66
                self.__class__.__name__, self.mediaText, id(self))
67

    
68
    def _getMediaText(self):
69
        return cssutils.ser.do_stylesheets_mediaquery(self)
70

    
71
    def _setMediaText(self, mediaText):
72
        """
73
        :param mediaText:
74
            a single media query string, e.g. ``print and (min-width: 25cm)``
75

76
        :exceptions:    
77
            - :exc:`~xml.dom.SyntaxErr`:
78
              Raised if the specified string value has a syntax error and is
79
              unparsable.
80
            - :exc:`~xml.dom.InvalidCharacterErr`:
81
              Raised if the given mediaType is unknown.
82
            - :exc:`~xml.dom.NoModificationAllowedErr`:
83
              Raised if this media query is readonly.
84
        
85
        media_query
86
         : [ONLY | NOT]? S* media_type S* [ AND S* expression ]*
87
         | expression [ AND S* expression ]*
88
         ;
89
        media_type
90
         : IDENT
91
         ;
92
        expression
93
         : '(' S* media_feature S* [ ':' S* expr ]? ')' S*
94
         ;
95
        media_feature
96
         : IDENT
97
         ;
98

99
        """
100
        self._checkReadonly()
101

    
102
        expression = lambda: Sequence(PreDef.char(name='expression', char=u'('),
103
                                      Prod(name=u'media_feature',
104
                                           match=lambda t, v: t == PreDef.types.IDENT
105
                                      ),
106
                                      Sequence(PreDef.char(name='colon', char=u':'),
107
                                               cssutils.css.value.MediaQueryValueProd(self),
108
                                               minmax=lambda: (0, 1) # optional
109
                                               ),
110
                                      PreDef.char(name='expression END', char=u')',
111
                                                  stopIfNoMoreMatch=self._partof
112
                                                  )
113
                                      )
114

    
115
        prods = Choice(Sequence(Prod(name=u'ONLY|NOT', # media_query
116
                                     match=lambda t, v: t == PreDef.types.IDENT and 
117
                                                        normalize(v) in (u'only', u'not'),
118
                                     optional=True,
119
                                     toStore='not simple'
120
                                     ), 
121
                                Prod(name=u'media_type',
122
                                     match=lambda t, v: t == PreDef.types.IDENT and 
123
                                                        normalize(v) in self.MEDIA_TYPES,
124
                                     stopIfNoMoreMatch=True,
125
                                     toStore='media_type'
126
                                     ),                   
127
                                Sequence(Prod(name=u'AND',
128
                                              match=lambda t, v: t == PreDef.types.IDENT and 
129
                                                                 normalize(v) == 'and',
130
                                              toStore='not simple'
131
                                         ),                   
132
                                         expression(),
133
                                         minmax=lambda: (0, None)
134
                                         )
135
                                ),
136
                       Sequence(expression(),                   
137
                                Sequence(Prod(name=u'AND',
138
                                              match=lambda t, v: t == PreDef.types.IDENT and 
139
                                                                 normalize(v) == 'and'
140
                                         ),                   
141
                                         expression(),
142
                                         minmax=lambda: (0, None)
143
                                         )
144
                                )                        
145
                       )
146
        
147
        # parse
148
        ok, seq, store, unused = ProdParser().parse(mediaText, 
149
                                                    u'MediaQuery',
150
                                                    prods)
151
        self._wellformed = ok
152
        if ok:
153
            try:
154
                media_type = store['media_type']
155
            except KeyError, e:
156
                pass
157
            else:
158
                if 'not simple' not in store:
159
                    self.mediaType = media_type.value
160

    
161
            # TODO: filter doubles!
162
            self._setSeq(seq)
163

    
164
    mediaText = property(_getMediaText, _setMediaText,
165
        doc="The parsable textual representation of the media list.")
166

    
167
    def _setMediaType(self, mediaType):
168
        """
169
        :param mediaType:
170
            one of :attr:`MEDIA_TYPES`
171

172
        :exceptions:
173
            - :exc:`~xml.dom.SyntaxErr`:
174
              Raised if the specified string value has a syntax error and is
175
              unparsable.
176
            - :exc:`~xml.dom.InvalidCharacterErr`:
177
              Raised if the given mediaType is unknown.
178
            - :exc:`~xml.dom.NoModificationAllowedErr`:
179
              Raised if this media query is readonly.
180
        """
181
        self._checkReadonly()
182
        nmediaType = normalize(mediaType)
183

    
184
        if nmediaType not in self.MEDIA_TYPES:
185
            self._log.error(
186
                u'MediaQuery: Syntax Error in media type "%s".' % mediaType,
187
                error=xml.dom.SyntaxErr)
188
        else:
189
            # set
190
            self._mediaType = mediaType
191

    
192
            # update seq
193
            for i, x in enumerate(self._seq):
194
                if isinstance(x.value, basestring):
195
                    if normalize(x.value) in (u'only', u'not'):
196
                        continue
197
                    else:
198
                        # TODO: simplify!
199
                        self._seq[i] = (mediaType, 'IDENT', None, None)
200
                        break
201
            else:
202
                self._seq.insert(0, mediaType, 'IDENT')
203

    
204
    mediaType = property(lambda self: self._mediaType, _setMediaType,
205
        doc="The media type of this MediaQuery (one of "
206
            ":attr:`MEDIA_TYPES`) but only if it is a simple MediaType!")
207
    
208
    wellformed = property(lambda self: self._wellformed)