CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner: Re: [mohan] Script to find unused CSS styles: Edit Log



Zhris
Enthusiast

Aug 5, 2016, 1:18 PM


Views: 17129
Re: [mohan] Script to find unused CSS styles

Here it is. Please see attached for zip file containing script and test html / css files.

- It has been designed with efficiency in mind. I ensure it only parses each file once, and selectors are not converted to xpaths if the selector has already been seen. But I decided against holding a tree for every html document in memory before iterating over selectors.

- CSS provides a read_file method but 1) the documentation is wrong, multiple css files should be provided as an array reference, 2) the object doesn't associate selectors with files.

- I have tried to keep the output data as informative as possible, it contains anything I thought could be relevant. As a result it is quite intricate. Importantly, if key xpath value is undefined then HTML::Selector::XPath wasn't able to convert the selector, and if key html doesn't exist then the selector doesn't exist in any of the html documents. You should simplify the output data as per your actual needs.


Code
use strict; 
use warnings;
use CSS;
use HTML::Selector::XPath 'selector_to_xpath';
use HTML::TreeBuilder::XPath;
use Data::Dumper;

# input
my $input =
{
filepaths_css => [ glob( "*.css" ) ],
filepaths_html => [ glob( "*.html" ) ],
properties => [ qw/margin width/ ],
};

# output
my $output = { };

# iterate over each css file
for my $filepath_css ( @{$input->{filepaths_css}} )
{
# create new css object and populate it
my $css = CSS->new; $css->read_file( $filepath_css );

# iterate over each css block
for my $style ( @{$css->{styles}} )
{
# create list of properties that match those we want
my $properties = [ grep { $style->get_property_by_name( $_ ) } @{$input->{properties}} ];

# next iteration if list of properties that match is empty
next unless @$properties;

# iterate over each selector
for my $selector ( map { $_->{name} } @{$style->{selectors}} )
{
# if we have not seen this selector before, populate output with its xpath
unless ( exists $output->{$selector} )
{
$output->{$selector}->{xpath} = eval { selector_to_xpath( $selector ) };
}

# populate output with property and css file counts
$output->{$selector}->{properties}->{$_}++ for @$properties;
$output->{$selector}->{css}->{$filepath_css}++;
}
}
}

# iterate over each html file
for my $filepath_html ( @{$input->{filepaths_html}} )
{
# create new tree object and populate it
my $tree = HTML::TreeBuilder::XPath->new_from_file( $filepath_html );

# iterate over each selector
for my $selector ( grep { defined $output->{$_}->{xpath} } keys %$output )
{
# populate output with html file counts
my $nodes = $tree->findnodes( $output->{$selector}->{xpath} );
$output->{$selector}->{html}->{$filepath_html} += @$nodes if @$nodes;
}
}

# output
local $, = "\n";
local $\ = "\n";
print Dumper $output;
print grep { defined $output->{$_}->{xpath} and not exists $output->{$_}->{html} } keys %$output;


Chris


(This post was edited by Zhris on Aug 8, 2016, 8:43 AM)
Attachments: cssfind.zip (1.66 KB)


Edit Log:
Post edited by Zhris (Enthusiast) on Aug 5, 2016, 1:28 PM
Post edited by Zhris (Enthusiast) on Aug 5, 2016, 1:48 PM
Post edited by Zhris (Enthusiast) on Aug 5, 2016, 1:57 PM
Post edited by Zhris (Enthusiast) on Aug 5, 2016, 2:03 PM
Post edited by Zhris (Enthusiast) on Aug 5, 2016, 2:04 PM
Post edited by Zhris (Enthusiast) on Aug 8, 2016, 8:43 AM


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives