sortcss.pl to HTML.

index -|- end

Generated: Sat Oct 12 17:23:19 2013 from sortcss.pl 2013/08/02 19.1 KB. text copy

#!/usr/bin/perl -w
# NAME: sortcss.pl
# AIM: Read a file of CSS, in this case taken from my site,
# and 'sort' it - that is put each element together
# 02/08/2013 - have no default input file
# 11/07/2010 - checkout, and added input file name - parse_arg and
# output the tags with width formatting...
# 05/07/2008 geoff mclane http://geoffair.net/mperl specialised
# Decode of CSS file
# Skip C comments - /* ... */
# Starts with *, ., # or character is start of tag
# other tag names can follow after comma (,)
# definition begins with '{', and ends with '}' ...
use strict;
use warnings;
use File::Basename;  # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] )
use Cwd;
my $os = $^O;
my $perl_dir = '/home/geoff/bin';
my $PATH_SEP = '/';
my $temp_dir = '/tmp';
if ($os =~ /win/i) {
    $perl_dir = 'C:\GTools\perl';
    $temp_dir = $perl_dir;
    $PATH_SEP = "\\";
}
unshift(@INC, $perl_dir);
require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl' Check paths in \@INC...\n";
# log file stuff
our ($LF);
my $pgmname = $0;
if ($pgmname =~ /(\\|\/)/) {
    my @tmpsp = split(/(\\|\/)/,$pgmname);
    $pgmname = $tmpsp[-1];
}
my $outfile = $temp_dir.$PATH_SEP."temp.$pgmname.txt";
open_log($outfile);

# user variables
my $VERS = "0.0.2 2013-08-02";
my $uin_file = '';

my $out_file = $temp_dir.$PATH_SEP.'tempcss2.css';
my $max_tag_width = 20;
my $load_log = 0;

# features
my $out_nice_txt = 0;
my $out_repeats  = 0;

# ### DEBUG ###
my $debug_on = 0;
my $def_file = 'C:\HOMEPAGE\GA\page2.css';
# DEBUG
my $dbg1 = 0;   # show start and end of C comments
my $dbg2 = 0;   # show "$i:$lnnum:$colm:$tagnum: Got tag [$tag] ... CLOSED
my $dbg3 = 0;   # show "$tagset { $tagtxt } ($lnnum)
my $dbg4 = 0;   # show "File = $actfile [$comtxt] ...
my $dbg5 = 0;   # show "NO MATCH [$tag] ne [$ttag] - VERY, VERY NOISY!!!
my $dbg6 = 0;   # show "Searching for tag [$tag] ...\n" )

my $verbosity = 0;

### program variables
my @warnings = ();

sub VERB1() { return $verbosity >= 1; }
sub VERB2() { return $verbosity >= 2; }
sub VERB5() { return $verbosity >= 5; }
sub VERB9() { return $verbosity >= 9; }

sub show_warnings($) {
    my ($val) = @_;
    if (@warnings) {
        prt( "\nGot ".scalar @warnings." WARNINGS...\n" );
        foreach my $itm (@warnings) {
           prt("$itm\n");
        }
        prt("\n");
    } else {
        prt( "\nNo warnings issued.\n\n" ) if (VERB9());
    }
}

sub pgm_exit($$) {
    my ($val,$msg) = @_;
    if (length($msg)) {
        $msg .= "\n" if (!($msg =~ /\n$/));
        prt($msg);
    }
    show_warnings($val);
    close_log($outfile,$load_log);
    exit($val);
}

sub prtw($) {
   my ($tx) = shift;
   $tx =~ s/\n$//;
   prt("$tx\n");
   push(@warnings,$tx);
}

# expect /\s*\w\s*:\s*.+;{0,1}/ repeated
sub nice_tag_text($) {
   my ($tt) = shift;
   $tt = trim_all($tt);
   my $len = length($tt);
   # got for a simple thing ...
   my @arr = split(';',$tt);
   my $asz = scalar @arr;
   my $ntt = '';
   for (my $k = 0; $k < $asz; $k++) {
      my $ti = trim_all($arr[$k]);
      $ntt .= "\n" if length($ntt);
      $ntt .= " $ti;";
   }
   return $ntt;
}

sub set_line_col($$$) {
   my ($ch1, $colm1, $lnnum1) = @_;
   $$colm1++;
   if ($ch1 eq "\n") {
      $$colm1 = 0;
      $$lnnum1++;
   }
}

sub trim_array_items($) {
   my (@ar) = @_;
   my $l = scalar @ar;
   for (my $p = 0; $p < $l; $p++) {
      $ar[$p] = trim_all($ar[$p]);
   }
   return @ar;
}


# usage: $wmsg = compare_done_tags($tag, $tagtxt, @tagtxtdone);
sub compare_done_tags($$$) {
   my ($tg, $tt, @done) = @_;
   my $sz = scalar @done;
   my @arr1 = split(';',$tt);
   my $al1 = scalar @arr1;
   my ($m, $n, $p, $q, $same, $itm1, $itm2);
   @arr1 = trim_array_items(@arr1);
   for ($m = 0; $m < $sz; $m++) {
      my $ttg = $done[$m][0];
      ###if ($tg eq $ttg) {
      if (lc($tg) eq lc($ttg)) {
         my $ttt = $done[$m][1];
         my @arr2 = split(';',$ttt);
         my $al2 = scalar @arr2;
         @arr2 = trim_array_items(@arr2);
         $same = 0;
         for ($n = 0; $n < $al1; $n++) {
            $itm1 = $arr1[$n];   # for each attribute in passed tag text
            my @arr3 = trim_array_items(split(':',$itm1));   # split attribute 'margin:0'
            my $al3 = scalar @arr3;
            for ($p = 0; $p < $al2; $p++) {   # now of done itme
               $itm2 = $arr2[$p];   # extract tag text item, split on ';'
               my @arr4 = trim_array_items(split(':',$itm2));   # get split on ':';
               my $al4 = scalar @arr4;
               if ($al3 == $al4) {
                  # if two splits are the same
                  for ($q = 0; $q < $al3; $q++) {
                     # try to correct case, at least on some, like color
                     if ($q == 1) {
                        if (substr($arr3[$q],0,1) eq '#') {
                           $arr3[$q] = lc($arr3[$q]);
                        }
                        if (substr($arr4[$q],0,1) eq '#') {
                           $arr4[$q] = lc($arr4[$q]);
                        }
                     }
                     if ($arr3[$q] ne $arr4[$q]) {
                        last;
                     }
                  }
                  if ($q == $al3) {
                     $same++;
                  }
               }
            }
         }
         if ($same == $al1) {
            return "repeat";
         }
      }   # tags are equal
   }
   return "";
}


sub process_in_file($) {
    my $in_file = shift;
    my @lines = ();
    my $line = '';
    my $lncnt = 0;
    my %taglist = ();
    my @tagarray = ();
    my $wmsg = '';
    my @tagtxtdone = ();
    my @tagoutput = ();

    my ($txt, $i, $ch, $len, $pch, $incom, $lnnum);
    my ($colm, $tag, $intag, $tagtxt, $tagset, $tagnum);
    my ($bgnln, $nch, $comtxt, $actfile, $tagp2);
    if (open INF, "<$in_file") {
        @lines = <INF>;
        close INF;
        $lncnt = scalar @lines;
        $txt = join('', @lines);
        $len = length($txt);
        prt( "Got $lncnt lines to process ... $len characters ... from $in_file\n" );
        $pch = '';
        $incom = 0;
        $lnnum = 1;
        $colm = 0;
        $tag = '';
        $comtxt = '';
        $actfile = '';
        for ($i = 0; $i < $len; $i++) {
            $ch = substr($txt,$i,1);
            set_line_col($ch, \$colm, \$lnnum);
            if ($incom) {
                $comtxt .= $ch;
                if ($ch eq '/') {
                    if ($pch eq '*') {
                        $incom = 0;
                        prt( "$i:$lnnum:$colm: Exit comment ...\n" ) if ($dbg1);
                        ###if ($comtxt =~ /\w{1}:[\\\/]\w+/) {
                        if ($comtxt =~ /\/\*.*(\w{1}:[\\\/]\w+.*)\*\//) {
                            $actfile = $1;
                            prt( "File = $actfile [$comtxt] ...\n" ) if ($dbg4);
                        }
                    }
                }
            } else {
                if ($ch eq '*') {
                    if ($pch eq '/') {
                        $incom = 1;
                        prt( "$i:$lnnum:$colm: Entered comment ...\n" ) if ($dbg1);
                        $comtxt = $pch.$ch;
                    }
                } elsif ($ch =~ /[\w#\.\*]/) {
                    $tag = $ch;
                    $i++;
                    $intag = 1;
                    $tagset = '';
                    $tagnum = 0;
                    $bgnln = $lnnum;
                    while ($intag) {
                        $tagnum++;
                        for (; $i < $len; $i++) {
                            $ch = substr($txt,$i,1);
                            set_line_col($ch, \$colm, \$lnnum);
                            if ($ch =~ /[\s,\{]/) {
                                $i++;
                                last;
                            }
                            $tag .= $ch;
                        }
                        while (($i < $len)&&($ch =~ /\s/)) {
                            # notes SPACE can also separate tags, so got to next non-space, but ...
                            # EAT space
                            while (($ch =~ /\s/)&&($i < $len)) {
                                $ch = substr($txt,$i,1);
                                set_line_col($ch, \$colm, \$lnnum);
                                $i++;
                            }
                            if (($ch ne ',') && ($ch ne '{') && !($ch =~ /\s/) ) {
                                # ok, it seems this BELONGS to the tag ???
                                $tag .= ' '.$ch;
                                for (; $i < $len; $i++) {
                                    $ch = substr($txt,$i,1);
                                    set_line_col($ch, \$colm, \$lnnum);
                                    if ($ch =~ /[\s,\{]/) {
                                        $i++;
                                        last;
                                    }
                                    $tag .= $ch;
                                }
                            }
                        }

                        if ($ch eq '{') {
                            prt( "$i:$lnnum:$colm:$tagnum: Got tag [$tag] ... CLOSED \n" ) if ($dbg2);
                        } else {
                            prt( "$i:$lnnum:$colm:$tagnum: Got tag [$tag] ... ($ch)\n" ) if ($dbg2);
                        }
                        if (defined $taglist{$tag}) {
                            $taglist{$tag}++;
                        } else {
                            $taglist{$tag} = 1;
                        }
                        $tagset .= '|' if length($tagset);
                        $tagset .= $tag;
                        $tag = '';
                        # if we have a COMMA, eat spaces until next non-space char
                        if (($ch eq ',')&&($i < $len)) {
                            $nch = substr($txt,$i,1);
                            while (($i < $len)&&($nch =~ /\s/)) {
                                $i++;
                                $nch = substr($txt,$i,1);
                                set_line_col($nch, \$colm, \$lnnum);
                            }
                        }
                        $intag = 0 if ($ch eq '{');
                    }

                    $tagtxt = '';
                    if ($ch eq '{') {
                        for (; $i < $len; $i++) {
                            $ch = substr($txt,$i,1);
                            set_line_col($ch, \$colm, \$lnnum);
                            if ($ch eq '}') {
                                last;
                            }
                            $tagtxt .= $ch;
                            $pch = $ch;
                        }
                        $tagtxt =~ s/\n/ /g;
                        $tagtxt = trim_all($tagtxt);
                        prt( "Stored: [$tagset] { $tagtxt } ($lnnum)\n" ) if ($dbg3);
                        push(@tagarray, ["$tagset", $tagtxt, $bgnln, 0, $actfile]);
                    } else {
                        mydie( "$i:$lnnum:$colm: No close tag ...\n" );
                    }
                }
            }
            $pch = $ch;
        }
    } else {
        prt( "ERROR: Can NOT open $in_file ... check name. location \n" );
    }

    if (@tagarray) {
        my (@tags, $tgcnt, $j, $fnd, $ttag,$min,$len,$ctag);
        $tagnum = scalar @tagarray;
        $lnnum = scalar keys(%taglist);
        prt( "***** RESULTS **** Options: out_nice_txt=$out_nice_txt, out_repeats=$out_repeats\n" );
        prt( "Got $tagnum tags to sort ... $lnnum different tags ...\n" );
        $min = 0;
        foreach $tag (keys %taglist) {
            $len = length($tag);
            $min = $len if ($len > $min);
            last if ($min > $max_tag_width);
        }
        $min = $max_tag_width if ($min > $max_tag_width);
        foreach $tag (sort keys %taglist) {
            $fnd = 0;
            $ctag = $tag;
            $ctag .= ' ' while (length($ctag) < $min);
            prt( "Searching for tag [$tag] ...\n" ) if ($dbg6);
            for ($i = 0; $i < $tagnum; $i++) {
                $tagset = $tagarray[$i][0];
                $tagtxt = $tagarray[$i][1];
                $bgnln  = $tagarray[$i][2];
                $actfile = $tagarray[$i][4];
                @tags = split(/\|/,$tagset);
                $tgcnt = scalar @tags;
                for ($j = 0; $j < $tgcnt; $j++) {
                    $ttag = $tags[$j];
                    if ($ttag eq $tag) {
                        $fnd++;
                        $tagarray[$i][3]++;
                        $wmsg = compare_done_tags($tag, $tagtxt, @tagtxtdone);
                        push(@tagtxtdone, [$tag, $tagtxt, $actfile]);
                        push(@tagoutput, [$tag, $tagtxt, $actfile]) if ($wmsg ne 'repeat');
                        if ($out_nice_txt) {
                            if ($out_repeats) {
                                prt( "$tag {\n".nice_tag_text($tagtxt)."\n} /* $bgnln $actfile $wmsg*/\n" );
                            } elsif ($wmsg ne 'repeat') {
                                prt( "$tag {\n".nice_tag_text($tagtxt)."\n} /* $bgnln $actfile $wmsg*/\n" );
                            }
                        } else {
                            if ($out_repeats) {
                                prt( "$ctag { $tagtxt } /* $bgnln $actfile $wmsg */ \n" );
                            } elsif ($wmsg ne 'repeat') {
                                prt( "$ctag { $tagtxt } /* $bgnln $actfile $wmsg */ \n" );
                            }
                        }
                    } else {
                        prt( "NO MATCH [$tag] ne [$ttag]\n" ) if ($dbg5);
                    }
                }
            }
            if (!$fnd) {
                $wmsg = "WARNING: tag [$tag] NOT FOUND!";
                prt( "$wmsg\n" );
            }
        }
        $fnd = 0;
        for ($i = 0; $i < $tagnum; $i++) {
            if ($tagarray[$i][3] == 0) {
                $fnd++;
            }
        }
        if ($fnd) {
            prt( "\nWARNING: It appears $fnd items NOT utilised ...\n" );
            for ($i = 0; $i < $tagnum; $i++) {
                if ($tagarray[$i][3] == 0) {
                    $tagset = $tagarray[$i][0];
                    $tagtxt = $tagarray[$i][1];
                    $bgnln  = $tagarray[$i][2];
                    $actfile = $tagarray[$i][4];
                    prt( "[$tagset] { $tagtxt } /* $bgnln $actfile */ \n" );
                }
            }
            prt( "CHECK THESE!!!\n" );
        } else {
            prt( "Appears ALL entries in tagarray covered ... as they should be ...\n" );
        }
    }

    ###my $out_file = 'tempcss2.css';
    if (@tagoutput) {
        my $cnt = scalar @tagoutput;
        my $lastfile = '';
        if (open OUTF, ">$out_file") {
            print OUTF "/* CSS SUMMARY - ".scalar localtime(time()). " */\n";
            $tagnum = scalar @tagoutput;
            $lastfile = '';
            for ($i = 0; $i < $tagnum; $i++) {
                $tagset = $tagoutput[$i][0];
                next if ($tagset =~ /#/);
                next if (!($tagset =~ /^\./));
                next if (length($tagset) > 2);
                $tagtxt = $tagoutput[$i][1];
                $actfile = $tagoutput[$i][2];
                $wmsg = '';
                $wmsg = "/* $actfile */" if length($actfile) && ($lastfile ne $actfile);
                print OUTF "$tagset {\n".nice_tag_text($tagtxt)."\n} $wmsg\n\n";
                $lastfile = $actfile;
            }
            $lastfile = '';
            for ($i = 0; $i < $tagnum; $i++) {
                $tagset = $tagoutput[$i][0];
                next if ($tagset =~ /#/);
                next if (($tagset =~ /^\./)&&(length($tagset) <= 2));
                $actfile = $tagoutput[$i][2];
                $tagtxt = $tagoutput[$i][1];
                $wmsg = '';
                $wmsg = "/* $actfile */" if length($actfile) && ($lastfile ne $actfile);
                print OUTF "$tagset {\n".nice_tag_text($tagtxt)."\n} $wmsg\n\n";
                $lastfile = $actfile;
            }
            $lastfile = '';
            for ($i = 0; $i < $tagnum; $i++) {
                $tagset = $tagoutput[$i][0];
                next if !($tagset =~ /#/);
                next if (($tagset =~ /^\./)&&(length($tagset) <= 2));
                $tagtxt = $tagoutput[$i][1];
                $wmsg = '';
                $wmsg = "/* $actfile */" if length($actfile) && ($lastfile ne $actfile);
                print OUTF "$tagset {\n".nice_tag_text($tagtxt)."\n} $wmsg\n\n";
                $lastfile = $actfile;
            }
            print OUTF "/* eof - $out_file */\n";
            close OUTF;
            prt( "Written file $out_file ...\n" );
        }
    }
}

################################
# ====================================
# MAIN
# ====================================
parse_args(@ARGV);
process_in_file($uin_file);
pgm_exit(0,"");
# =====================================

sub need_arg {
    my ($arg,@av) = @_;
    pgm_exit(1,"ERROR: [$arg] must have a following argument!\n") if (!@av);
}

sub parse_args {
    my (@av) = @_;
    my ($arg,$sarg);
    while (@av) {
        $arg = $av[0];
        if ($arg =~ /^-/) {
            $sarg = substr($arg,1);
            $sarg = substr($sarg,1) while ($sarg =~ /^-/);
            if (($sarg =~ /^h/i)||($sarg eq '?')) {
                give_help();
                pgm_exit(0,"Help exit(0)");
            } elsif ($sarg =~ /^v/) {
                if ($sarg =~ /^v.*(\d+)$/) {
                    $verbosity = $1;
                } else {
                    while ($sarg =~ /^v/) {
                        $verbosity++;
                        $sarg = substr($sarg,1);
                    }
                }
                prt("Verbosity = $verbosity\n") if (VERB1());
            } elsif ($sarg =~ /^l/) {
                if ($sarg =~ /^ll/) {
                    $load_log = 2;
                } else {
                    $load_log = 1;
                }
                prt("Set to load log at end. ($load_log)\n") if (VERB1());
            } elsif ($sarg =~ /^o/) {
                need_arg(@av);
                shift @av;
                $sarg = $av[0];
                $out_file = $sarg;
                prt("Set out file to [$out_file].\n") if (VERB1());
            } else {
                pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n");
            }
        } else {
            $uin_file = $arg;
            prt("Set input to [$uin_file]\n") if (VERB1());
        }
        shift @av;
    }

    if ($debug_on) {
        prtw("WARNING: DEBUG is ON!\n");
        if (length($uin_file) ==  0) {
            $uin_file = $def_file;
            prt("Set DEFAULT input to [$uin_file]\n");
        }
    }
    if (length($uin_file) ==  0) {
        pgm_exit(1,"ERROR: No input files found in command!\n");
    }
    if (! -f $uin_file) {
        pgm_exit(1,"ERROR: Unable to find in file [$uin_file]! Check name, location...\n");
    }
}

sub give_help {
    prt("$pgmname: version $VERS\n");
    prt("Usage: $pgmname [options] in-css-file\n");
    prt("Options:\n");
    prt(" --help  (-h or -?) = This help, and exit 0.\n");
    prt(" --verb[n]     (-v) = Bump [or set] verbosity. def=$verbosity\n");
    prt(" --load        (-l) = Load LOG at end. ($outfile)\n");
    prt(" --out <file>  (-o) = Write output to this file.\n");
}


# eof - sortcss.pl

index -|- top

checked by tidy  Valid HTML 4.01 Transitional