def test_get_css_text(self): class_set = {'giant-only-i', 'color-hfff-xsmall-only', 'font-size-13-s-i', } expected_media_query = { ( '@media only screen and (max-width: 120.0625em) {\n' + '\t.giant-only-i {\n' + '\t\tdisplay: none !important;\n' + '\t}\n' + '}\n\n' + '@media only screen and (min-width: 160.0em) {\n' + '\t.giant-only-i {\n' + '\t\tdisplay: none !important;\n' + '\t}\n' + '}\n\n' ), ( '@media only screen and (min-width: 7.5625em) and (max-width: 15.0em) {\n' + '\t.color-hfff-xsmall-only {\n' + '\t\tcolor: #fff;\n' + '\t}\n' + '}\n\n' ), ( '.font-size-13-s-i { font-size: 0.8125em !important; }\n\n' + '@media only screen and (max-width: 64.0em) {\n' + '\t.font-size-13-s-i { font-size: 0.779em !important; }\n' + '}\n\n' + '@media only screen and (max-width: 45.0em) {\n' + '\t.font-size-13-s-i { font-size: 0.7222em !important; }\n' + '}\n\n' + '@media only screen and (max-width: 30.0em) {\n' + '\t.font-size-13-s-i { font-size: 0.65em !important; }\n' + '}\n\n' ), } property_parser = ClassPropertyParser(class_set=class_set) media_query_builder = MediaQueryBuilder(property_parser=property_parser) css = media_query_builder.get_css_text() for media_query in expected_media_query: self.assertTrue(media_query in css, msg=css)
def parse(recent=True, class_set=set(), css_text=b''): """ 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 |sp| |sp| |sp| |sp| |sp| **human readable** - blowdry.min.css |sp| **minified** - Clashing Alias files (Encoded class selector aliases that are invalid and cannot be used because they clash.) - Markdown |sp| |sp| |sp| |sp| |sp| |sp| **Github** - HTML |sp| |sp| |sp| |sp| |sp| |sp| |sp| |sp| |sp| **Browser** - reStructuredText |sp| **Sphinx** - Property Alias File (Encoded class selector aliases that are valid and can be used to construct class selectors.) - Markdown |sp| |sp| |sp| |sp| |sp| |sp| **Github** - HTML |sp| |sp| |sp| |sp| |sp| |sp| |sp| |sp| |sp| **Browser** - reStructuredText |sp| **Sphinx** - Temporal Statistics **Note:** The default locations of these files can be overridden to suit your needs. **Directory assignments** ``project_directory`` -- Allows ``blowdrycss`` to know where the HTML project is located. It will only search the files in the directory specified here. .. |sp| raw:: 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. """ if settings.timing_enabled: from blowdrycss.timing import Timer timer = Timer() print('\n~~~ blowdrycss started ~~~') # Get files to parse. file_finder = FileFinder(recent=recent) # Create set of all defined classes class_parser = ClassParser(file_dict=file_finder.file_dict) # Unite class sets during on_modified case. if recent: modified_class_set = class_parser.class_set use_this_set = modified_class_set.difference(class_set) else: use_this_set = class_parser.class_set # Filter class names. Only keep classes matching the defined class encoding. class_property_parser = ClassPropertyParser(class_set=use_this_set) logging.info(msg='blowdry.class_property_parser.class_set:\t' + str(class_property_parser.class_set)) use_this_set = class_property_parser.class_set.copy() # Build a set() of valid css properties. Some classes may be removed during cssutils validation. css_builder = CSSBuilder(property_parser=class_property_parser) css_text += bytes(css_builder.get_css_text()) builder_class_set = css_builder.property_parser.class_set.copy() # Build Media Queries if settings.media_queries_enabled: unassigned_class_set = use_this_set.difference(css_builder.property_parser.class_set) css_builder.property_parser.class_set = unassigned_class_set.copy() # Only use unassigned classes css_builder.property_parser.removed_class_set = set() # Clear set media_query_builder = MediaQueryBuilder(property_parser=class_property_parser) logging.debug( msg=( 'blowdry.media_query_builder.property_parser.class_set:\t' + str(media_query_builder.property_parser.class_set) ) ) css_text += bytes(media_query_builder.get_css_text(), 'utf-8') media_class_set = unassigned_class_set.intersection(media_query_builder.property_parser.class_set) if recent: class_set = class_set.union(builder_class_set) class_set = class_set.union(media_class_set) else: class_set = builder_class_set.copy() class_set = class_set.union(media_class_set) else: if recent: class_set = class_set.union(builder_class_set) else: class_set = builder_class_set.copy() logging.debug('\nCSS Text:\n\n' + str(css_text)) print('\nAuto-Generated CSS:') # Output the DRY CSS file. (user setting option) if settings.human_readable: css_file = CSSFile(file_directory=settings.css_directory, file_name='blowdry') css_file.write(css_text=css_text) print(path.join(settings.css_directory, css_file.file_name) + '.css') # Output the Minified DRY CSS file. (user setting option) if settings.minify: css_file = CSSFile(file_directory=settings.css_directory, file_name='blowdry') css_file.minify(css_text=css_text) print(path.join(settings.css_directory, css_file.file_name) + '.min.css') if settings.timing_enabled: timer.report() if settings.minify: print_css_stats(file_name='blowdry') return class_set, css_text