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
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), ), ), ) _operant = lambda: Choice( # noqa:E731 _DimensionProd(self), _CalcValueProd(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)
def _productiondefinition(self): """Return definition used for parsing.""" types = self._prods # rename! value = Sequence( PreDef.unary(), Prod( name='PrimitiveValue', match=lambda t, v: t in ( types.DIMENSION, types.HASH, types.IDENT, types.NUMBER, types.PERCENTAGE, types.STRING, ), toSeq=lambda t, tokens: (t[0], CSSPrimitiveValue(t[1])), ), ) valueOrFunc = Choice( value, # FUNC is actually not in spec but used in e.g. Prince PreDef.function(toSeq=lambda t, tokens: ( 'FUNCTION', CSSFunction(cssutils.helper.pushtoken(t, tokens)), )), ) funcProds = Sequence( Prod( name='FUNC', match=lambda t, v: t == types.FUNCTION, toSeq=lambda t, tokens: (t[0], cssutils.helper.normalize(t[1])), ), Choice( Sequence( valueOrFunc, # more values starting with Comma # should use store where colorType is saved to # define min and may, closure? Sequence(PreDef.comma(), valueOrFunc, minmax=lambda: (0, None)), PreDef.funcEnd(stop=True), ), PreDef.funcEnd(stop=True), ), ) return funcProds
def _productiondefinition(self): """Return defintion used for parsing.""" types = self._prods # rename! def toSeq(t, tokens): "Do not normalize function name!" return t[0], t[1] funcProds = Sequence( Prod(name='expression', match=lambda t, v: t == types.FUNCTION, toSeq=toSeq), Sequence( Choice( Prod( name='nested function', match=lambda t, v: t == self._prods.FUNCTION, toSeq=lambda t, tokens: ( ExpressionValue._functionName, ExpressionValue( cssutils.helper.pushtoken(t, tokens)), ), ), Prod( name='part', match=lambda t, v: v != ')', toSeq=lambda t, tokens: (t[0], t[1]), ), ), minmax=lambda: (0, None), ), PreDef.funcEnd(stop=True), ) return funcProds
def _setCssText(self, cssText): self._checkReadonly() types = self._prods # rename! valueProd = Prod( name='value', match=lambda t, v: t in (types.NUMBER, types.PERCENTAGE), toSeq=lambda t, v: (CSSPrimitiveValue, CSSPrimitiveValue(v)), toStore='parts', ) # COLOR PRODUCTION funccolor = Sequence( Prod( name='FUNC', match=lambda t, v: t == types.FUNCTION and cssutils.helper. normalize(v) in ('rgb(', 'rgba(', 'hsl(', 'hsla('), toSeq=lambda t, v: (t, v), # cssutils.helper.normalize(v)), toStore='colorType', ), PreDef.unary(), valueProd, # 2 or 3 more values starting with Comma Sequence(PreDef.comma(), PreDef.unary(), valueProd, minmax=lambda: (2, 3)), PreDef.funcEnd(), ) colorprods = Choice( funccolor, PreDef.hexcolor('colorType'), Prod( name='named color', match=lambda t, v: t == types.IDENT, toStore='colorType', ), ) # store: colorType, parts wellformed, seq, store, unusedtokens = ProdParser().parse( cssText, 'RGBColor', colorprods, keepS=True, store={'parts': []}) if wellformed: self.wellformed = True if store['colorType'].type == self._prods.HASH: self._colorType = 'HEX' elif store['colorType'].type == self._prods.IDENT: self._colorType = 'Named Color' else: self._colorType = store['colorType'].value[:-1] # self._colorType = \ # cssutils.helper.normalize(store['colorType'].value)[:-1] self._setSeq(seq)
def _setCssText(self, cssText): self._checkReadonly() types = self._prods # rename! funcProds = Sequence( Prod(name='var', match=lambda t, v: t == types.FUNCTION), PreDef.ident(toStore='ident'), PreDef.funcEnd(stop=True), ) # store: name of variable store = {'ident': None} wellformed, seq, store, unusedtokens = ProdParser().parse( cssText, 'CSSVariable', funcProds, keepS=True) if wellformed: self._name = store['ident'].value self._setSeq(seq) self.wellformed = True
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)
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
def _setCssText(self, cssText): # noqa: C901 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 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 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 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)