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
– Allowsblowdrycss
to 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.base
as the unit conversion factor.Rules:
pixels
shall only contain [0-9.-].- Inputs that contain any other value are simply passed through unchanged.
- Default
base
is 16 meaning16px = 1rem
Note: Does not check the
property_name
oruse_em
values. 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
em
appended 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
key
is the official CSS property name. - The
value
is 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.
bold
can 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
key
is the official CSS property name. - The
value
is 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
normal
is a valid property value. However,normal
is not unique tofont-weight
. To verify that go here and search fornormal
. Also,100 - 900
are 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-right
is'br-'
. Howeverbackground-repeat
has an identical alias of'br-'
. Therefore'br-'
is added toclashing_alias_dict
and is not allowed to be used as an alias.Dictionary Contains:
- The
key
is the official CSS property name. - The
value
is aset()
of custom string aliases.
property_alias_dict (dict)Auto-generated dictionary of property aliases.
Dictionary Contains:
- The
key
is the official CSS property name. - The
value
is aset()
of custom string aliases.
alphabetical_clashing_dict (dict)Alphabetized ordered dictionary of clashing aliases.
Ordered Dictionary Contains:
- The
key
is the official CSS property name. - The
value
is aset()
of clashing string aliases.
alphabetical_property_dict (dict)Alphabetized ordered dictionary of property aliases.
Ordered Dictionary Contains:
- The
key
is the official CSS property name. - The
value
is 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_dict
key that starts withmargin-top
notmargin
.Ordered Dictionary Contains:
- The
key
is the official CSS property name. - The
value
is 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_names
to 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_dict
withproperty_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_dict
for duplicate / clashing aliases and adds them toclashing_alias_dict
.
-
remove_clashing_aliases
()[source]¶ Removes clashing aliases stored in
clashing_alias_dict
fromproperty_alias_dict
and 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_text
key_title | value_title
--- | ---
key[0] | value
key[1] | value
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 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_types
specified within a particularproject_directory
. All folders within theproject_directory
are 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.*.html
is 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_types
inproject_directory
. For eachfile_type
find 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 + extension
orfile_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-9
ora-z
.Notes:file_name
does not include extension becausewrite_file()
normalizes and appends the extension.extension
is 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 text
input 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_path
was modified more recently than blowdry.css. Ifself.file_path
is 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_path
under consideration.
-
cssbuilder
¶
-
class
cssbuilder.
CSSBuilder
(property_parser=<blowdrycss.classpropertyparser.ClassPropertyParser object>)[source]¶ Builds CSS text with the
cssutils.css
module.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
blowdrycss
encoding.
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_rules
set.
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_class
tocss_class
. - If a pseudo element is found append
'::' + pseudo_element
tocss_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-s
orfont-size-28-medium-only-s
are 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_queries
together 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_35
not allowed42_
not allowedbold_px
not allowed
- If found in the middle of a string it may begin and/or end with
-
1_2-5_75-1_2-5_75
allowed
- If found in the middle of a string it may begin and/or end with
- String may start with
n
to designate negative numbers. n5_25cm
allowed.
- String may start with
- String may not start with
-
-7_2
not 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
None
or''
. - 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-700
is valid because700
is a validfont-weight
value.fw-700
is valid because itfw-
is a valid alias forfont-weight
bold
is valid because thebold
alias implies a property name offont-weight
- Invalid:
font-weight
by 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.700
does 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_name
is 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 thatcssutils
understands.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 important
if 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_class
may end with ‘-‘ + pseudo_item. Example prefix:color-green-i-hover
- The
css_class
may end with ‘-‘ + pseudo_item + ‘-i’. Example prefix:color-green-hover-i
- The
css_class
must 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_class
if 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_element
if 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_name
anduse_em
unit 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
value
identically matches a value built-in to the CSS standard. Returns True ifvalue
matches 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
True
ifvalue
matches a CSS built-in valued andFalse
if it does not. - The values ‘bold’, ‘italic’, ‘w-resize’, ‘arial’ all return
True
. - The values ‘-bold’, ‘fw-‘, ‘color-‘ all return
False
. - Invalid
self.property_name
also 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' -'
. Ifn
is the first letter of the string and followed by digits replace it with-
. The lettern
is an encoding for a negative sign. Leaves othern's
unmodified.' 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
value
input 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_name
allows a color property value.Reference: http://www.w3.org/TR/CSS21/propidx.html
Returns: (bool) – Returns True if the property_name
is 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
value
is a valid hexidecimal encoding.Note: Supports shorthand properties.
Parameters: value (str) – Expects a value
of 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 h
to be replaced in thevalue
if 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
h
prefix 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 theh
that matches the regex as otherh
characters may be present.Shorthand properties are supported:border case:1px solid hddd
becomes1px solid #ddd
Parameters: value – Encoded hexidecimal value of the form hf1f
orhc2c2c2
.Returns: (str) – Returns actually #0ff48f and #faf in the valid case. Returns the input value
unchanged 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 value
unchanged 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-family
category namesValues:font-family
member 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_namefont
Examples:
>>> 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_name
if 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
px
are converted toem
if use_em is True. - If
property_value
has 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 forsmall
screen sizes.'green-medium-up'
– Setcolor
to green for screen sizes greater than or equal to the lower limit_key formedium
size 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-weight
tobold
for screen sizes greater than or equal to 624px.- Note: If unit conversion is enabled i.e.
use_em
isTrue
, then 624px would be converted to 39em.
- Note: If unit conversion is enabled i.e.
Important Note about cssutils and media queries
Currently,
cssutils
does 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_class
contains one of the keys inself.breakpoint_dict
, then setself.breakpoint_values
to 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
small
could matchxxsmall
,xsmall
, andsmall
.
- This also prevents false positives since searching for
The length of
self.css_class
must be greater than the length of the key + 2. This prevents acss_class
like'-xsmall-'
or'-xxlarge-up'
from being accepted as valid by themselves.The
key
minus 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 = False
if none of the keys inself.breakpoint_dict
are 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_set
is contained inself.css_class
, then Setself.limit_key
to the value of the string found. Otherwise, setis_breakpoint = False
.Rules:
- The
limit_key
is expected to begin with a dash-
. - The
limit_key
may appear in the middle ofself.css_class
e.g.'padding-10-small-up-s-i'
. - The
limit_key
may appear at the end ofself.css_class
e.g.'margin-20-giant-down'
. - The length of
self.css_class
must be greater than the length of the limit_key + 2. This prevents acss_class
like'-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 = False
if none of the members ofself.limit_set
are 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-up
or-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_class
i.e. implieddisplay
property 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_class
with 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_class
contains 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-only
is a special case. The CSS property namedisplay
without a value is used to show/hide content. Fordisplay
reverse logic is used. The reason for this special handling ofdisplay
is that we do not know what the currentdisplay
setting is if any. This implies that the only safe way to handle it is by settingdisplay
tonone
for everything outside of the desired breakpoint limit. - Shorthand cases, for example:
small-only
,medium-up
,giant-down
are allowed. These cases imply that the CSS property name isdisplay
. This is handled in theif-statement
viapair[1:] == self.css_class
. - Note:
display + value + pair
is handled under the General Usage case. For example,display-inline-large-only
contains a value fordisplay
and only used to alter the way an element is displayed.
- The css_class
- Special Usage with
General Usage
- The css_class
padding-100-large-down
appliespadding: 100px
for screen sizes less than the lower limit oflarge
.
- The css_class
Note: Unit conversions for pixel-based
self.value
is required before the BreakpointParser is instantiated.Media Query Examples
Special Case: Generated CSS for
display-large-only
orlarge-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
below
a given screen breakpoint. Returns the generated css.Handle Cases:
- Special Usage with
display
- The css_class
display-medium-down
is a special case. The CSS property namedisplay
without a value is used to show/hide content. Fordisplay
reverse logic is used. The reason for this special handling ofdisplay
is that we do not know what the currentdisplay
setting is if any. This implies that the only safe way to handle it is by settingdisplay
tonone
for everything outside of the desired breakpoint limit. - Shorthand cases, for example:
small-only
,medium-up
,giant-down
are allowed. These cases imply that the CSS property name isdisplay
. This is handled in theif-statement
viapair[1:] == self.css_class
. - Note:
display + value + breakpoint + limit
is handled under the General Usage case. For example,display-inline-medium-down
contains a value fordisplay
and only used to alter the way an element is displayed.
- The css_class
- Special Usage with
General Usage
- The css_class
padding-100-medium-down
appliespadding: 100px
for screen sizes less than the lower limit ofmedium
.
- The css_class
Note: Unit conversions for pixel-based
self.value
is 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
above
a given screen breakpoint. Returns the generated css.Handle Cases:
- Special Usage with
display
- The css_class
display-small-up
is a special case. The CSS property namedisplay
without a value is used to show/hide content. Fordisplay
reverse logic is used. The reason for this special handling ofdisplay
is that we do not know what the currentdisplay
setting is if any. This implies that the only safe way to handle it is by settingdisplay
tonone
for everything outside of the desired breakpoint limit. - Shorthand cases, for example:
small-only
,medium-up
,giant-down
are allowed. These cases imply that the CSS property name isdisplay
. This is handled in theif-statement
viapair[1:] == self.css_class
. - Note:
display + value + breakpoint + limit
is handled under the General Usage case. For example,display-inline-small-up
contains a value fordisplay
and only used to alter the way an element is displayed.
- The css_class
- Special Usage with
General Usage
- The css_class
padding-100-small-up
appliespadding: 100px
for screen sizes less than the lower limit ofsmall
.
- The css_class
Note: Unit conversions for pixel-based
self.value
is 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_key
found 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>-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.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_flag
fromcss_class
if possible and return the clean css class. Otherwise, return thecss_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.
Returns: (str) – If the css_class
is scaling remove thescaling_flag
and return the clean css class. Otherwise, return thecss_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
- 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
blue
is 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
blue
was 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 sinceblue
is 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_limit
is exceeded and False otherwise.Returns: (bool) – Returns True if self.time_limit
is 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
string
orvariable_name
from 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]$)"
^[.]
–extension
must begin with a.
dot.[.0-9a-z]*
–extension
may contain any of the character inside the brackets.[0-9a-z]$
–extension
may 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