示例#1
0
    def _setCssText(self, cssText):
        self._checkReadonly()

        prods = Sequence(  # PreDef.unary(),
            Choice(PreDef.dimension(stop=True),
                   PreDef.number(stop=True),
                   PreDef.percentage(stop=True)
                   )
        )
        ok, seq, store, unused = ProdParser().parse(cssText,
                                                    'DimensionValue',
                                                    prods)
        self.wellformed = ok
        if ok:
            item = seq[0]

            sign, v, d = self.__reUnNumDim.findall(
                normalize(item.value))[0]
            if '.' in v:
                val = float(sign + v)
            else:
                val = int(sign + v)

            dim = None
            if d:
                dim = d

            self._sign = sign
            self._value = val
            self._dimension = dim
            self._type = item.type

            self._setSeq(seq)
示例#2
0
    def _setCssText(self, cssText):
        self._checkReadonly()

        types = self._prods  # rename!

        _operator = Choice(Prod(name='Operator */',
                                match=lambda t, v: v in '*/',
                                toSeq=lambda t, tokens: (t[0], t[1])
                                ),
                           Sequence(
                               PreDef.S(),
                               Choice(
                                   Sequence(
                                       Prod(name='Operator */',
                                            match=lambda t, v: v in '*/',
                                            toSeq=lambda t, tokens: (t[0], t[1])
                                            ),
                                       PreDef.S(optional=True)
                                   ),
                                   Sequence(
                                       Prod(name='Operator +-',
                                            match=lambda t, v: v in '+-',
                                            toSeq=lambda t, tokens: (t[0], t[1])
                                            ),
                                       PreDef.S()
                                   ),
                                   PreDef.funcEnd(stop=True, mayEnd=True)
                               )
        )
        )

        def _operant(): return Choice(_DimensionProd(self),
                                      _CSSVariableProd(self))

        prods = Sequence(Prod(name='CALC',
                              match=lambda t, v: t == types.FUNCTION and
                              normalize(v) == 'calc('
                              ),
                         PreDef.S(optional=True),
                         _operant(),
                         Sequence(_operator,
                                  _operant(),
                                  minmax=lambda: (0, None)
                                  ),
                         PreDef.funcEnd(stop=True)
                         )

        # store: name of variable
        ok, seq, store, unused = ProdParser().parse(cssText,
                                                    'CSSCalc',
                                                    prods,
                                                    checkS=True)
        self.wellformed = ok
        if ok:
            self._setSeq(seq)
示例#3
0
        def expression(): return Sequence(PreDef.char(name='expression', char='('),
                                          Prod(name='media_feature',
                                               match=lambda t, v: t == PreDef.types.IDENT
                                               ),
                                          Sequence(PreDef.char(name='colon', char=':'),
                                                   css_parser.css.value.MediaQueryValueProd(self),
                                                   minmax=lambda: (0, 1)  # optional
                                                   ),
                                          PreDef.char(name='expression END', char=')',
                                                      stopIfNoMoreMatch=self._partof
                                                      )
                                          )

        prods = Choice(Sequence(Prod(name='ONLY|NOT',  # media_query
示例#4
0
    def _setCssText(self, cssText):
        self._checkReadonly()

        prods = Choice(PreDef.hexcolor(stop=True),
                       PreDef.ident(stop=True),
                       PreDef.string(stop=True),
                       PreDef.unicode_range(stop=True),
                       )
        ok, seq, store, unused = ProdParser().parse(cssText, 'Value', prods)
        self.wellformed = ok
        if ok:
            # only 1 value anyway!
            self._type = seq[0].type
            self._value = seq[0].value

            self._setSeq(seq)
示例#5
0
def _CSSVariableProd(parent, nextSor=False, toStore=None):
    return PreDef.variable(nextSor=nextSor,
                           toStore=toStore,
                           toSeq=lambda t, tokens: (CSSVariable._functionName,
                                                    CSSVariable(
                                                        pushtoken(t, tokens),
                                                        parent=parent)
                                                    )
                           )
    def setVariable(self, variableName, value):
        """Used to set a variable value within this variable declaration block.

        :param variableName:
            The name of the CSS variable.
        :param value:
            The new value of the variable, may also be a PropertyValue object.

        :exceptions:
            - :exc:`~xml.dom.SyntaxErr`:
              Raised if the specified value has a syntax error and is
              unparsable.
            - :exc:`~xml.dom.NoModificationAllowedErr`:
              Raised if this declaration is readonly or the property is
              readonly.
        """
        self._checkReadonly()

        # check name
        wellformed, seq, store, unused = \
            ProdParser().parse(normalize(variableName),
                               'variableName',
                               Sequence(PreDef.ident()))
        if not wellformed:
            self._log.error('Invalid variableName: %r: %r'
                            % (variableName, value))
        else:
            # check value
            if isinstance(value, PropertyValue):
                v = value
            else:
                v = PropertyValue(cssText=value, parent=self)

            if not v.wellformed:
                self._log.error('Invalid variable value: %r: %r'
                                % (variableName, value))
            else:
                # update seq
                self.seq._readonly = False

                variableName = normalize(variableName)

                if variableName in self._vars:
                    for i, x in enumerate(self.seq):
                        if x.value[0] == variableName:
                            self.seq.replace(i,
                                             [variableName, v],
                                             x.type,
                                             x.line,
                                             x.col)
                            break
                else:
                    self.seq.append([variableName, v], 'var')
                self.seq._readonly = True
                self._vars[variableName] = v
示例#7
0
    def _setCssText(self, cssText):
        self._checkReadonly()

        prods = Sequence(PreDef.uri(stop=True))

        ok, seq, store, unused = ProdParser().parse(cssText, 'URIValue', prods)
        self.wellformed = ok
        if ok:
            # only 1 value only anyway
            self._type = seq[0].type
            self._value = seq[0].value

            self._setSeq(seq)
示例#8
0
    def _setCssText(self, cssText):
        self._checkReadonly()

        types = self._prods  # rename!
        prods = Sequence(Prod(name='var',
                              match=lambda t, v: t == types.FUNCTION and
                              normalize(v) == 'var('
                              ),
                         PreDef.ident(toStore='ident'),
                         Sequence(PreDef.comma(),
                                  Choice(_ColorProd(self, toStore='fallback'),
                                         _DimensionProd(self, toStore='fallback'),
                                         _URIProd(self, toStore='fallback'),
                                         _ValueProd(self, toStore='fallback'),
                                         _CalcValueProd(self, toStore='fallback'),
                                         _CSSVariableProd(self, toStore='fallback'),
                                         _CSSFunctionProd(self, toStore='fallback')
                                         ),
                                  minmax=lambda: (0, 1)
                                  ),
                         PreDef.funcEnd(stop=True))

        # store: name of variable
        store = {'ident': None, 'fallback': None}
        ok, seq, store, unused = ProdParser().parse(cssText,
                                                    'CSSVariable',
                                                    prods)
        self.wellformed = ok

        if ok:
            self._name = store['ident'].value
            try:
                self._fallback = store['fallback'].value
            except KeyError:
                self._fallback = None

            self._setSeq(seq)
示例#9
0
    def _productions(self):
        """Return definition used for parsing."""
        types = self._prods  # rename!

        itemProd = Choice(_ColorProd(self),
                          _DimensionProd(self),
                          _URIProd(self),
                          _ValueProd(self),
                          _CalcValueProd(self),
                          _CSSVariableProd(self),
                          _CSSFunctionProd(self)
                          )
        funcProds = Sequence(Prod(name='FUNCTION',
                                  match=lambda t, v: t == types.FUNCTION,
                                  toSeq=lambda t, tokens: (t[0],
                                                           normalize(t[1]))),
                             Choice(Sequence(itemProd,
                                             Sequence(PreDef.comma(optional=True),
                                                      itemProd,
                                                      minmax=lambda: (0, None)),
                                             PreDef.funcEnd(stop=True)),
                                    PreDef.funcEnd(stop=True))
                             )
        return funcProds
示例#10
0
    def _productions(self):
        """Return definition used for parsing."""
        types = self._prods  # rename!

        func = Prod(name='MSValue-Sub',
                    match=lambda t, v: t == self._prods.FUNCTION,
                    toSeq=lambda t, tokens: (MSValue._functionName,
                                             MSValue(pushtoken(t,
                                                               tokens
                                                               ),
                                                     parent=self
                                                     )
                                             )
                    )

        funcProds = Sequence(Prod(name='FUNCTION',
                                  match=lambda t, v: t == types.FUNCTION,
                                  toSeq=lambda t, tokens: (t[0], t[1])
                                  ),
                             Sequence(Choice(_ColorProd(self),
                                             _DimensionProd(self),
                                             _URIProd(self),
                                             _ValueProd(self),
                                             _MSValueProd(self),
                                             # _CalcValueProd(self),
                                             _CSSVariableProd(self),
                                             func,
                                             # _CSSFunctionProd(self),
                                             Prod(name='MSValuePart',
                                                  match=lambda t, v: v != ')',
                                                  toSeq=lambda t, tokens: (t[0], t[1])
                                                  )
                                             ),
                                      minmax=lambda: (0, None)
                                      ),
                             PreDef.funcEnd(stop=True)
                             )
        return funcProds
示例#11
0
    def _setCssText(self, cssText):
        if isinstance(cssText, (int, float)):
            cssText = text_type(cssText)  # if it is a number
        """
        Format::

            unary_operator
              : '-' | '+'
              ;
            operator
              : '/' S* | ',' S* | /* empty */
              ;
            expr
              : term [ operator term ]*
              ;
            term
              : unary_operator?
                [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* |
                  ANGLE S* | TIME S* | FREQ S* ]
              | STRING S* | IDENT S* | URI S* | hexcolor | function
              | UNICODE-RANGE S*
              ;
            function
              : FUNCTION S* expr ')' S*
              ;
            /*
             * There is a constraint on the color that it must
             * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
             * after the "#"; e.g., "#000" is OK, but "#abcd" is not.
             */
            hexcolor
              : HASH S*
              ;

        :exceptions:
            - :exc:`~xml.dom.SyntaxErr`:
              Raised if the specified CSS string value has a syntax error
              (according to the attached property) or is unparsable.
            - :exc:`~xml.dom.InvalidModificationErr`:
              TODO: Raised if the specified CSS string value represents a
              different type of values than the values allowed by the CSS
              property.
            - :exc:`~xml.dom.NoModificationAllowedErr`:
              Raised if this value is readonly.
        """
        self._checkReadonly()

        # used as operator is , / or S
        nextSor = ',/'
        term = Choice(_ColorProd(self, nextSor),
                      _DimensionProd(self, nextSor),
                      _URIProd(self, nextSor),
                      _ValueProd(self, nextSor),
                      #                      _Rect(self, nextSor),
                      # all other functions
                      _CSSVariableProd(self, nextSor),
                      _MSValueProd(self, nextSor),
                      _CalcValueProd(self, nextSor),
                      _CSSFunctionProd(self, nextSor)
                      )
        operator = Choice(PreDef.S(toSeq=False),
                          PreDef.char('comma', ',',
                                      toSeq=lambda t, tokens: ('operator', t[1]),
                                      optional=True
                                      ),
                          PreDef.char('slash', '/',
                                      toSeq=lambda t, tokens: ('operator', t[1]),
                                      optional=True),
                          optional=True)
        prods = Sequence(term,
                         Sequence(  # mayEnd this Sequence if whitespace
                             operator,
                             # TODO: only when setting via other class
                             # used by variabledeclaration currently
                             PreDef.char('END', ';',
                                         stopAndKeep=True,
                                         optional=True),
                             # TODO: } and !important ends too!
                             term,
                             minmax=lambda: (0, None)))
        # parse
        ok, seq, store, unused = ProdParser().parse(cssText,
                                                    'PropertyValue',
                                                    prods)
        # must be at least one value!
        ok = ok and len(as_list(self.__items(seq))) > 0

        for item in seq:
            if hasattr(item.value, 'wellformed') and not item.value.wellformed:
                ok = False
                break

        self.wellformed = ok
        if ok:
            self._setSeq(seq)
        else:
            self._log.error('PropertyValue: Unknown syntax or no value: %s' %
                            self._valuestr(cssText))
示例#12
0
文件: value.py 项目: wcq062821/Sigil
    def _setCssText(self, cssText):
        self._checkReadonly()
        types = self._prods  # rename!

        component = Choice(
            PreDef.unary(toSeq=lambda t, tokens: (t[
                0], DimensionValue(pushtoken(t, tokens), parent=self))),
            PreDef.number(toSeq=lambda t, tokens: (t[
                0], DimensionValue(pushtoken(t, tokens), parent=self))),
            PreDef.percentage(toSeq=lambda t, tokens: (t[
                0], DimensionValue(pushtoken(t, tokens), parent=self))))
        noalp = Sequence(
            Prod(name='FUNCTION',
                 match=lambda t, v: t == types.FUNCTION and v.lower() in
                 ('rgb(', 'hsl('),
                 toSeq=lambda t, tokens: (t[0], normalize(t[1]))), component,
            Sequence(PreDef.comma(optional=True),
                     component,
                     minmax=lambda: (2, 2)), PreDef.funcEnd(stop=True))
        witha = Sequence(
            Prod(name='FUNCTION',
                 match=lambda t, v: t == types.FUNCTION and v.lower() in
                 ('rgba(', 'hsla('),
                 toSeq=lambda t, tokens: (t[0], normalize(t[1]))), component,
            Sequence(PreDef.comma(optional=True),
                     component,
                     minmax=lambda: (3, 3)), PreDef.funcEnd(stop=True))
        namedcolor = Prod(name='Named Color',
                          match=lambda t, v: t == 'IDENT' and
                          (normalize(v) in as_list(self.COLORS.keys())),
                          stop=True)

        prods = Choice(PreDef.hexcolor(stop=True), namedcolor, noalp, witha)

        ok, seq, store, unused = ProdParser().parse(cssText, self.type, prods)
        self.wellformed = ok
        if ok:
            t, v = seq[0].type, seq[0].value
            if 'IDENT' == t:
                rgba = self.COLORS[normalize(v)]
            if 'HASH' == t:
                if len(v) == 4:
                    # HASH #rgb
                    rgba = (int(2 * v[1], 16), int(2 * v[2],
                                                   16), int(2 * v[3], 16), 1.0)
                else:
                    # HASH #rrggbb
                    rgba = (int(v[1:3], 16), int(v[3:5], 16), int(v[5:7],
                                                                  16), 1.0)

            elif 'FUNCTION' == t:
                functiontype, raw, check = None, [], ''
                HSL = False

                for item in seq:
                    try:
                        type_ = item.value.type
                    except AttributeError:
                        # type of function, e.g. rgb(
                        if item.type == 'FUNCTION':
                            functiontype = item.value
                            HSL = functiontype in ('hsl(', 'hsla(')
                        continue

                    # save components
                    if type_ == Value.NUMBER:
                        raw.append(item.value.value)
                        check += 'N'
                    elif type_ == Value.PERCENTAGE:
                        if HSL:
                            # save as percentage fraction
                            raw.append(item.value.value / 100.0)
                        else:
                            # save as real value of percentage of 255
                            raw.append(int(255 * item.value.value / 100))
                        check += 'P'

                if HSL:
                    # convert to rgb
                    # h is 360 based (circle)
                    h, s, l_ = raw[0] / 360.0, raw[1], raw[2]
                    # ORDER h l_ s !!!
                    r, g, b = colorsys.hls_to_rgb(h, l_, s)
                    # back to 255 based
                    rgba = [
                        int(round(r * 255)),
                        int(round(g * 255)),
                        int(round(b * 255))
                    ]

                    if len(raw) > 3:
                        rgba.append(raw[3])

                else:
                    # rgb, rgba
                    rgba = raw

                if len(rgba) < 4:
                    rgba.append(1.0)

                # validate
                checks = {
                    'rgb(': ('NNN', 'PPP'),
                    'rgba(': ('NNNN', 'PPPN'),
                    'hsl(': ('NPP', ),
                    'hsla(': ('NPPN', )
                }
                if check not in checks[functiontype]:
                    self._log.error('ColorValue has invalid %s) parameters: '
                                    '%s (N=Number, P=Percentage)' %
                                    (functiontype, check))

            self._colorType = t
            self._red, self._green, self._blue, self._alpha = tuple(rgba)
            self._setSeq(seq)
示例#13
0
文件: value.py 项目: wcq062821/Sigil
def _CSSVariableProd(parent, nextSor=False, toStore=None):
    return PreDef.variable(nextSor=nextSor,
                           toStore=toStore,
                           toSeq=lambda t, tokens:
                           (CSSVariable._functionName,
                            CSSVariable(pushtoken(t, tokens), parent=parent)))
示例#14
0
    def _setCssText(self, cssText):
        self._checkReadonly()
        types = self._prods  # rename!

        component = Choice(PreDef.unary(toSeq=lambda t, tokens: (t[0],
                                                                 DimensionValue(pushtoken(t, tokens),
                                                                                parent=self)
                                                                 )),
                           PreDef.number(toSeq=lambda t, tokens: (t[0],
                                                                  DimensionValue(pushtoken(t, tokens),
                                                                                 parent=self)
                                                                  )),
                           PreDef.percentage(toSeq=lambda t, tokens: (t[0],
                                                                      DimensionValue(pushtoken(t, tokens),
                                                                                     parent=self)
                                                                      ))
                           )
        noalp = Sequence(Prod(name='FUNCTION',
                              match=lambda t, v: t == types.FUNCTION and
                              v.lower() in ('rgb(', 'hsl('),
                              toSeq=lambda t, tokens: (t[0], normalize(t[1]))),
                         component,
                         Sequence(PreDef.comma(optional=True),
                                  component,
                                  minmax=lambda: (2, 2)
                                  ),
                         PreDef.funcEnd(stop=True)
                         )
        witha = Sequence(Prod(name='FUNCTION',
                              match=lambda t, v: t == types.FUNCTION and
                              v.lower() in ('rgba(', 'hsla('),
                              toSeq=lambda t, tokens: (t[0],
                                                       normalize(t[1]))
                              ),
                         component,
                         Sequence(PreDef.comma(optional=True),
                                  component,
                                  minmax=lambda: (3, 3)
                                  ),
                         PreDef.funcEnd(stop=True)
                         )
        namedcolor = Prod(name='Named Color',
                          match=lambda t, v: t == 'IDENT' and (
                              normalize(v) in as_list(self.COLORS.keys())
                          ),
                          stop=True)

        prods = Choice(PreDef.hexcolor(stop=True),
                       namedcolor,
                       noalp,
                       witha)

        ok, seq, store, unused = ProdParser().parse(cssText,
                                                    self.type,
                                                    prods)
        self.wellformed = ok
        if ok:
            t, v = seq[0].type, seq[0].value
            if 'IDENT' == t:
                rgba = self.COLORS[normalize(v)]
            if 'HASH' == t:
                if len(v) == 4:
                    # HASH #rgb
                    rgba = (int(2*v[1], 16),
                            int(2*v[2], 16),
                            int(2*v[3], 16),
                            1.0)
                else:
                    # HASH #rrggbb
                    rgba = (int(v[1:3], 16),
                            int(v[3:5], 16),
                            int(v[5:7], 16),
                            1.0)

            elif 'FUNCTION' == t:
                functiontype, raw, check = None, [], ''
                HSL = False

                for item in seq:
                    try:
                        type_ = item.value.type
                    except AttributeError:
                        # type of function, e.g. rgb(
                        if item.type == 'FUNCTION':
                            functiontype = item.value
                            HSL = functiontype in ('hsl(', 'hsla(')
                        continue

                    # save components
                    if type_ == Value.NUMBER:
                        raw.append(item.value.value)
                        check += 'N'
                    elif type_ == Value.PERCENTAGE:
                        if HSL:
                            # save as percentage fraction
                            raw.append(item.value.value / 100.0)
                        else:
                            # save as real value of percentage of 255
                            raw.append(int(255 * item.value.value / 100))
                        check += 'P'

                if HSL:
                    # convert to rgb
                    # h is 360 based (circle)
                    h, s, l_ = raw[0] / 360.0, raw[1], raw[2]
                    # ORDER h l_ s !!!
                    r, g, b = colorsys.hls_to_rgb(h, l_, s)
                    # back to 255 based
                    rgba = [int(round(r*255)),
                            int(round(g*255)),
                            int(round(b*255))]

                    if len(raw) > 3:
                        rgba.append(raw[3])

                else:
                    # rgb, rgba
                    rgba = raw

                if len(rgba) < 4:
                    rgba.append(1.0)

                # validate
                checks = {'rgb(': ('NNN', 'PPP'),
                          'rgba(': ('NNNN', 'PPPN'),
                          'hsl(': ('NPP',),
                          'hsla(': ('NPPN',)
                          }
                if check not in checks[functiontype]:
                    self._log.error('ColorValue has invalid %s) parameters: '
                                    '%s (N=Number, P=Percentage)' %
                                    (functiontype, check))

            self._colorType = t
            self._red, self._green, self._blue, self._alpha = tuple(rgba)
            self._setSeq(seq)
示例#15
0
def MediaQueryValueProd(parent):
    return Choice(_ColorProd(parent),
                  _DimensionProd(parent),
                  _ValueProd(parent),
                  PreDef.ratio(),
                  )
示例#16
0
文件: value.py 项目: wcq062821/Sigil
    def _setCssText(self, cssText):
        if isinstance(cssText, (int, float)):
            cssText = text_type(cssText)  # if it is a number
        """
        Format::

            unary_operator
              : '-' | '+'
              ;
            operator
              : '/' S* | ',' S* | /* empty */
              ;
            expr
              : term [ operator term ]*
              ;
            term
              : unary_operator?
                [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* |
                  ANGLE S* | TIME S* | FREQ S* ]
              | STRING S* | IDENT S* | URI S* | hexcolor | function
              | UNICODE-RANGE S*
              ;
            function
              : FUNCTION S* expr ')' S*
              ;
            /*
             * There is a constraint on the color that it must
             * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
             * after the "#"; e.g., "#000" is OK, but "#abcd" is not.
             */
            hexcolor
              : HASH S*
              ;

        :exceptions:
            - :exc:`~xml.dom.SyntaxErr`:
              Raised if the specified CSS string value has a syntax error
              (according to the attached property) or is unparsable.
            - :exc:`~xml.dom.InvalidModificationErr`:
              TODO: Raised if the specified CSS string value represents a
              different type of values than the values allowed by the CSS
              property.
            - :exc:`~xml.dom.NoModificationAllowedErr`:
              Raised if this value is readonly.
        """
        self._checkReadonly()

        # used as operator is , / or S
        nextSor = ',/'
        term = Choice(
            _ColorProd(self, nextSor),
            _DimensionProd(self, nextSor),
            _URIProd(self, nextSor),
            _ValueProd(self, nextSor),
            #                      _Rect(self, nextSor),
            # all other functions
            _CSSVariableProd(self, nextSor),
            _MSValueProd(self, nextSor),
            _CalcValueProd(self, nextSor),
            _CSSFunctionProd(self, nextSor))
        operator = Choice(PreDef.S(toSeq=False),
                          PreDef.char('comma',
                                      ',',
                                      toSeq=lambda t, tokens:
                                      ('operator', t[1]),
                                      optional=True),
                          PreDef.char('slash',
                                      '/',
                                      toSeq=lambda t, tokens:
                                      ('operator', t[1]),
                                      optional=True),
                          optional=True)
        prods = Sequence(
            term,
            Sequence(  # mayEnd this Sequence if whitespace
                operator,
                # TODO: only when setting via other class
                # used by variabledeclaration currently
                PreDef.char('END', ';', stopAndKeep=True, optional=True),
                # TODO: } and !important ends too!
                term,
                minmax=lambda: (0, None)))
        # parse
        ok, seq, store, unused = ProdParser().parse(cssText, 'PropertyValue',
                                                    prods)
        # must be at least one value!
        ok = ok and len(as_list(self.__items(seq))) > 0

        for item in seq:
            if hasattr(item.value, 'wellformed') and not item.value.wellformed:
                ok = False
                break

        self.wellformed = ok
        if ok:
            self._setSeq(seq)
        else:
            self._log.error('PropertyValue: Unknown syntax or no value: %s' %
                            self._valuestr(cssText))
示例#17
0
def MediaQueryValueProd(parent):
    return Choice(_ColorProd(parent),
                  _DimensionProd(parent),
                  _ValueProd(parent),
                  PreDef.ratio(),
                  )
    def _setCssText(self, cssText):
        """Setting this attribute will result in the parsing of the new value
        and resetting of all the properties in the declaration block
        including the removal or addition of properties.

        :exceptions:
            - :exc:`~xml.dom.NoModificationAllowedErr`:
              Raised if this declaration is readonly or a property is readonly.
            - :exc:`~xml.dom.SyntaxErr`:
              Raised if the specified CSS string value has a syntax error and
              is unparsable.

        Format::

            variableset
            : vardeclaration [ ';' S* vardeclaration ]*
            ;

            vardeclaration
            : varname ':' S* term
            ;

            varname
            : IDENT S*
            ;

            expr
            : [ VARCALL | term ] [ operator [ VARCALL | term ] ]*
            ;

        """
        self._checkReadonly()

        vardeclaration = Sequence(
            PreDef.ident(),
            PreDef.char(':', ':', toSeq=False, optional=True),
            # PreDef.S(toSeq=False, optional=True),
            Prod(name='term', match=lambda t, v: True,
                 toSeq=lambda t, tokens: ('value',
                                          PropertyValue(itertools.chain([t],
                                                                        tokens),
                                                        parent=self)
                                          )
                 )
        )
        prods = Sequence(vardeclaration,
                         Sequence(PreDef.S(optional=True),
                                  PreDef.char(';', ';', toSeq=False, optional=True),
                                  PreDef.S(optional=True),
                                  vardeclaration,
                                  minmax=lambda: (0, None)),
                         PreDef.S(optional=True),
                         PreDef.char(';', ';', toSeq=False, optional=True)
                         )
        # parse
        wellformed, seq, store, notused = \
            ProdParser().parse(cssText,
                               'CSSVariableDeclaration',
                               prods,
                               emptyOk=True)
        if wellformed:
            newseq = self._tempSeq()
            newvars = {}

            # seq contains only name: value pairs plus comments etc
            nameitem = None
            for item in seq:
                if 'IDENT' == item.type:
                    nameitem = item
                elif 'value' == item.type:
                    nname = normalize(nameitem.value)
                    if nname in newvars:
                        # replace var with same name
                        for i, it in enumerate(newseq):
                            if normalize(it.value[0]) == nname:
                                newseq.replace(i,
                                               (nameitem.value, item.value),
                                               'var',
                                               nameitem.line, nameitem.col)
                    else:
                        # saved non normalized name for reserialization
                        newseq.append((nameitem.value, item.value),
                                      'var',
                                      nameitem.line, nameitem.col)

#                    newseq.append((nameitem.value, item.value),
#                                  'var',
#                                  nameitem.line, nameitem.col)

                    newvars[nname] = item.value

                else:
                    newseq.appendItem(item)

            self._setSeq(newseq)
            self._vars = newvars
            self.wellformed = True
示例#19
0
 def prods():
     return Sequence(PreDef.char(';', ';'), PreDef.char(':', ':'))
示例#20
0
    def _setMediaText(self, mediaText):
        """
        :param mediaText:
            simple value or comma-separated list of media

        :exceptions:
            - - :exc:`~xml.dom.SyntaxErr`:
              Raised if the specified string value has a syntax error and is
              unparsable.
            - - :exc:`~xml.dom.NoModificationAllowedErr`:
              Raised if this media list is readonly.
        """
        self._checkReadonly()

        def mediaquery(): return Prod(name='MediaQueryStart',
                                      match=lambda t, v: t == 'IDENT' or v == '(',
                                      toSeq=lambda t, tokens: ('MediaQuery',
                                                               MediaQuery(pushtoken(t, tokens),
                                                                          _partof = True))
                                      )
        prods = Sequence(Sequence(PreDef.comment(parent=self),
                                  minmax=lambda: (0, None)
                                  ),
                         mediaquery(),
                         Sequence(PreDef.comma(toSeq=False),
                                  mediaquery(),
                                  minmax=lambda: (0, None))

                         )
        # parse
        ok, seq, store, unused = ProdParser().parse(mediaText,
                                                    'MediaList',
                                                    prods, debug="ml")

        # each mq must be valid
        atleastone = False

        for item in seq:
            v = item.value
            if isinstance(v, MediaQuery):
                if not v.wellformed:
                    ok = False
                    break
                else:
                    atleastone = True

        # must be at least one value!
        if not atleastone:
            ok = False
            self._wellformed = ok
            self._log.error('MediaQuery: No content.',
                            error=xml.dom.SyntaxErr)

        self._wellformed = ok

        if ok:
            mediaTypes = []
            finalseq = css_parser.util.Seq(readonly=False)
            commentseqonly = css_parser.util.Seq(readonly=False)
            for item in seq:
                # filter for doubles?
                if item.type == 'MediaQuery':
                    mediaType = item.value.mediaType
                    if mediaType:
                        if mediaType == 'all':
                            # remove anthing else and keep all+comments(!) only
                            finalseq = commentseqonly
                            finalseq.append(item)
                            break
                        elif mediaType in mediaTypes:
                            continue
                        else:
                            mediaTypes.append(mediaType)
                elif isinstance(item.value, css_parser.css.csscomment.CSSComment):
                    commentseqonly.append(item)

                finalseq.append(item)

            self._setSeq(finalseq)
示例#21
0
    def _setCssText(self, cssText):
        """Setting this attribute will result in the parsing of the new value
        and resetting of all the properties in the declaration block
        including the removal or addition of properties.

        :exceptions:
            - :exc:`~xml.dom.NoModificationAllowedErr`:
              Raised if this declaration is readonly or a property is readonly.
            - :exc:`~xml.dom.SyntaxErr`:
              Raised if the specified CSS string value has a syntax error and
              is unparsable.

        Format::

            variableset
            : vardeclaration [ ';' S* vardeclaration ]*
            ;

            vardeclaration
            : varname ':' S* term
            ;

            varname
            : IDENT S*
            ;

            expr
            : [ VARCALL | term ] [ operator [ VARCALL | term ] ]*
            ;

        """
        self._checkReadonly()

        vardeclaration = Sequence(
            PreDef.ident(),
            PreDef.char(':', ':', toSeq=False, optional=True),
            # PreDef.S(toSeq=False, optional=True),
            Prod(name='term',
                 match=lambda t, v: True,
                 toSeq=lambda t, tokens:
                 ('value',
                  PropertyValue(itertools.chain([t], tokens), parent=self))))
        prods = Sequence(
            vardeclaration,
            Sequence(PreDef.S(optional=True),
                     PreDef.char(';', ';', toSeq=False, optional=True),
                     PreDef.S(optional=True),
                     vardeclaration,
                     minmax=lambda: (0, None)), PreDef.S(optional=True),
            PreDef.char(';', ';', toSeq=False, optional=True))
        # parse
        wellformed, seq, store, notused = \
            ProdParser().parse(cssText,
                               'CSSVariableDeclaration',
                               prods,
                               emptyOk=True)
        if wellformed:
            newseq = self._tempSeq()
            newvars = {}

            # seq contains only name: value pairs plus comments etc
            nameitem = None
            for item in seq:
                if 'IDENT' == item.type:
                    nameitem = item
                elif 'value' == item.type:
                    nname = normalize(nameitem.value)
                    if nname in newvars:
                        # replace var with same name
                        for i, it in enumerate(newseq):
                            if normalize(it.value[0]) == nname:
                                newseq.replace(i, (nameitem.value, item.value),
                                               'var', nameitem.line,
                                               nameitem.col)
                    else:
                        # saved non normalized name for reserialization
                        newseq.append((nameitem.value, item.value), 'var',
                                      nameitem.line, nameitem.col)

#                    newseq.append((nameitem.value, item.value),
#                                  'var',
#                                  nameitem.line, nameitem.col)

                    newvars[nname] = item.value

                else:
                    newseq.appendItem(item)

            self._setSeq(newseq)
            self._vars = newvars
            self.wellformed = True