64 lines
2.6 KiB
Python
64 lines
2.6 KiB
Python
# ------------------------------------------------------------------------------
|
|
import re
|
|
|
|
# ------------------------------------------------------------------------------
|
|
def parseStyleAttribute(value, asDict=False):
|
|
'''Returns a list of CSS (name, value) pairs (or a dict if p_asDict is
|
|
True), parsed from p_value, which holds the content of a HTML "style"
|
|
tag.'''
|
|
if asDict: res = {}
|
|
else: res = []
|
|
for attr in value.split(';'):
|
|
if not attr.strip(): continue
|
|
name, value = attr.split(':', 1)
|
|
if asDict: res[name.strip()] = value.strip()
|
|
else: res.append( (name.strip(), value.strip()) )
|
|
return res
|
|
|
|
# ------------------------------------------------------------------------------
|
|
class CssValue:
|
|
'''Represents a CSS value having unit "px" or "%": value and unit are
|
|
extracted in attributes of the same name. If no unit is specified, "px"
|
|
is assumed.'''
|
|
valueRex = re.compile('(\d+)(%|px)?')
|
|
|
|
def __init__(self, value):
|
|
value, unit = CssValue.valueRex.match(value)
|
|
if not unit: unit = 'px'
|
|
self.value = int(value)
|
|
self.unit = unit
|
|
def __str__(self): return '%d%s' % (self.value, self.unit)
|
|
def __repr__(self): return self.__str__()
|
|
|
|
class CssStyles:
|
|
'''This class represents a set of styles collected from:
|
|
* an HTML "style" attribute;
|
|
* other attributes like "width".
|
|
'''
|
|
# The list of CSS properties having a unit (px or %)
|
|
withUnit = ('width', 'height')
|
|
|
|
def __init__(self, elem, attrs):
|
|
'''Analyses styles as found in p_attrs and sets, for every found style,
|
|
an attribute on self.'''
|
|
# First, parse the "style" attr if present
|
|
if 'style' in attrs.keys():
|
|
styles = parseStyleAttribute(attrs['style'], asDict=True)
|
|
for name, value in styles.items():
|
|
if name in CssStyles.withUnit:
|
|
value = CssValue(value)
|
|
setattr(self, name.replace('-', ''), value)
|
|
# Parse attributes "width" and "height" if present. But they will not
|
|
# override corresponding attributes from the "styles" attributes if
|
|
# found.
|
|
for name in ('width', 'height'):
|
|
if not hasattr(self, name) and name in attrs.keys():
|
|
setattr(self, name, CssValue(attrs[name]))
|
|
|
|
def __repr__(self):
|
|
res = '<CSS'
|
|
for name, value in self.__dict__.items():
|
|
res += ' %s:%s' % (name, value)
|
|
return res + '>'
|
|
# ------------------------------------------------------------------------------
|