blowdrycss¶
blowdrycss is a rapid styling tool that compiles DRY CSS from encoded class selectors in your web project files.
blowdry¶
-
blowdry.boilerplate()[source]¶ Watchdog wrapper only calls this once to eliminate recurring performance impact.
- Validate the output_file_name and output_extenion settings.
- Generate Markdown documentation files.
- Generate HTML documentation files. (This location is important since it allows encoded css to be included in the documentation files.)
- Generate reStructuredText documentation files.
Returns: None
-
blowdry.parse(recent=True, class_set=set(), css_text=b'')[source]¶ - It parses every eligible file in the project i.e. file type matches an element of settings.file_types.
This ensures that from time to time unused CSS class selectors are removed from blowdry.css.
Order of Operations:
- Initialize settings.
- Start performance timer.
- Define File all file types/extensions to search for in project_directory
- Get all files associated with defined file_types in project_directory
- Get set of all defined classes
- Filter class names only keeping classes that match the defined class encoding.
- Build a set() of valid css properties. Some classes may be removed during cssutils validation.
- Output the DRY CSS file. (user command option)
- Output the Minified DRY CSS file. (user command option)
Depending on the settings this script generates the following:
- DRY CSS files
- blowdry.css :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. human readable
- blowdry.min.css :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. minified
- Clashing Alias files (Encoded class selector aliases that are invalid and cannot be used because they clash.)
- Markdown :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. Github
- HTML :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. Browser
- reStructuredText :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. Sphinx
- Property Alias File (Encoded class selector aliases that are valid and can be used to construct class selectors.)
- Markdown :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. Github
- HTML :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. Browser
- reStructuredText :param css_text: :type recent: bool :param recent: Flag that indicates whether to parse the most recently modified files (True Case) or all eligible files (False Case). :type class_set: set :param class_set: The set of known css class selectors. :type css_text: bytes :param css_text: The current version of the CSS text. Sphinx
- Temporal Statistics
Note: The default locations of these files can be overridden to suit your needs.
Directory assignments
project_directory– Allowsblowdrycssto know where the HTML project is located. It will only search the files in the directory specified here.
blowdrycss_settings¶
Usage Notes:
The first time blowdrycss is run it auto-builds blowdrycss_settings.py via __init__.py.
This makes it easy to find and customize related settings.
Why such a long name? – blowdrycss_settings.py
Popular web frameworks such as django and flask already auto-generate a settings file called settings.py.
The longer more specific name is used to prevent naming conflicts, and increase clarity.
Parameters:
file_types.Example format:
('*.html', )
blowdrycss.blowdry.css by
default.blowdry.min.css by default.pixels to em unit conversion flag. True enables unit conversion.
False disables unit conversions meaning any pixel value remains unchanged.base during unit conversion.Custom Alias Syntax:
'c-' is an alias for 'color'. This saves on typing.file_type.
They can be customized to your liking.cssutils Patch:
cssutils does not currently support all CSS 3 Units. The patch in this file allows length units of
q, ch, rem, vw, vh, vmin, and vmax. It also allows angle units of turn.
-
blowdrycss_settings.px_to_em(pixels)[source]¶ Convert a numeric value from px to em using
settings.baseas the unit conversion factor.Rules:
pixelsshall only contain [0-9.-].- Inputs that contain any other value are simply passed through unchanged.
- Default
baseis 16 meaning16px = 1rem
Note: Does not check the
property_nameoruse_emvalues. Rather, it blindly converts whatever input is provided. The calling method is expected to know what it is doing.Rounds float to a maximum of 4 decimal places.
Parameters: pixels (str, int, float) – A numeric value with the units stripped. Returns: (str) - If the input is convertible return the converted number as a string with the units
emappended to the end. - If the input is not convertible return the unprocessed input.
>>> from blowdrycss_settings import px_to_em >>> # settings.use_em = True >>> px_to_em(pixels='-16.0') -1em >>> # settings.use_em = False >>> px_to_em(pixels='42px') 42px >>> # Invalid input passes through. >>> px_to_em(pixels='invalid') invalid
datalibrary¶
-
class
datalibrary.DataLibrary[source]¶ DataLibrary is not intended for use outside of this file as each time its’ called it rebuilds the dictionaries.
Attributes:
property_regex_dict (dict)A regex dictionary for detecting more complex value patterns for a given property.
Dictionary Contains:
- The
keyis the official CSS property name. - The
valueis aset()of regex strings.
Regexes Cases:
- Hexidecimal (3 digit) – ‘h123’, ‘h123 bold’, ‘underline h123 bold’
- Hexidecimal (6 digit) – ‘h123456’, ‘h123456 underline’, ‘underline h123456 bold’
- Hexidecimal (3 digit + pseudo-class + importance designator) – ‘h123-hover-i’, ‘h123-after-i bold’,
- Hexidecimal (6 digit + pseudo-class + importance designator) – ‘h12ad56-hover-i’, ‘h12AD56-hover-i underline’
- Hexidecimal (3 digit + importance designator + pseudo-class) – ‘h1f3-i-hover’, ‘h1F3-i-hover bold’
- Hexidecimal (6 digit + importance designator + pseudo-class) – ‘h123456-i-hover’, ‘h123456-i-hover underline’
- Hexidecimal Regex explained
r"(h[0-9a-fA-F]{3} ?)$"orr"(h[0-9a-fA-F]{6} ?)$"h– The substring must begin with anh.[0-9a-fA-F]– The characters that follow must be a hexidecimal characters.{3}or{6}– Limit the number of hexidecimal characters to either 3 or 6 only.' ?'– The substring may optionally be followed by a space.
property_value_as_alias_dict (dict)Maps valid, unique W3C CSS property values to a W3C CSS property name. This enables the use of unique property values as standalone class selectors i.e.
boldcan be used in place offont-weight-bold. This makes the syntax succinct while remaining declarative.Rules:
- The property value alias must be unique across all valid W3C defined property values.
- The property value alias must be unique across all property values defined in the dictionary.
- The
keyis the official CSS property name. - The
valueis aset()of valid, unique W3C CSS property values.
Example:
``'font-weight': {'bold', 'bolder', 'lighter', },``Allowed values for font-weight according to W3C. Based on the standard
normalis a valid property value. However,normalis not unique tofont-weight. To verify that go here and search fornormal. Also,100 - 900are listed as valid values, but CSS class selectors cannot begin with a digit. This implies that the numeric values cannot be included. That leavesbold, bolder, and lighter.property_names (set)The set of all CSS 2.1 property names listed here: http://www.w3.org/TR/CSS21/propidx.html on the W3C website.clashing_alias_dict (dict)Auto-generated dictionary of clashing aliases. An alias clashes if it exactly equals an alias associated with another property e.g. One alias for
border-rightis'br-'. Howeverbackground-repeathas an identical alias of'br-'. Therefore'br-'is added toclashing_alias_dictand is not allowed to be used as an alias.Dictionary Contains:
- The
keyis the official CSS property name. - The
valueis aset()of custom string aliases.
property_alias_dict (dict)Auto-generated dictionary of property aliases.
Dictionary Contains:
- The
keyis the official CSS property name. - The
valueis aset()of custom string aliases.
alphabetical_clashing_dict (dict)Alphabetized ordered dictionary of clashing aliases.
Ordered Dictionary Contains:
- The
keyis the official CSS property name. - The
valueis aset()of clashing string aliases.
alphabetical_property_dict (dict)Alphabetized ordered dictionary of property aliases.
Ordered Dictionary Contains:
- The
keyis the official CSS property name. - The
valueis aset()of custom string aliases.
clashing_alias_markdown (str) – Auto-generated table of clashing aliases in markdown format.property_alias_markdown (str) – Auto-generated table of property names and aliases in markdown format.clashing_alias_html (str) – Auto-generated table of clashing aliases in HTML format.property_alias_html (str) – Auto-generated table of property names and aliases in HTML format.clashing_alias_rst (str) – Auto-generated table of clashing aliases in reStructuredText format.property_alias_rst (str) – Auto-generated table of property names and aliases in reStructuredText form.ordered_property_dict (dict)Sorted property_alias_dict with the longest items first as the most verbose match is preferred i.e. If
css_class == 'margin-top', then match theproperty_alias_dictkey that starts withmargin-topnotmargin.Ordered Dictionary Contains:
- The
keyis the official CSS property name. - The
valueis aset()of custom string aliases.
-
static
get_property_aliases(property_name='')[source]¶ Auto-generates and returns a set of aliases based on abbreviation patterns.
Rules:
Property name does not contain a dash: {First three letters of property_name +
'-'}Property name contains one dashes:
1st word + 1st letter after dash +'-'1st letter of 1st word + 1st letter of 2nd word +'-', (single dash case)1st letter of 1st word + 1st letter of 2nd word + 1st letter of 3rd word +'-', (double dash case)Append dash ‘-‘ at the end of each abbreviation.
Do not abbreviate words less than or equal to 5 characters in length.
Examples:
property_name --> {...} color --> set() padding --> {'pad-'} margin-top --> {'margin-t-', 'mt-'} border-bottom-width --> {'border-b-width', 'bbw-'}
Parameters: property_name (str) – A CSS property name. Returns: Return a set() of abbreviation patterns according to the rules defined above.
-
autogen_property_alias_dict()[source]¶ Uses
self.property_namesto auto–generate a property aliases. Assigns the result toself.property_alias_dict.Note: The dictionary may contain clashing aliases. More processing is required to remove them.
-
merge_dictionaries()[source]¶ Merges the
property_alias_dictwithproperty_value_as_alias_dict.Note: All keys in both dictionaries much match.
Raises: KeyError – Raises KeyError if property name does not exist as a key in property_alias_dict.
-
set_clashing_aliases()[source]¶ Searches
property_alias_dictfor duplicate / clashing aliases and adds them toclashing_alias_dict.
-
remove_clashing_aliases()[source]¶ Removes clashing aliases stored in
clashing_alias_dictfromproperty_alias_dictand deep copies the clean dictionary toproperty_alias_dict.
-
static
dict_to_markdown(h1_text='', key_title='', value_title='', _dict=None)[source]¶ Convert a dictionary into a markdown formatted 2-column table.
Markdown Table Format:
# h1_textkey_title | value_title--- | ---key[0] | valuekey[1] | valueParameters: - h1_text (str) – Title for the table.
- key_title (str) – Key name.
- value_title (str) – Value stored at Key.
- _dict (dict) – A generic dictionary.
Returns: (str) – Returns a markdown formatted 2-column table based on the key/value pairs in
_dict.
-
static
dict_to_html(h1_text='', key_title='', value_title='', _dict=None)[source]¶ Convert a dictionary into an HTML formatted 2-column table.
HTML Table Format:
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="icon" type="image/x-icon" href="/images/favicon.ico" /> <title>value_title - blowdrycss</title> <link rel="stylesheet" type="text/css" href="/css/blowdry.min.css"/> </head> <body> <table> <thead> <tr> <th>key_title</th> <th>value_title</th> </tr> </thead> <tbody> <tr> <td>key[0]</td> <td>value</td> </tr> </tbody> </table> </body> </html>
Parameters: - h1_text (str) – Title for the table.
- key_title (str) – Key name.
- value_title (str) – Value stored at Key.
- _dict (dict) – A generic dictionary.
Returns: (str) – Returns a HTML formatted 2-column table based on the key/value pairs in
_dict.
- The
filehandler¶
-
class
filehandler.FileFinder(recent=True)[source]¶ Designed to find all
settings.files_typesspecified within a particularproject_directory. All folders within theproject_directoryare searched.Parameters:recent (str) – Flag that indicates whether to gather the most recently modified files (True Case) or all eligible files (False Case).Members:project_directory (str) – Set to settings.project_directory.files (str list) – List of all paths to all parsable files.file_dict (dict) – Dictionary of all paths to all parsable files where the file extension e.g.*.htmlis the key and the full file path is the value.Example:
>>> file_finder = FileFinder(recent=False) >>> files = file_finder.files
-
static
print_collection(collection)[source]¶ Takes a list or tuple as input and prints each item.
Parameters: collection (iterable) – A list or tu of unicode strings to be printed. Returns: None
-
set_files()[source]¶ Get all files associated with defined
file_typesinproject_directory. For eachfile_typefind the full path to each file in the project directory of the currentfile_type. Add the full path of each file found to the listself.files.Reference: stackoverflow.com/questions/954504/how-to-get-files-in-a-directory-including-all-subdirectories#answer-954948
Returns: None
-
set_file_dict()[source]¶ Filter and organize files by type in
file_dict.Dictionary Format:
self.file_dict = { '.html': {'filepath_1.html', 'filepath_2.html', ..., 'filepath_n.html'}, '.aspx': {'filepath_1.aspx', 'filepath_2.aspx', ..., 'filepath_n.aspx'}, ... '.file_type': {'filepath_1.file_type', 'filepath_2.file_type', ..., 'filepath_n.file_type'}, }
Automatically removes the * wildcard from
file_type.Returns: None
-
set_recent_file_dict()[source]¶ Filter and organize recent files by type in
file_dict. Meaning only files that are newer than the latest version of blowdry.css are added.Dictionary Format:
self.file_dict = { '.html': {'filepath_1.html', 'filepath_2.html', ..., 'filepath_n.html'}, '.aspx': {'filepath_1.aspx', 'filepath_2.aspx', ..., 'filepath_n.aspx'}, ... '.file_type': {'filepath_1.file_type', 'filepath_2.file_type', ..., 'filepath_n.file_type'}, }
Automatically removes the * wildcard from
file_type.Returns: None
-
static
-
class
filehandler.FileConverter(file_path='')[source]¶ Converts text files to strings.
On initialization checks the existence of
file_path.Example:
>>> from os import getcwd, chdir, path >>> # Valid file_path >>> current_dir = getcwd() >>> chdir('..') >>> file_path = path.join(current_dir, 'examplesite', 'index.html') >>> chdir(current_dir) # Change it back. >>> file_converter = FileConverter(file_path=file_path) >>> file_string = file_converter.get_file_as_string() >>> # >>> # Invalid file_path >>> file_converter = FileConverter(file_path='/not/valid/file.html') FileNotFoundError: file_path /not/valid/file.html does not exist.
-
get_file_as_string()[source]¶ Convert the _file to a string and return it.
Returns: (str) Return the _file as a string. Example:
>>> from os import getcwd, chdir, path >>> current_dir = getcwd() >>> chdir('..') >>> file_path = path.join(current_dir, 'examplesite', 'index.html') >>> chdir(current_dir) # Change it back. >>> file_converter = FileConverter(file_path=file_path) >>> file_string = file_converter.get_file_as_string()
-
-
class
filehandler.CSSFile[source]¶ A tool for writing and minifying CSS to files.
Reference: stackoverflow.com/questions/273192/in-python-check-if-a-directory-exists-and-create-it-if-necessary#answer-14364249
Parameters:css_directory (str) – File directory where the .css and .min.css output files are stored.Members:file_name (str) – Defined in blowdrycss_settings.py asoutput_file_name. Default is ‘blowdry’.extension (str) – Defined in blowdrycss_settings.py asoutput_extension. Default is ‘.css’.Note: The output file is namedfile_name + extensionorfile_name + .min + extension. ex1: blowdry.css or blowdry.min.css ex2: _custom.scss or _custom.min.scssExample:
>>> from os import getcwd, chdir, path >>> current_dir = getcwd() >>> chdir('..') >>> project_directory = path.join(current_dir, 'examplesite') >>> css_directory = path.join(project_directory, 'css') >>> chdir(current_dir) # Change it back. >>> css_text = '.margin-top-50px { margin-top: 3.125em }' >>> css_file = CSSFile( >>> file_directory=css_directory, file_name='blowdry' >>> ) >>> css_file.write(css_text=css_text) >>> css_file.minify(css_text=css_text)
-
write(css_text='')[source]¶ Output a human readable version of the css file in utf-8 format.
Notes:
- The file is human readable. It is not intended to be human editable as the file is auto-generated.
- Pre-existing files with the same name are overwritten.
Parameters: css_text (str) – Text containing the CSS to be written to the file. Returns: None Example:
>>> css_text = '.margin-top-50px { margin-top: 3.125em }' >>> css_file = CSSFile() >>> css_file.write(css_text=css_text)
-
minify(css_text='')[source]¶ Output a minified version of the css file in utf-8 format.
Definition:
The term minify “in the context of CSS means removing all unnecessary characters, such as spaces, new lines, comments without affecting the functionality of the source code.”
Source: https://www.jetbrains.com/phpstorm/help/minifying-css.html
Purpose:
The purpose of minification is to increase web page load speed.Reducing the size of the CSS file reduces the time spent downloading the CSS file and waiting for the page to load.Notes:
- The file is minified and not human readable.
- Pre-existing files with the same name are overwritten.
- Uses the cssutils minification tool.
Important:
ser.prefs.useMinified()is a global setting. It must be reset toser.prefs.useDefaults(). Otherwise, minification will continue to occur. This can result in strange behavior especially during unit testing or in code called after this method is called.
Parameters: css_text (str) – Text containing the CSS to be written to the file. Returns: None Example:
>>> css_text = '.margin-top-50px { margin-top: 3.125em }' >>> css_file = CSSFile() >>> css_file.minify(css_text=css_text)
-
-
class
filehandler.GenericFile(file_directory='/home/docs/checkouts/readthedocs.org/user_builds/blowdrycss/checkouts/stable/docs', file_name='', extension='')[source]¶ A tool for writing extension-independent files.
Reference: stackoverflow.com/questions/273192/in-python-check-if-a-directory-exists-and-create-it-if-necessary#answer-14364249
Parameters:file_directory (str) – File directory where the output files are saved / overwritten.file_name (str) – The name of the output file. Default is ‘blowdry’.extension (str) – A file extension that begins with a.and only contains.,0-9ora-z.Notes:file_namedoes not include extension becausewrite_file()normalizes and appends the extension.extensionis converted to lowercase.
Example:
>>> from os import getcwd, path >>> file_directory = path.join(getcwd()) >>> css_text = '.margin-top-50px { margin-top: 3.125em }' >>> markdown_file = GenericFile( >>> file_directory=file_directory, >>> file_name='blowdry', >>> extension='.md' >>> ) >>> text = '# blowdrycss' >>> markdown_file.write(text=text)
-
write(text='')[source]¶ Output a human readable version of the file in utf-8 format.
Converts string to bytearray so that no new lines are added to the file. Note: Overwrites any pre-existing files with the same name.
Raises: TypeError – Raise a TypeError if textinput is not of typestr.Parameters: text (unicode or str) – The text to be written to the file. Returns: None
-
class
filehandler.FileModificationComparator[source]¶ A Comparator that compares the last modified time of blowdry.css with the last modified time of another file.
Returns: None Example
>>> import blowdrycss_settings as settings >>> from blowdrycss.filehandler import FileModificationComparator >>> file_age_comparator = FileModificationComparator() >>> print(file_age_comparator.is_newer(file_path=path.join(settings.project_directory, '/index.html'))
-
is_newer(file_path)[source]¶ Detects if
self.file_pathwas modified more recently than blowdry.css. Ifself.file_pathis newer than blowdry.css or blowdry.min.css it returns True otherwise it returns false.If blowdry.css or blowdry.min.css do not exist, then the file under comparison is newer.
Parameters: file_path (str) – The full path to a file. Returns: (bool) Returns True if modification time of blowdry.css or blowdry.min.css do not exist, or are older i.e. less than the self.file_pathunder consideration.
-
cssbuilder¶
-
class
cssbuilder.CSSBuilder(property_parser=<blowdrycss.classpropertyparser.ClassPropertyParser object>)[source]¶ Builds CSS text with the
cssutils.cssmodule.Note: Removes invalid classes. A class is invalid for one of the following reasons:
- It is not valid CSS.
- It does not contain a valid
blowdrycssencoding.
Object initialization process:
- Build CSS property rules
- Add to css_rules, OR remove invalid css_class from class_set.
- Build a CSS stylesheet based on the CSS
css_rulesset.
Parameters: property_parser (ClassPropertyParser object) – Contains a class property parser with a populated class_set.Returns: None-
build_selector(css_class='')[source]¶ Builds a CSS selector by prepending a
'.'tocss_class, and appending an optional pseudo item.Rules
- Always append a
'.'tocss_class. - If a pseudo class is found append
':' + pseuedo_classtocss_class. - If a pseudo element is found append
'::' + pseudo_elementtocss_class.
Parameters: css_class (str) – This value may or may not be identical to the property_value. Returns: str – The selector with a ‘.’ prepended and an option pseudo item appended. - Always append a
mediaquerybuilder¶
-
class
mediaquerybuilder.MediaQueryBuilder(property_parser=<blowdrycss.classpropertyparser.ClassPropertyParser object>)[source]¶ Builds a set of CSS media queries from valid classes found in
ClassPropertyParser.class_set.Takes a set of classes that may or may not contain media query flags.Mixing breakpoint and scaling syntax is not allowed. Classes that contain mixed syntax like the following:small-down-sorfont-size-28-medium-only-sare invalidated.Parameters: property_parser (ClassPropertyParser) – ClassPropertyParser object containing class_set.Returns: None Example Usage:
>>> import blowdrycss_settings as settings >>> from classpropertyparser import ClassPropertyParser >>> class_set = {'bold', 'large-down', 'font-size-25-s'} >>> # Filter class names. Only keep classes matching the defined class encoding. >>> property_parser = ClassPropertyParser(class_set=class_set) >>> class_set = property_parser.class_set.copy() >>> # Build Media Queries >>> if settings.media_queries_enabled: >>> unassigned_class_set = class_set.difference(property_parser.class_set) >>> # Only use unassigned classes >>> property_parser.class_set = unassigned_class_set >>> property_parser.removed_class_set = set() >>> media_query_builder = MediaQueryBuilder(property_parser=property_parser) >>> css_text = bytes(media_query_builder.get_css_text(), 'utf-8') >>> print(media_query_builder.property_parser.class_set) {'large-down', 'font-size-25-s'}
-
get_css_text()[source]¶ Joins
css_media_queriestogether with an empty separator string''.Returns: str – Returns all media queries as CSS text. Example
>>> from classpropertyparser import ClassPropertyParser >>> class_set = {'bold', 'large-down', 'font-size-24-s'} >>> # Filter class names. Only keep classes matching the defined class encoding. >>> property_parser = ClassPropertyParser(class_set=class_set) >>> media_query_builder = MediaQueryBuilder(property_parser=property_parser) >>> print(media_query_builder.get_css_text()) @media only screen and (min-width: 64.0em) { .large-down { display: none; } } .font-size-24-s { font-size: 24px; @media only screen and (max-width: 45.0em) { font-size: 21.3px; } @media only screen and (max-width: 30.0em) { font-size: 19.2px; } }
-
classpropertyparser¶
Parser for extracting CSS property names, values, and priorities from set of CSS Class Selectors. These class
selectors are gathered externally by the HTMLClassParser().
- Parameters:
- class_set (set) – A set() of potential css properties.
Returns: Object of Type ClassPropertyParser
Examples:
Give this HTML: <div class="super-5 h-16-i padding-2 margin-10">Hello</div>
The HTMLClassParser() would extract the following class_set.
>>> class_set = {'super-5', 'h-16-i', 'PADDING-2', 'margin-10', }
>>> property_parser = ClassPropertyParser(class_set)
>>> # Note that 'super-5' was removed.
>>> print(property_parser.class_set)
{'h-16-i', 'padding-2', 'margin-10'}
>>> css_class = list(property_parser.class_set)[0]
>>> print(css_class)
h-16-i
>>> name = property_parser.get_property_name(css_class=css_class)
>>> # Decodes 'h-' to 'height'
>>> print(name)
height
>>> # Could throw a ValueError.
>>> # See cssbuilder.py for an example of how to handle it.
>>> encoded_property_value = property_parser.get_encoded_property_value(
>>> property_name=name,
>>> css_class=css_class
>>> )
>>> print(encoded_property_value)
16
>>> priority = property_parser.get_property_priority(css_class=css_class)
>>> print(priority)
IMPORTANT
>>> value = property_parser.get_property_value(
>>> property_name=name,
>>> encoded_property_value=encoded_property_value
>>> )
>>> print(value) # Note the unit conversion from px_to_em.
1em
-
class
classpropertyparser.ClassPropertyParser(class_set=set())[source]¶ -
class_set_to_lowercase()[source]¶ Converts member variable self.class_set to lowercase.
Returns: None
-
static
underscores_valid(css_class='')[source]¶ Validate underscore usage in a single css_class. In general, underscores are only allowed to designate a decimal point between two numbers.
- Rules:
- Strip all whitespace in front and back.
- Underscores are only valid between digits
[0-9]_[0-9]allowed_35not allowed42_not allowedbold_pxnot allowed
- If found in the middle of a string it may begin and/or end with
- 1_2-5_75-1_2-5_75allowed
- If found in the middle of a string it may begin and/or end with
- String may start with
nto designate negative numbers. n5_25cmallowed.
- String may start with
- String may not start with
- -7_2not allowed.
- String may not start with
- String may not end with
- 5_4-not allowed
- String may not end with
Parameters: css_class (str) – Accepts a single CSS class extracted from HTML class attribute. Returns: boolean - True cases:
>>> ClassPropertyParser.underscores_valid('6_3') True >>> ClassPropertyParser.underscores_valid('2_456em') True >>> ClassPropertyParser.underscores_valid('1_2-5_75-1_2-5_75') True >>> ClassPropertyParser.underscores_valid('n5_25cm-n6_1cm') True
- False cases:
>>> ClassPropertyParser.underscores_valid('-7_2') False >>> ClassPropertyParser.underscores_valid('5_4-') False >>> ClassPropertyParser.underscores_valid('_b') False >>> ClassPropertyParser.underscores_valid('b_') False >>> ClassPropertyParser.underscores_valid('padding--_2') False >>> ClassPropertyParser.underscores_valid('2_rem') False >>> ClassPropertyParser.underscores_valid('m_px') False >>> ClassPropertyParser.underscores_valid('__') False
-
clean_class_set()[source]¶ Detect and Remove invalid css classes from class_set Class names must abide by: http://www.w3.org/TR/CSS2/syndata.html#characters
- For purposes of this project only a SUBSET of the CSS standard is permissible as follows:
- Encoded classes shall not be
Noneor''. - Encoded shall not contain whitespace (handled implicitly by subsequent rules).
- Encoded classes are only allowed to begin with
[a-z] - Encoded classes are only allowed to end with
[a-z0-9] - Encoded classes are allowed to contain
[_a-z0-9-]between the first and last characters. - Underscores are only valid between digits
[0-9]_[0-9]
- Encoded classes shall not be
- Reference:
- http://stackoverflow.com/questions/1323364/in-python-how-to-check-if-a-string-only-contains-certain-characters
Returns: None
-
static
get_property_name(css_class='')[source]¶ Extract a property name from a given class.
- Rules:
- Classes that use css property names or aliases must set a property value.
- Valid:
font-weight-700is valid because700is a validfont-weightvalue.fw-700is valid because itfw-is a valid alias forfont-weightboldis valid because theboldalias implies a property name offont-weight
- Invalid:
font-weightby itself is a property name, but does not include a property value.fw-by itself is a property alias, but does not include a property value.700does implyfont-weight, but is not a valid CSS selector as it may not begin with a number.
Parameters: css_class (str) – A class name containing a property name and value pair, or just a property value from which the property name may be inferred. Returns: (str) – Class returns the property_name OR if unrecognized returns ''.
-
static
strip_property_name(property_name='', css_class='')[source]¶ Strip property name from css_class if applicable and return the css_class.
Raises: ValueError – If either property_name or css_class are empty or only contain whitespace values.
Parameters: - property_name (str) – Presumed to match a key or value in the
property_alias_dict. - css_class (str) – This value may or may not be identical to the property_value.
Returns: (str) – Returns the encoded property value portion of the css_class.
Examples:
>>> ClassPropertyParser.strip_property_name('padding', 'padding-1-2-1-2') '1-2-1-2' >>> ClassPropertyParser.strip_property_name('font-weight', 'bold') 'bold' >>> ClassPropertyParser.strip_property_name('', 'padding-1-2-1-2') ValueError >>> ClassPropertyParser.strip_property_name('font-weight', ' ') ValueError
- property_name (str) – Presumed to match a key or value in the
-
static
alias_is_abbreviation(possible_alias='')[source]¶ Detects if the alias is an abbreviation e.g.
fw-stands forfont-weight-. Abbreviated aliases are found indatalibrary.property_alias_dict.Parameters: possible_alias (str) – A value that might be an alias. Returns: (bool) – True if possible_alias ends with a dash -.Examples:
>>> ClassPropertyParser.alias_is_abbreviation('fw-') True >>> ClassPropertyParser.alias_is_abbreviation('bold') False
-
get_property_abbreviations(property_name='')[source]¶ Returns a list of all property abbreviations appearing in
property_alias_dict.Raises: KeyError – If property_nameis not found inproperty_alias_dict.Parameters: property_name – Returns: (list) – A list of all property abbreviations appearing in property_alias_dict.Example:
Assume the following key, value pair occurs in
property_alias_dict:'background-color': {'bgc-', 'bg-c-', 'bg-color-', },>>> property_parser = ClassPropertyParser() >>> property_parser.get_property_abbreviations('background-color') ['bgc-', 'bg-c-', 'bg-color-'] >>> property_parser.get_property_abbreviations('invalid_property_name') KeyError
-
strip_property_abbreviation(property_name='', css_class='')[source]¶ Strip property abbreviation from css_class if applicable and return the result.
Raises: ValueError – If either property_name or css_class are empty or only contain whitespace values.
Parameters: - property_name (str) – Presumed to match a key or value in the
property_alias_dict - css_class (str) – Initially this value may or may not contain the property_name.
Returns: (str) – Returns the encoded property value portion of the css_class.
Examples:
>>> property_parser = ClassPropertyParser() >>> property_parser.strip_property_abbreviation('color', 'c-lime') 'lime' >>> property_parser.strip_property_abbreviation('', 'c-lime') ValueError >>> property_parser.strip_property_abbreviation('color', ' ') ValueError
- property_name (str) – Presumed to match a key or value in the
-
get_encoded_property_value(property_name='', css_class='')[source]¶ Strip property name or alias abbreviation prefix from front, pseudo item, and property priority designator. Returns the encoded_property_value.
The term encoded_property_value means a property value that represents a css property value, and may or may not contain dashes and underscores.
Raises: ValueError – If either property_name or css_class are empty or only contain whitespace values.
Parameters: - property_name (str) – Name of CSS property that matches a key in
property_alias_dict. - css_class (str) – An encoded css class selector that may contain property name, value, and priority designator.
Returns: (str) – Returns only the encoded_property_value after the name and priority designator are stripped.
Examples:
>>> property_parser = ClassPropertyParser() >>> property_parser.get_encoded_property_value('font-weight', 'fw-bold-i') # abbreviated property_name 'bold' >>> property_parser.get_encoded_property_value('padding', 'padding-1-10-10-5-i') # standard property_name '1-10-10-5' >>> property_parser.get_encoded_property_value('height', 'height-7_25rem-i') # contains underscores '7_25rem' >>> property_parser.get_encoded_property_value('font-style', 'font-style-oblique') # no priority designator 'oblique' >>> property_parser.get_encoded_property_value('', 'c-lime') ValueError >>> property_parser.get_encoded_property_value('color', ' ') ValueError
- property_name (str) – Name of CSS property that matches a key in
-
static
get_property_value(property_name='', encoded_property_value='')[source]¶ Accepts an encoded_property_value that’s been stripped of it’s property named and priority Uses CSSPropertyValueParser, and returns a valid css property value or ‘’.
Usage Note: Invalid CSS values can be returned by this method. CSS validation occurs at a later step.
Raises: ValueError – If either property_name or css_class are empty or only contain whitespace values.
Parameters: - property_name (str) – Name of CSS property that matches a key in
property_alias_dict. - encoded_property_value (str) – A property value that may or may not contain dashes and underscores.
Returns: (str) – An unvalidated / potential CSS property value.
Examples:
>>> property_parser = ClassPropertyParser(set(), False) # Turn OFF unit conversion. >>> property_parser.get_property_value('font-weight', 'bold') # Special case: alias == property value 'bold' >>> property_parser.get_property_value('padding', '1-10-10-5') # Multi-value encoding contains dashes. '1px 10px 10px 5px' >>> property_parser.get_property_value('width', '7_25rem') # Single value contains underscores. '7.25rem' >>> property_parser.get_property_value('margin', '1ap-10xp-3qp-1mp3') # Invalid CSS returned. '1a% 10x% 3q% 1mp3' >>> property_parser.get_property_value('', 'c-lime') ValueError >>> property_parser.get_property_value('color', ' ') ValueError
- property_name (str) – Name of CSS property that matches a key in
-
is_important(css_class='')[source]¶ Tests whether the css_class ends with the importance_designator.
Raises: ValueError – If the css_class is empty or only contain whitespace values. Parameters: css_class (str) – An encoded css class selector that may contain property name, value, and priority designator. Returns: (bool) – Returns True if the css_class ends with the importance_designator. Otherwise, returns False. Examples:
>>> property_parser = ClassPropertyParser() >>> property_parser.is_important('line-through-i') True >>> property_parser.is_important('line-through') False >>> property_parser.is_important('') ValueError >>> property_parser.is_important(' ') ValueError
-
strip_priority_designator(css_class='')[source]¶ Removes the priority designator, if necessary.
Raises: ValueError – If the css_class is empty or only contain whitespace values. Parameters: css_class (str) – A css_class that may or may not contain a priority designator. Returns: (str) – If necessary, strip priority designator from the end of css_class and return the string. If the importance_designator is not found, then it returns the unchanged css_class. >>> property_parser = ClassPropertyParser() >>> property_parser.strip_priority_designator('blink-i') 'blink' >>> property_parser.strip_priority_designator('blink') 'blink' >>> property_parser.strip_priority_designator('') ValueError >>> property_parser.strip_priority_designator(' ') ValueError
-
get_property_priority(css_class='')[source]¶ Returns the keyword
'important'or''. These are in the form thatcssutilsunderstands.Raises: ValueError – If the css_class is empty or only contain whitespace values. Parameters: css_class (str) – An encoded css class selector that may contain property name, value, and priority designator. Returns: (str) – Returns the keyword importantif the property priority is set to important. Otherwise, it returns ‘’.>>> property_parser = ClassPropertyParser() >>> property_parser.get_property_priority('text-align-center-i') 'important' >>> property_parser.get_property_priority('text-align-center') '' >>> property_parser.get_property_priority('') ValueError >>> property_parser.get_property_priority(' ') ValueError
-
is_valid_pseudo_format(pseudo_item='', css_class='')[source]¶ Returns True if the CSS class contains a properly formatted pseudo class or element, and False otherwise.
Rules
- The
css_classmay end with ‘-‘ + pseudo_item. Example prefix:color-green-i-hover - The
css_classmay end with ‘-‘ + pseudo_item + ‘-i’. Example prefix:color-green-hover-i - The
css_classmust be longer than the suffix or suffix + ‘-i’.
Parameters: - pseudo_item (str) – Either a pseudo class or pseudo element as defined here
- css_class (str) – This value may or may not be identical to the property_value.
Returns: bool – Returns True if the CSS class contains the pseudo item, and False otherwise.
- The
-
set_pseudo_class(css_class='')[source]¶ Check the pseudo class set for a match. Sets
pseudo_classif found. Otherwise, returns ‘’.Raises: ValueError – If either property_name or css_class are empty or only contain whitespace values. Parameters: css_class (str) – This value may or may not be identical to the property_value. Returns: None
-
set_pseudo_element(css_class='')[source]¶ Check the pseudo element set for a match. Sets the
pseudo_elementif found. Otherwise, returns ‘’.Raises: ValueError – If either property_name or css_class are empty or only contain whitespace values. Parameters: css_class (str) – This value may or may not be identical to the property_value. Returns: None
-
strip_pseudo_item(css_class='')[source]¶ Strip property name from css_class if applicable and return the css_class.
Note: This method must be called after
strip_property_name().Raises: ValueError – If either pseudo_item or css_class are empty or only contain whitespace values. Parameters: css_class (str) – _value. Returns: (str) – Returns the encoded property value portion of the css_class. Examples:
>>> ClassPropertyParser.strip_pseudo_item('hover-padding-1-2-1-2') '1-2-1-2' >>> ClassPropertyParser.strip_pseudo_item('before-bold') 'bold' >>> ClassPropertyParser.strip_pseudo_item('after-1-2-1-2') ValueError >>> ClassPropertyParser.strip_pseudo_item(' ') ValueError
-
cssvalueparser¶
-
class
cssvalueparser.CSSPropertyValueParser(property_name='')[source]¶ Accepts a
property_nameanduse_emunit conversion flag.Contains multiple parsers and methods that decodes the CSS property_value.
Parameters: property_name (str) – A CSS property name. Returns: None Attributes:
property_name (str) – A CSS property name. Not allowed to be
''or None.color_parser (ColorParser) – Parses encoded color values.
unit_parser (UnitParser) – Parses encoded unit values, and handles unit conversion.
Important note about methods:
These methods are intended to be called in the order they are defined inside the class.
-
is_built_in(value='')[source]¶ Checks if the encoded
valueidentically matches a value built-in to the CSS standard. Returns True ifvaluematches a CSS built-in valued and False if it does not.Examples include: ‘bold’, ‘italic’, ‘w-resize’, ‘arial’, etc.
Parameters: value (str) – Encoded CSS property value. Returns: (bool) - Returns
Trueifvaluematches a CSS built-in valued andFalseif it does not. - The values ‘bold’, ‘italic’, ‘w-resize’, ‘arial’ all return
True. - The values ‘-bold’, ‘fw-‘, ‘color-‘ all return
False. - Invalid
self.property_namealso returnsFalse(KeyError Case).
Examples:
>>> value_parser = CSSPropertyValueParser( >>> property_name='font-weight', use_em=True >>> ) >>> value_parser.is_built_in('bold') True >>> value_parser = CSSPropertyValueParser( >>> property_name='padding', use_em=True >>> ) >>> value_parser.is_built_in('7-4-7-4') False >>> value_parser = CSSPropertyValueParser( >>> property_name='InvalidCSSPropertyName', use_em=True >>> ) >>> value_parser.is_built_in('italic') False
- Returns
-
static
replace_dashes(value='')[source]¶ Remove leading and trailing dashes. Replace internal dashes with spaces. Return the modified value.
-becomes either''or' '.Parameters: value (str) – Encoded CSS property value. Returns: (str) – Return the value with dashes removed if necessary. >>> # Delete leading dash '-bold' --> 'bold' >>> value_parser = CSSPropertyValueParser( >>> property_name='font-weight', use_em=True >>> ) >>> value_parser.replace_dashes('-bold') 'bold' >>> # >>> # Delete trailing 'white-' --> 'white' >>> value_parser = CSSPropertyValueParser( >>> property_name='color', use_em=True >>> ) >>> value_parser.replace_dashes('white-') 'white' >>> # >>> # Replace internal '1-5-1-5' --> '1 5 1 5' >>> value_parser = CSSPropertyValueParser( >>> property_name='padding', use_em=True >>> ) >>> value_parser.replace_dashes('1-5-1-5') '1 5 1 5'
-
static
replace_underscore_with_decimal(value='')[source]¶ Replace underscore with decimal point. Underscores are used to encode a decimal point
'_'becomes'.'Parameters: value (str) – Encoded CSS property value. Returns: (str) – Return the value with decimal points added if necessary. Example
>>> value_parser = CSSPropertyValueParser( >>> property_name='padding', use_em=True >>> ) >>> value_parser.replace_underscore_with_decimal('1_32rem') '1.32rem'
-
static
replace_p_with_percent(value='')[source]¶ Replace
'p'suffix with'%'if found at the end of any substring containing digits.'p 'becomes'%'Mind the space
Parameters: value (str) – Encoded CSS property value. Returns: (str) – Return the value with percent signs added if necessary. Example:
>>> # Multi-value: '1p 10p 3p 1p' --> '1% 10% 3% 1%' >>> value_parser = CSSPropertyValueParser( >>> property_name='padding', use_em=True >>> ) >>> value_parser.replace_p_with_percent(value='1p 10p 3p 1p') '1% 10% 3% 1%' >>> # >>> # Single value ' 1p' --> ' 1%' >>> value_parser = CSSPropertyValueParser( >>> property_name='padding', use_em=True >>> ) >>> value_parser.replace_p_with_percent(value=' 1p') ' 1%'
-
static
replace_n_with_minus(value='')[source]¶ If a space plus the letter
' n'is immediately followed by a digit replace it with' -'. Ifnis the first letter of the string and followed by digits replace it with-. The letternis an encoding for a negative sign. Leaves othern'sunmodified.' n2'becomes' -2'Mind the space.'n5'becomes'-5'Parameters: value (str) – Encoded CSS property value. Returns: (str) – Return the value with minus signs added if necessary. Example:
>>> # Multi-value: 'n5cm n6cm' --> '-5cm -6cm' >>> value_parser = CSSPropertyValueParser( >>> property_name='padding', use_em=True >>> ) >>> value_parser.replace_n_with_minus('n5cm n6cm') '-5cm -6cm' >>> # >>> # 'n9in' --> '-9in' (note that the 'n' at the end is not touched) >>> value_parser.replace_n_with_minus('n9in') '-9in'
-
decode_property_value(value='')[source]¶ Decode the encoded property
valueinput e.g. ‘bold’, ‘1-5-1-5’, ‘1_32rem’, ‘1p-10p-3p-1p’, ‘n12px’, ‘n5_25cm-n6_1cm’. Returns parsed, but non-validated CSS property value.Parameters: value (str) – An encoded CSS property value. Returns: (str) – Returns the decoded, but non-validated CSS property value. Examples:
>>> value_parser = CSSPropertyValueParser( >>> property_name='padding', use_em=True >>> ) >>> value_parser.decode_property_value(value='1-5-1-5') '0.0625em 0.3125em 0.0625em 0.3125em' >>> value_parser.unit_parser.use_em = False >>> value_parser.decode_property_value(value='1-5-1-5') '1px 5px 1px 5px'
-
static
property_is_valid(name='', value='', priority='')[source]¶ Detects if a given property name, value, and priority combination is valid. Returns True if the combination is valid, and false otherwise.
Validation occurs after the property value is decoded.
Parameters: - name – CSS property name
- value – Decoded CSS property value
- priority – CSS priority designator
Returns: (bool) – Returns True if the CSS property name, value, and priority combination is valid, and false otherwise.
Examples:
>>> value_parser = CSSPropertyValueParser() >>> value_parser.property_is_valid( >>> name='padding', value='1px', priority='' >>> ) True >>> value_parser.property_is_valid( >>> name='padding', value='invalid', priority='' >>> ) False
-
colorparser¶
Features:
Validates whether the property_name allows a color property to be set.
Decodes the following color formats: hexidecimal, rgb, rgba, hsl, hsla.
- Exception: English color names are handled separately
- Either in the property_alias_dict under the key
color,Or they are passed through to cssutils because they are valid CSS and do not require further processing.
Note: The shorthand properties background, border, and outline are supported (as of November 2015).
Assumption: It is assumed that all dashes are removed from the input value prior to using this parser.
Example:
>>> color_parser = ColorParser('border-color', 'h0df48a')
>>> color_parser.property_name_allows_color()
True
-
class
colorparser.ColorParser(property_name='', value='')[source]¶ Extracts plain text, hexidecimal, rgb, rgba, hsl, and hsla color codes from encoded class selectors.
-
property_name_allows_color()[source]¶ Detects if the
property_nameallows a color property value.Reference: http://www.w3.org/TR/CSS21/propidx.html
Returns: (bool) – Returns True if the property_nameis allow to contain colors. Otherwise, it returns False.Examples:
>>> color_parser = ColorParser('border-color', 'h0df48a') >>> color_parser.property_name_allows_color() True >>> color_parser.property_name = 'invalid' >>> color_parser.property_name_allows_color() False
-
find_h_index(value='')[source]¶ Detects if the
valueis a valid hexidecimal encoding.Note: Supports shorthand properties.
Parameters: value (str) – Expects a valueof the form: h0ff48f or hfaf i.e. ‘h’ + a 3 or 6 digit hexidecimal value 0-f.Returns: (int or NoneType) – Returns the index of the hto be replaced in thevalueif it matches the hex regex. Otherwise it returns None.Examples:
>>> color_parser = ColorParser() >>> color_parser.find_h_index(value='h0df48a') 0 >>> color_parser.find_h_index(value='h1invalid') None
-
replace_h_with_hash(value='')[source]¶ Replaces the prepended
hprefix with a hash sign#or octothorpe if you prefer long words.Includes an internal check to ensure that the value is a valid hexidecimal encoding.Only replaces thehthat matches the regex as otherhcharacters may be present.Shorthand properties are supported:border case:1px solid hdddbecomes1px solid #dddParameters: value – Encoded hexidecimal value of the form hf1forhc2c2c2.Returns: (str) – Returns actually #0ff48f and #faf in the valid case. Returns the input valueunchanged for the invalid case.>>> color_parser = ColorParser() >>> # Valid Cases >>> color_parser.replace_h_with_hash('h0ff24f') #0ff24f >>> color_parser.replace_h_with_hash('hf4f') #f4f >>> # Valid multiple 'h' case. >>> color_parser.replace_h_with_hash('13px dashed hd0d') 13px dashed #d0d >>> # Invalid Cases >>> color_parser.replace_h_with_hash('bold') bold >>> color_parser.replace_h_with_hash('he2z') he2z
-
add_color_parenthetical(value='')[source]¶ Convert parenthetical color values: rbg, rbga, hsl, hsla to valid css format
Assumes that color conversion happens after dashes, decimal point, negative signs, and percentage signs are converted.
Note: Currently not compatible with shorthand properties.
Parameters: value (str) – Space delimited rbg, rbga, hsl, hsla values. Returns: (str) – Returns the valid css color parenthetical. Returns the input valueunchanged for the non-matching case.Examples:
>>> color_parser = ColorParser('color', '') >>> color_parser.add_color_parenthetical('rgb 0 255 0') rgb(0, 255, 0) >>> color_parser.add_color_parenthetical('rgba 255 0 0 0.5') rgba(255, 0, 0, 0.5) >>> color_parser.add_color_parenthetical('hsl 120 60% 70%') hsl(120, 60%, 70%) >>> color_parser.add_color_parenthetical('hsla 120 60% 70% 0.3') hsla(120, 60%, 70%, 0.3) >>> # Pass-through case as no conversion is possible. >>> color_parser.add_color_parenthetical('hsla') hsla
-
fontparser¶
-
class
fontparser.FontParser(font_value='')[source]¶ Features:
Parses unquoted font families.
- Unquoted Font-Family References:
- Holds a basic
font_families_dict(could be extended as desired): - Keys:
font-familycategory namesValues:font-familymember names
- Holds a basic
Can generate web safe fallback fonts.
Assumes that the property_name is
font-family. It does not handle the shorthand property_namefontExamples:
>>> font_parser = FontParser('papyrus') >>> font_parser.generate_fallback_fonts() 'papyrus, fantasy'
-
generate_fallback_fonts()[source]¶ Generates web safe fallback fonts
Reference: http://www.w3schools.com/cssref/css_websafe_fonts.asp
Returns: (str) – Returns a web safe fallback font string. Examples:
>>> font_parser = FontParser('arial') >>> font_parser.generate_fallback_fonts() 'arial, sans-serif' >>> font_parser.font_value = 'monospace' 'monospace' >>> font_parser.font_value = 'invalid' ''
unitparser¶
-
class
unitparser.UnitParser(property_name='')[source]¶ Used in these cases:
- No units are provided and default units need to be added to make it valid css.
- The user wants their pixel (px) based units to be converted to em or root em (rem) so that their page scales / zooms properly.
Assumption: The value provided already has negative signs and decimal points. There are no dashes or underscores present in the value e.g. -1.25 can be processed, but n1_25 cannot be processed.
Contains a ``default_property_units_dict`` which maps property names to their default units.
Note: Shorthand properties are not supported.
Why do I want to use em (named after the sound for the letter ‘M’) or root em (rem)?:
Because your webpage will scale with browser and device size.- What does (em) actually stand for?:
Source: W3C – http://www.w3.org/WAI/GL/css2em.htm
The foremost tool for writing scalable style sheets is the “em” unit, and it therefore goes on top of the list of guidelines that we will compile throughout this chapter: use ems to make scalable style sheets. Named after the letter “M”, the em unit has a long-standing tradition in typography where it has been used to measure horizontal widths. … In CSS, the em unit is a general unit for measuring lengths, for example page margins and padding around elements. You can use it both horizontally and vertically, and this shocks traditional typographers who always have used em exclusively for horizontal measurements. By extending the em unit to also work vertically, it has become a very powerful unit - so powerful that you seldom have to use other length units.
Source: Wikipedia – https://en.wikipedia.org/wiki/Em_%28typography%29
An em is a unit in the field of typography, equal to the currently specified point size. For example, one em in a 16-point typeface is 16 points. Therefore, this unit is the same for all typefaces at a given point size.
-
default_units()[source]¶ Returns the default units “if any” for the assigned
self.property_name.Returns: (str) – Returns default units for the assigned self.property_nameif they exist. Otherwise, return an empty string''.
-
add_units(property_value='')[source]¶ If the property_name requires units, then apply the default units defined in default_property_units_dict.
Rules:
- If use_em is False apply the default units for the property name by looking it up in default_property_units_dict.
- Unit that have default units of
pxare converted toemif use_em is True. - If
property_valuehas multiple property values, then split it apart. - If the value already has units, then pass it through unchanged.
- The value provided shall possess negative signs and decimal points.
- Mixed units are allowed, but not recommended.
- Values shall only contain [] e.g. -1.25 can be processed, but n1_25 cannot be processed.
Parameters: property_value (str) – A string containing one or more space delimited alphanumeric characters. Returns: (str) – Returns the property value with the default or converted units added. >>> # Convert 'px' to 'em' >>> unit_parser = UnitParser(property_name='padding', use_em=True) >>> unit_parser.add_units('1 2 1 2') 0.0625em 0.125em 0.0625em 0.125em >>> # Use default units >>> unit_parser.use_em = False >>> unit_parser.add_units('1 2 1 2') 1px 2px 1px 2px >>> # Values already have units or are not parsable pass through >>> # True produces the same output. >>> unit_parser.use_em = False >>> unit_parser.add_units('55zp') 55zp >>> unit_parser.add_units('17rem') 17rem >>> # Unitless ``property_name`` >>> # causes ``property_value`` to pass through. >>> unit_parser.property_name = 'font-weight' >>> unit_parser.add_units('200') 200 >>> # Mixed units cases - Not a Recommended Practice, >>> # but represent valid CSS. Be careful. >>> unit_parser.use_em = False >>> unit_parser.add_units('5em 6 5em 6') 5em 6px 5em 6px >>> unit_parser.use_em = True >>> unit_parser.add_units('1em 100 4cm 9rem') 1em 6.25em 4cm 9rem
breakpointparser¶
-
class
breakpointparser.BreakpointParser(css_class='', css_property=cssutils.css.Property(name='', value='', priority=''))[source]¶ Enables powerful responsive @media query generation via screen size suffixes.
Standard screen breakpoints xxsmall through xgiant:
'name--breakpoint_values--limit_key'– General Format'inline-small-only'– Only displays the HTML element inline for screen sizes less than or equal to the upper limit_key forsmallscreen sizes.'green-medium-up'– Setcolorto green for screen sizes greater than or equal to the lower limit_key formediumsize screens.
Custom user defined breakpoint limit_key.
'block-480px-down'– Only displays the HTML element as a block for screen sizes less than or equal to 480px.'bold-624-up'– Set thefont-weighttoboldfor screen sizes greater than or equal to 624px.- Note: If unit conversion is enabled i.e.
use_emisTrue, then 624px would be converted to 39em.
- Note: If unit conversion is enabled i.e.
Important Note about cssutils and media queries
Currently,
cssutilsdoes not support parsing media queries. Therefore, media queries need to be built, minified, and appended separately.Parameters: - css_class (str) – Potentially encoded css class that may or may not be parsable. May not be empty or None.
- css_property (Property) – Valid CSS Property as defined by
cssutils.css.Property.
Returns: None
Examples:
>>> from cssutils.css import Property >>> from xml.dom import SyntaxErr >>> # value='inherit' since we do not know if the class is valid yet. >>> name = 'display' >>> value = 'inherit' >>> priority = '' >>> inherit_property = Property(name=name, value=value, priority=priority) >>> breakpoint_parser = BreakpointParser( css_class='large-up', css_property=inherit_property ) >>> print(breakpoint_parser.breakpoint_key) large >>> print(breakpoint_parser.limit_key) -up >>> # Validate encoded syntax. >>> is_breakpoint = breakpoint_parser.is_breakpoint >>> if is_breakpoint: >>> clean_css_class = breakpoint_parser.strip_breakpoint_limit() >>> # Change value to 'none' as display media queries use reverse logic. >>> value = 'none' >>> # Build CSS Property >>> try: >>> css_property = Property(name=name, value=value, priority=priority) >>> if css_property.valid: >>> if is_breakpoint and breakpoint_parser: >>> breakpoint_parser.css_property = css_property >>> media_query = breakpoint_parser.build_media_query() >>> else: >>> print(' (cssutils invalid property value: ' + value + ')') >>> except SyntaxErr: >>> print('(cssutils SyntaxErr invalid property value: ' + value + ')') >>> print(media_query) @media only screen and (max-width: 45.0625em) { .large-up { display: none; } }
-
set_breakpoint_key()[source]¶ If
self.css_classcontains one of the keys inself.breakpoint_dict, then setself.breakpoint_valuesto a breakpoint_values tuple for the matching key. Otherwise, setis_breakpoint = False.Rules:
Before a comparison is made each key is wrapped in dashes i.e.
-key-since the key must appear in the middle of aself.css_class.- This also prevents false positives since searching for
smallcould matchxxsmall,xsmall, andsmall.
- This also prevents false positives since searching for
The length of
self.css_classmust be greater than the length of the key + 2. This prevents acss_classlike'-xsmall-'or'-xxlarge-up'from being accepted as valid by themselves.The
keyminus the preceding dash is allowed if it the key is the first word in the string. This allows the shorthand cases, for example:small-only,medium-up,giant-down. These cases imply that the CSS property name isdisplay.These rules do not catch all cases, and prior validation of the css_class is assumed.
- Set
is_breakpoint = Falseif none of the keys inself.breakpoint_dictare found in self.css_class.
- Set
Returns: None Examples:
>>> from cssutils.css import Property >>> # value='inherit' since we do not know if the class is valid yet. >>> name = 'display' >>> value = 'inherit' >>> priority = '' >>> inherit_property = Property(name=name, value=value, priority=priority) >>> breakpoint_parser = BreakpointParser( css_class='padding-1em-giant-down', css_property=inherit_property ) >>> # BreakpointParser() sets breakpoint_key. >>> print(breakpoint_parser.breakpoint_key) giant
-
set_limit_key()[source]¶ If one of the values in
self.limit_setis contained inself.css_class, then Setself.limit_keyto the value of the string found. Otherwise, setis_breakpoint = False.Rules:
- The
limit_keyis expected to begin with a dash-. - The
limit_keymay appear in the middle ofself.css_classe.g.'padding-10-small-up-s-i'. - The
limit_keymay appear at the end ofself.css_classe.g.'margin-20-giant-down'. - The length of
self.css_classmust be greater than the length of the limit_key + 2. This prevents acss_classlike'-up-'or'-only-'from being accepted as valid by themselves. - These rules do not catch all cases, and prior validation of the css_class is assumed.
- Set
is_breakpoint = Falseif none of the members ofself.limit_setare found in self.css_class.
- Set
Returns: None Examples:
>>> from cssutils.css import Property >>> # value='inherit' since we do not know if the class is valid yet. >>> name = 'display' >>> value = 'inherit' >>> priority = '' >>> inherit_property = Property(name=name, value=value, priority=priority) >>> breakpoint_parser = BreakpointParser( css_class='padding-1em-giant-down', css_property=inherit_property ) >>> # BreakpointParser() sets limit_key. >>> print(breakpoint_parser.limit_key) -down
- The
-
set_custom_breakpoint_key()[source]¶ Assuming that a limit key is found, but a standard breakpoint key is not found in the
css_class; determine if a properly formatted custom breakpoint is defined.Custom Breakpoint Rules:
- Must begin with an integer.
- May contain underscores
_to represent decimal points. - May end with any allowed unit (em|ex|px|in|cm|mm|pt|pc|q|ch|rem|vw|vh|vmin|vmax).
- Must not be negative.
- Unit conversion is based on the related setting in blowdrycss_settings.py.
Pattern Explained
pattern = r'[a-zA-Z].*\-([0-9]*_?[0-9]*?(em|ex|px|in|cm|mm|pt|pc|q|ch|rem|vw|vh|vmin|vmax)?)\-(up|down)\-?'[a-zA-Z]– css_class must begin with a letter..*– First letter may be followed by any number of characters.\-– A dash will appear before the substring pattern.([0-9]*_?[0-9]*?(em|ex|px|in|cm|mm|pt|pc|q|ch|rem|vw|vh|vmin|vmax)?)– Substring pattern begins with A number that could contain an_to encode an optional decimal point followed by more numbers. Followed by an optional unit of measure.\-(up|down)– Substring pattern must end with either-upor-down.\-?– Substring pattern may or may not be followed by a dash since it could be the end of a string or
Returns: None Examples:
padding-25-820-up, display-480-down, margin-5-2-5-2-1000-up, display-960-up-i, display-3_2rem-down
>>> from cssutils.css import Property >>> # value='inherit' since we do not know if the class is valid yet. >>> name = 'display' >>> value = 'inherit' >>> priority = '' >>> inherit_property = Property(name=name, value=value, priority=priority) >>> breakpoint_parser = BreakpointParser( css_class='padding-25-820-up', css_property=inherit_property ) >>> # BreakpointParser() sets limit_key. >>> print(breakpoint_parser.is_breakpoint) True >>> print(breakpoint_parser.limit_key) '-up' >>> print(breakpoint_parser.breakpoint_dict[breakpoint_parser.breakpoint_key][breakpoint_parser.limit_key]) '51.25em'
-
strip_breakpoint_limit()[source]¶ Removes breakpoint and limit keywords from
css_class.Rules:
- Return
''if breakpoint limit key pair ==css_classi.e. implieddisplayproperty name. 'xlarge-only'becomes''.
- Return
- Return
property_name + property_value - breakpoint_key - limit_key. 'bold-large-up'becomes'bold'.'padding-12-small-down'becomes'padding-12'.'margin-5-2-5-2-1000-up'becomes'margin-5-2-5-2'(custom breakpoint case).
- Return
Returns: (str) – Returns a modified version css_classwith breakpoint and limit key syntax removed.Examples:
>>> from cssutils.css import Property >>> # value='inherit' since we do not know if the class is valid yet. >>> name = 'display' >>> value = 'inherit' >>> priority = '' >>> inherit_property = Property(name=name, value=value, priority=priority) >>> breakpoint_parser = BreakpointParser( css_class='xlarge-only', css_property=inherit_property ) >>> breakpoint_parser.strip_breakpoint_limit() '' >>> inherit_property = Property(name='font-weight', value=value, priority=priority) >>> breakpoint_parser.css_class='bold-large-up' >>> breakpoint_parser.strip_breakpoint_limit() 'bold'
-
is_display()[source]¶ Tests if
css_classcontains character patterns that match the special case when the property name isdisplay.Returns: (bool) – Returns true if one of the cases is true. Otherwise it returnsfalse.Examples:
>>> from cssutils.css import Property >>> # value='inherit' since we do not know if the class is valid yet. >>> name = 'display' >>> value = 'inherit' >>> priority = '' >>> inherit_property = Property(name=name, value=value, priority=priority) >>> breakpoint_parser = BreakpointParser( css_class='xlarge-only', css_property=inherit_property ) >>> breakpoint_parser.strip_breakpoint_limit() '' >>> inherit_property = Property(name='font-weight', value=value, priority=priority) >>> breakpoint_parser.css_class='bold-large-up' >>> breakpoint_parser.strip_breakpoint_limit() 'bold'
-
css_for_only()[source]¶ Generates css
Handle Cases:
- Special Usage with
display - The css_class
display-large-onlyis a special case. The CSS property namedisplaywithout a value is used to show/hide content. Fordisplayreverse logic is used. The reason for this special handling ofdisplayis that we do not know what the currentdisplaysetting is if any. This implies that the only safe way to handle it is by settingdisplaytononefor everything outside of the desired breakpoint limit. - Shorthand cases, for example:
small-only,medium-up,giant-downare allowed. These cases imply that the CSS property name isdisplay. This is handled in theif-statementviapair[1:] == self.css_class. - Note:
display + value + pairis handled under the General Usage case. For example,display-inline-large-onlycontains a value fordisplayand only used to alter the way an element is displayed.
- The css_class
- Special Usage with
General Usage
- The css_class
padding-100-large-downappliespadding: 100pxfor screen sizes less than the lower limit oflarge.
- The css_class
Note: Unit conversions for pixel-based
self.valueis required before the BreakpointParser is instantiated.Media Query Examples
Special Case: Generated CSS for
display-large-onlyorlarge-only:@media only screen and (max-width: 45.0625em) { .display-large-only { display: none; } } @media only screen and (min-width: 64.0em) { .display-large-only { display: none; } }
General Usage Case: Generated CSS for
padding-100-large-only:@media only screen and (min-width: 45.0625em) and (max-width: 64.0em) { .padding-100-large-only { padding: 100px; } }
Priority !important Case: Generated CSS for
large-only-i:@media only screen and (max-width: 45.0625em) { .display-large-only { display: none !important; } } @media only screen and (min-width: 64.0em) { .display-large-only { display: none !important; } }
Returns: None
-
css_for_down()[source]¶ Only display the element, or apply a property rule
belowa given screen breakpoint. Returns the generated css.Handle Cases:
- Special Usage with
display - The css_class
display-medium-downis a special case. The CSS property namedisplaywithout a value is used to show/hide content. Fordisplayreverse logic is used. The reason for this special handling ofdisplayis that we do not know what the currentdisplaysetting is if any. This implies that the only safe way to handle it is by settingdisplaytononefor everything outside of the desired breakpoint limit. - Shorthand cases, for example:
small-only,medium-up,giant-downare allowed. These cases imply that the CSS property name isdisplay. This is handled in theif-statementviapair[1:] == self.css_class. - Note:
display + value + breakpoint + limitis handled under the General Usage case. For example,display-inline-medium-downcontains a value fordisplayand only used to alter the way an element is displayed.
- The css_class
- Special Usage with
General Usage
- The css_class
padding-100-medium-downappliespadding: 100pxfor screen sizes less than the lower limit ofmedium.
- The css_class
Note: Unit conversions for pixel-based
self.valueis required before the BreakpointParser is instantiated.Media Query Examples
Special Case: Generated CSS for
display-medium-down:@media only screen and (min-width: 45.0em) { .display-medium-down { display: none; } }
General Usage Case: Generated CSS for
padding-100-medium-down:@media only screen and (max-width: 45.0em) { .padding-100-medium-down { padding: 100px; } }
Returns: None
-
css_for_up()[source]¶ Only display the element, or apply a property rule
abovea given screen breakpoint. Returns the generated css.Handle Cases:
- Special Usage with
display - The css_class
display-small-upis a special case. The CSS property namedisplaywithout a value is used to show/hide content. Fordisplayreverse logic is used. The reason for this special handling ofdisplayis that we do not know what the currentdisplaysetting is if any. This implies that the only safe way to handle it is by settingdisplaytononefor everything outside of the desired breakpoint limit. - Shorthand cases, for example:
small-only,medium-up,giant-downare allowed. These cases imply that the CSS property name isdisplay. This is handled in theif-statementviapair[1:] == self.css_class. - Note:
display + value + breakpoint + limitis handled under the General Usage case. For example,display-inline-small-upcontains a value fordisplayand only used to alter the way an element is displayed.
- The css_class
- Special Usage with
General Usage
- The css_class
padding-100-small-upappliespadding: 100pxfor screen sizes less than the lower limit ofsmall.
- The css_class
Note: Unit conversions for pixel-based
self.valueis required before the BreakpointParser is instantiated.Media Query Examples
Special Case: Generated CSS for
display-small-up:@media only screen and (max-width: 15.0625em) { .display-small-up { display: none; } }
General Usage Case: Generated CSS for
padding-100-small-up:@media only screen and (min-width: 15.0625em) { .padding-100-small-up { padding: 100px; } }
Returns: None
-
build_media_query()[source]¶ Pick the css generation method based on the
limit_keyfound incss_class.Returns: Return CSS media queries as CSS Text. Examples:
>>> from cssutils.css import Property >>> # value='inherit' since we do not know if the class is valid yet. >>> name = 'display' >>> value = 'inherit' >>> priority = '' >>> inherit_property = Property(name=name, value=value, priority=priority) >>> breakpoint_parser = BreakpointParser( css_class='padding-1em-giant-down', css_property=inherit_property ) >>> css_property = Property(name='padding', value='1em', priority='') >>> if breakpoint_parser.is_breakpoint and css_property.valid: >>> breakpoint_parser.css_property = css_property >>> media_query = breakpoint_parser.build_media_query() >>> print(media_query) @media only screen and (max-width: 160.0em) { .padding-1em-giant-down { padding: 1em; } }
scalingparser¶
-
class
scalingparser.ScalingParser(css_class='', css_property=cssutils.css.Property(name='', value='', priority=''))[source]¶ 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>-sSpecific case:
font-size-24-sPriority
!importantcase:font-size-24-s-i- (
'-i'is always last)
- (
Responsive Scaling Ratios:
Assuming
font-size-24-sis 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,
cssutilsdoes not support parsing media queries. Therefore, media queries need to be built, minified, and appended separately.Parameters: - css_class (str) – Potentially encoded css class that may or may not be parsable. May not be empty or None.
- css_property (Property()) – Valid CSS Property as defined by
cssutils.css.Property.
Returns: None
Examples:
>>> scaling_parser = ScalingParser(css_class='font-weight-24-s')
-
strip_scaling_flag()[source]¶ Remove the
scaling_flagfromcss_classif possible and return the clean css class. Otherwise, return thecss_classunchanged.Rules
- Remove
-sif found at end of a string - Remove
-sif-s-iis found at the end of the string.
Returns: (str) – If the css_classis scaling remove thescaling_flagand return the clean css class. Otherwise, return thecss_classunchanged.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
- Remove
-
build_media_query()[source]¶ Returns CSS media queries that scales pixel / em values in response to screen size changes.
Generated CSS for ``font-size-24-s`` minus the inline comments & line breaks:
// Default size above medium .font-size-24-s { font-size: 24px; } // medium screen font size reduction @media only screen and (max-width: 64.0em) { .font-size-24-s { font-size: 23.0px; } } // medium screen font size reduction @media only screen and (max-width: 45.0em) { .font-size-24-s { font-size: 21.3px; } } // small screen font size reduction @media only screen and (max-width: 30.0em) { .font-size-24-s { font-size: 19.2px; } }
Priority !important – Generated CSS for ``font-size-24-s-i`` minus the inline comments & line breaks:
// Default size above the maximum 'medium' width breakpoint. .font-size-24-s-i { font-size: 24px !important; } // medium screen font size reduction @media only screen and (max-width: 64.0em) { .font-size-24-s-i { font-size: 23.0px !important; } } // Apply 'medium' screen font size reduction. @media only screen and (max-width: 45.0em) { .font-size-24-s-i { font-size: 21.3px !important; } } // Apply 'small' screen font size reduction. @media only screen and (max-width: 30.0em) { .font-size-24-s-i { font-size: 19.2px !important; } }Returns: (str) – Returns CSS media queries that scales pixel / em values in response to screen size changes.
timing¶
Simple code performance timer that allows for the execution time to be recorded
Credit:
- This is a modified version of Paul’s and Nicojo’s answers on stackoverflow.
- Reference: http://stackoverflow.com/questions/1557571/how-to-get-time-of-a-python-program-execution
Usage Case:
>>> # At the beginning of the chunk of code to be timed.
>>> from blowdrycss.timing import Timer
>>> timer = Timer()
>>> timer.report()
Completed @ 2015-12-14 16:56:08.665080
=======================================
It took: 0.17296 seconds
=======================================
-
class
timing.Timer[source]¶ A performance Timer that reports the amount of time it took to run a block of code.
Parameters:start (time) – Time that the program started.end (time) – Time that the program ended.Returns: None Example
>>> from blowdrycss.timing import Timer >>> timer = Timer() >>> timer.report() Completed 2015-12-14 16:56:08.665080 ===================================== It took: 0.17296 seconds ===================================== >>> timer.reset() # Resets start time to now. >>> timer.report() Completed 2015-12-14 17:05:12.164030 ===================================== It took: 1.45249 seconds =====================================
-
static
seconds_to_string(seconds_elapsed=0.0)[source]¶ Converts the amount of time elapsed to seconds_elapsed, and returns it as a string.
Parameters: seconds_elapsed (float) – A time() value in units of seconds_elapsed. Returns: (str) – Returns a string version of the total time elapsed in seconds_elapsed.
-
elapsed¶ Calculates the amount of time elapsed (delta T) by subtracting start
time()from endtime().Math: elapsed = delta T = end - start
Returns: (str) – Returns delta T in units of seconds as a string.
-
static
-
class
timing.LimitTimer[source]¶ Timer governs when to perform a full and comprehensive run of blowdry.parse().
Note
This is independent of file modification watchdog triggers which only scan the file(s) that changed since the last run.
** Why is a LimitTimer needed? **
Understanding the Truth Table
- The project only contains two files: File 1 and File 2.
- Each file either contains the CSS class selector ‘blue’ or not i.e. set().
- File 2 is modified. Either the class
blueis added or removed i.e. set(). - X means don’t care whether the file contains blue or set().
- Case #3 is the reason why the LimitTimer is required. The css class selector
bluewas only defined in File 2. Then blue was removed from File 2. Since blue existed in the combined class_set before File 2 was modified, it will remain in the combined class_set after the union with set(). This is undesirable in Case #3 sinceblueis not used anymore in either of the two files. The LimitTimer runs periodically to clear these unused selectors.
Case # File 1 class_set File 2 class_set Combined class_set File 2 modified Combined class_set 1 blue blue blue set() blue 2 blue set() blue X blue 3 set() blue blue set() blue 4 set() set() set() blue blue 5 set() set() set() set() set() ** Another reason why the LimitTimer is needed. **
On windows and mac watchdog on_modify event gets triggered twice on save. In order to prevent a duplicate run for the same change or set of changes this class is implemented. It can also depend on the IDE being used since some IDEs auto-save.
Members:time_limit (str) – Number of seconds that must pass before the limit is exceeded. Default is settings.time_limit.start_time (str) – Time that the timer started.Returns: None Example
>>> from blowdrycss.timing import LimitTimer >>> limit_timer = LimitTimer() >>> if limit_timer.limit_exceeded: >>> print("30 minutes elapses.") >>> limit_timer.reset()
-
time_limit¶ Getter returns
_time_limit.Returns: (int) – Returns _time_limit.
-
limit_exceeded¶ Compares the current time to the start time, and returns True if
self.time_limitis exceeded and False otherwise.Returns: (bool) – Returns True if self.time_limitis exceeded and False otherwise.
utilities¶
-
utilities.contains_a_digit(string='')[source]¶ Check if string contains a digit
[0-9].Parameters: string (str) – The string to test. Returns: (bool) – Returns True if string contains at least 1 digit. Otherwise, returns False. Examples:
>>> contains_a_digit('abc1') True >>> contains_a_digit('876') True >>> contains_a_digit('cat') False >>> contains_a_digit('') False >>> contains_a_digit(' ') False
-
utilities.deny_empty_or_whitespace(string='', variable_name='')[source]¶ Prevent
stringorvariable_namefrom being empty or only containing whitespace.Raises: ValueError – Raises a ValueError if the string or the variable_name is empty or only contains whitespace. The ValueError contains the name of the calling function and the variable name used in the calling function.
Parameters: - string (str) – The string to test.
- variable_name (str) – The name of the variable used in the calling function.
Returns: None
-
utilities.get_file_path(file_directory='', file_name='blowdry', extension='')[source]¶ Joins the
file_directory,file_name, andextension. Returns the joined file path.Rules:
- Do not allow
''empty input forfile_directory,file_name, orextension. - Transform extension to lowercase.
- Extensions must match this regex r”(^[.][.0-9a-z]*[0-9a-z]$)”.
Findall regex Decoded:
r"(^[.][.0-9a-z]*[0-9a-z]$)"^[.]–extensionmust begin with a.dot.[.0-9a-z]*–extensionmay contain any of the character inside the brackets.[0-9a-z]$–extensionmay only end with the characters inside the brackets.
Parameters: - file_directory (str) – Directory in which to place the file.
- file_name (str) – Name of the file (excluding extension)
- extension (str) – A file extension including the
., for example,.css,.min.css,.md,.html, and.rst
Returns: (str) – Returns the joined file path.
- Do not allow
-
utilities.validate_output_file_name_setting()[source]¶ Validates output_file_name from blowdrycss_settings.py. First thing that runs.
Raises: SyntaxError – If settings.output_file_name or settings.output_extension contain ‘’, ‘/’, whitespace or ends with a dot. Returns: None
-
utilities.validate_output_extension_setting()[source]¶ Validates output_extension from blowdrycss_settings.py. First thing that runs.
Raises: SyntaxError – If settings.output_extension does not begin with a dot or contains ‘’, ‘/’, whitespace or ends with a dot. Returns: None
-
utilities.change_settings_for_testing()[source]¶ Change settings directories for testing.
Warning
This method should only be used by the unit_test framework.
Returns: None
-
utilities.unittest_file_path(folder='', filename='')[source]¶ Determines the path of assigned to the folder and file based on the directory in which the unittest command is executed.
Parameters: - folder (str) – Name of the folder where the file is located.
- filename (str) – Name of the file including extension e.g. test_aspx.aspx
Returns: (str) – Return the path of the file to test.
-
utilities.print_minification_stats(file_name='', extension='')[source]¶ Print before and after minification file size reduction statistics.
Parameters: - file_name (str) – The file name excluding extension e.g. ‘blowdry’ or ‘site’.
- extension (str) – Appended to the file_name and begins with a dot e.g. ‘.css’, ‘.scss’, etc.
Returns: None
-
utilities.make_directory(directory='')[source]¶ Try to make a directory or verify its’ existence. Raises an error if neither of these are possible.
Raises: OSError – Raises an OSError if the directory cannot be made or found. Parameters: directory (str) – A directory path in the file system. Returns: None
