Source code for scalingparser
# python 2
from __future__ import absolute_import
# plugins
from cssutils.css import Property
# custom
from blowdrycss.utilities import deny_empty_or_whitespace
from blowdrycss.unitparser import UnitParser
from blowdrycss_settings import small, medium, large
__author__ = 'chad nelson'
__project__ = 'blowdrycss'
# TODO: Handle negative numbers, or list as unsupported.
# TODO: Should it be possible to switch between scaling up and scaling down?
[docs]class ScalingParser(object):
""" Enables powerful responsive @media query generation via screen size suffixes.
**Scaling Flag:**
Append ``'-s'`` to the end of an encoded property values to scale the value up and down based on screen size.
Note: This only works on property values containing distance--based units (pixels, em, etc).
- General format: ``<name>-<value>-s``
- Specific case: ``font-size-24-s``
- Priority ``!important`` case: ``font-size-24-s-i``
- (``'-i'`` *is always last*)
**Responsive Scaling Ratios:**
- Assuming ``font-size-24-s`` is the encoded css class, the font-size will respond to the screen size according
to the following table:
+-------------+-------------------+----------------+------+-------+
| Screen Size | Trigger Range | Scaling Factor | px | em |
+-------------+-------------------+----------------+------+-------+
| XLarge | > 1024 or 64.0em | 1 | 24 | 1.5 |
+-------------+-------------------+----------------+------+-------+
| Large | > 720px & <= 1024 | 1.043 | 23.0 | 1.438 |
+-------------+-------------------+----------------+------+-------+
| Medium | < 720px or 45.0em | 1.125 | 21.3 | 1.333 |
+-------------+-------------------+----------------+------+-------+
| Small | < 480px or 30.0em | 1.25 | 19.2 | 1.2 |
+-------------+-------------------+----------------+------+-------+
**Important Note about cssutils**
Currently, ``cssutils`` does not support parsing media queries. Therefore, media queries need to be built, minified,
and appended separately.
:type css_class: str
:type css_property: Property()
:param css_class: Potentially encoded css class that may or may not be parsable. May not be empty or None.
:param css_property: Valid CSS Property as defined by ``cssutils.css.Property``.
:return: None
**Examples:**
>>> scaling_parser = ScalingParser(css_class='font-weight-24-s')
"""
def __init__(self, css_class='', css_property=Property()):
deny_empty_or_whitespace(css_class, variable_name='css_class')
deny_empty_or_whitespace(css_property.cssText, variable_name='css_property')
self.css_class = css_class
self.css_property = css_property
self.scale_dict = {
'large': 1.043,
'medium': 1.125,
'small': 1.25,
}
self.scaling_flag = '-s'
self.is_scaling = self._is_scaling()
def _is_scaling(self):
""" Return False if ``self.property_name`` does not have default units of ``'px'``.
Test if ``self.css_class`` contains the scaling flag ``-s``. Returns True if ``-s`` is found and
False otherwise.
**Rules:**
- The ``self.property_name`` must possess units of pixels ``'px'``.
- If no property priority is set the encoded ``css_class`` must end with ``-s``.
- If priority is set the encoded ``css_class`` must end with ``-s-i``.
:return: (*bool*) -- Returns True if ``-s`` is found and False otherwise.
**Examples**
>>> scaling_parser = ScalingParser(css_class='font-weight-24-s')
>>> scaling_parser._is_scaling()
True
>>> scaling_parser.css_class = 'font-weight-24-s-i'
>>> scaling_parser._is_scaling()
True
>>> scaling_parser.css_class = 'font-weight-24'
>>> scaling_parser._is_scaling()
False
"""
unit_parser = UnitParser(property_name=self.css_property.name)
if unit_parser.default_units() != 'px':
return False
else:
return self.css_class.endswith(self.scaling_flag) or self.css_class.endswith(self.scaling_flag + '-i')
[docs] def strip_scaling_flag(self):
""" Remove the ``scaling_flag`` from ``css_class`` if possible and return the clean css class. Otherwise,
return the ``css_class`` unchanged.
**Rules**
- Remove ``-s`` if found at end of a string
- Remove ``-s`` if ``-s-i`` is found at the end of the string.
:return: (*str*) -- If the ``css_class`` is scaling remove the ``scaling_flag`` and return the clean
css class. Otherwise, return the ``css_class`` unchanged.
**Examples:**
>>> scaling_parser = ScalingParser(css_class='font-size-32-s', name='font-size')
>>> scaling_parser.strip_scaling_flag()
font-size-32
>>> scaling_parser.css_class = 'font-size-56-s-i'
>>> scaling_parser.strip_scaling_flag()
font-size-56-i
>>> scaling_parser.css_class = 'font-size-14'
>>> scaling_parser.strip_scaling_flag()
font-size-14
"""
if self.css_class.endswith(self.scaling_flag):
return self.css_class[:-2]
if self.css_class.endswith(self.scaling_flag + '-i'):
return self.css_class[:-4] + '-i'
return self.css_class