pax_global_header00006660000000000000000000000064122354570710014520gustar00rootroot0000000000000052 comment=3be7dfff2d8b5453ade3caa06a37bd33a8aaf21b libcss-lessp-perl-0.86/000077500000000000000000000000001223545707100150205ustar00rootroot00000000000000libcss-lessp-perl-0.86/Changes000066400000000000000000000015561223545707100163220ustar00rootroot00000000000000Revision history for Perl extension CSS::LESSp 0.86 Fix for perl < 5.10 add MANIFEST 0.85 01.03.2011/14:31 fix calculation result=0 inifinte loop bug [Michael Schout] add support for expressions involving negative numbers [Michael Schout] 0.83 30.12.2010/20:08 fixed tests - again 0.82 30.12.2010/16:55 fixed tests 0.81 28.07.2010/10:00 tests files changed to fix the tests 0.80 21.07.2010/10:08 parts of lessp were rewritten dash-prefix and mixins with variables support a lot of other stuff supported ( see .pm file and search for specs ) 0.03 01.10.2009/09:15 chanes in pod documentation 0.02 30.09.2009/15:53 fixed bug for negative values ( margin: -40px 0px 0px 0px ) fixed POD documentation to give correct test fixed use of uninitialized value in string warning - line 74 0.01 29.09.2009/16:33 initial public version libcss-lessp-perl-0.86/MANIFEST000066400000000000000000000004671223545707100161600ustar00rootroot00000000000000Changes lib/CSS/LESSp.pm Makefile.PL MANIFEST MANIFEST.SKIP README script/lessp.pl t/01-loads.t t/02-parse.t t/less/css-3.css t/less/css-3.less t/less/css.css t/less/css.less t/less/mult-by-zero.css t/less/mult-by-zero.less t/pod.t META.yml Module meta-data (added by MakeMaker) libcss-lessp-perl-0.86/MANIFEST.SKIP000066400000000000000000000001501223545707100167120ustar00rootroot00000000000000^blib/ ^Makefile$ .*\.bak$ ^Makefile\.old$ ^pm_to_blib$ ^blib$ ^\.git/ ^\.gitignore$ \._.* CSS-LESSp-.* libcss-lessp-perl-0.86/META.yml000066400000000000000000000010071223545707100162670ustar00rootroot00000000000000--- #YAML:1.0 name: CSS-LESSp version: 0.86 abstract: ~ author: - Ivan Drinchev license: unknown distribution_type: module configure_requires: ExtUtils::MakeMaker: 0 build_requires: ExtUtils::MakeMaker: 0 requires: Test::More: 0 no_index: directory: - t - inc generated_by: ExtUtils::MakeMaker version 6.56 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 libcss-lessp-perl-0.86/Makefile.PL000066400000000000000000000007341223545707100167760ustar00rootroot00000000000000use strict; use warnings; use ExtUtils::MakeMaker; WriteMakefile( NAME => 'CSS::LESSp', AUTHOR => 'Ivan Drinchev ', VERSION_FROM => 'lib/CSS/LESSp.pm', PL_FILES => {}, EXE_FILES => [ qw/script\/lessp.pl/ ], PREREQ_PM => { 'Test::More' => 0, }, dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, clean => { FILES => 'CSS-Lessp-*' }, ); libcss-lessp-perl-0.86/README000066400000000000000000000010061223545707100156750ustar00rootroot00000000000000CSS::LESSp This module is for parsing .less css files in to css INSTALLATION To install this module, run the following commands: perl Makefile.PL make make test make install SUPPORT AND DOCUMENTATION After installing, you can find documentation for this module with the perldoc command. perldoc CSS::LESSp COPYRIGHT AND LICENCE Copyright (C) 2009 Ivan Drinchev This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. libcss-lessp-perl-0.86/lib/000077500000000000000000000000001223545707100155665ustar00rootroot00000000000000libcss-lessp-perl-0.86/lib/CSS/000077500000000000000000000000001223545707100162165ustar00rootroot00000000000000libcss-lessp-perl-0.86/lib/CSS/LESSp.pm000077500000000000000000000501421223545707100175070ustar00rootroot00000000000000#!/usr/bin/perl package CSS::LESSp; use warnings; use strict; use Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw('parse'); our $VERSION = '0.86'; my $id = 1; # # specs check # # accessors.less ( ok ) # big.less ( ok ) # colors.less ( ok ) exceptions : no hsl # comments.less ( ok ) # css-3.less ( ok ) # css.less ( ok ) # dash-prefix.less ( ok ) # functions.less ( unsupported ) # hidden.less ( unsupported ) # import-with-extra-paths.less ( unsupported ) # import.less ( unsupported ) # lazy-eval.less ( unsupported ) # literal-css.less ( unsupported ) # mixins-args.less ( ok ) # mixins.less ( ok ) # operations.less ( ok ) # parens.less ( ok ) # rulesets.less ( ok ) # scope.less ( ok ) # selectors.less ( ok ) # strings.less ( ok ) # variables.less ( ok ) # whitespace.less ( ok ) exceptions : doesn't merge same lines # sub new { my $class = shift; my $self = { 'variables' => {}, 'rules' => [], 'type' => 'child', 'children' => [] }; bless $self, $class; return $self; } sub isFunction { my ($self) = @_; if ( $self->{'type'} eq 'function' ) { return 1; } return 0; } sub insertChild { my ($self, $name, $parents) = @_; my @parents = @{$parents} if $parents; $id++; $self->{'children'} = [] if !defined($self->{'children'}); $name =~ s/\n/ /mg; # # Find the full name my $fullName = $name; if ( defined($self->{'id'}) ) { my @names = $name =~ /\,/ ? split(/\s*\,\s*/, $name) : ( $name ); for my $parent ( reverse @parents ) { next if !defined($parent->{'name'}); my @prenames = $parent->{'name'} =~ /\,/ ? split(/\s*\,\s*/, $parent->{'name'}) : ($parent->{'name'}); my @postnames = (); for my $prename ( @prenames ) { for my $name ( @names ) { push @postnames, $prename.( $name =~ /^\:/ ? "" : " " ).$name; } } @names = @postnames; $fullName = join(", ", @names); } } push @{$self->{'children'}}, { 'name' => $name, 'fullname' => $fullName, 'type' => 'child', 'id' => $id, 'variables' => {} }; return bless $self->{'children'}->[$#{$self->{'children'}}]; } sub insertVariable { my ($self, $variable, $value) = @_; if ( $self->isFunction ) { push @{$self->{'variables'}}, { $variable => $value }; } else { $self->{'variables'}->{$variable} = $value; } return $self; } sub insertRule { my ($self, $property, $value) = @_; $self->{'rules'} = [] if !defined($self->{'rules'}); push @{$self->{'rules'}}, { $property => $value }; return $self; } sub insertFunction { my ($self, $name, $parents) = @_; my @parents = @{$parents} if $parents; #my @variables = @{$variables} if $variables; $name =~ s/\n/ /mg; $self->{'functions'} = [] if !defined($self->{'functions'}); push @{$self->{'functions'}}, { 'name' => $name, 'type' => 'function', 'variables' => [] }; return bless $self->{'functions'}->[$#{$self->{'functions'}}]; } sub getVariable { my ($self, $variable, $parents) = @_; my @parents = @{$parents} if $parents; # # First try to see if the variable is here if ( defined($self->{'variables'}->{$variable}) ) { return $self->{'variables'}->{$variable}; } # # If we have parents parse them too for my $parent ( reverse @parents ) { return $parent->{'variables'}->{$variable} if defined($parent->{'variables'}->{$variable}); } return 0; } sub getSelector { my ($self, $name, $parents) = @_; my @parents = @{$parents} if $parents; # # First try to see if it's a previous sibling if ( defined($self->{'children'}) ) { for my $style ( @{$self->{'children'}} ) { return $style if ($style->{'name'} eq $name); } } # # Next try to find from parents for my $parent ( reverse @parents ) { for my $style ( @{$parent->{'children'}} ) { return $style if ($style->{'name'} eq $name); } } # # Last we start search of everything if it is root my $root = $parents[0] if !defined($parents[0]->{'id'}); if ( defined($root->{'children'}) ) { my $return; my $fullNameSelector; $root->process(sub { my ($style) = @_; if ( defined($style->{'name'}) and $style->{'name'} eq $name ) { $return = $style; } if ( defined($style->{'fullname'}) and $style->{'fullname'} eq $name ) { $fullNameSelector = $style; } }); return $return if $return; return $fullNameSelector if $fullNameSelector; } # # If we can't find ... then try for functions the same way if ( defined($self->{'functions'}) ) { for my $function ( @{$self->{'functions'}} ) { return $function if ($function->{'name'} eq $name); } } for my $parent ( reverse @parents ) { if ( defined($parent->{'functions'}) ) { for my $function ( @{$parent->{'functions'}} ) { return $function if ($function->{'name'} eq $name); } } } if ( defined($root->{'children'}) ) { my $return; my $fullNameSelector; $root->process(sub { my ($style) = @_; if ( defined($style->{'functions'}) ) { for my $function ( @{$style->{'functions'}} ) { if ( defined($function->{'name'}) and $function->{'name'} eq $name ) { $return = $function; } } } }); return $return if $return; return $fullNameSelector if $fullNameSelector; } return 0; } sub getValue { my ($self, $property) = @_; my $value; if ( defined($self->{'rules'}) ) { for my $rule ( @{$self->{'rules'}} ) { $value = join('', values %{$rule}) if join('', keys %{$rule}) eq $property; } } return $value; } sub process { my ($styles, $function) = @_; my @parents = (); push @parents, $styles->{'children'}; $styles = $styles->{'children'}; my $level = 0; push my @position, 0; while ( 1 ) { my $style = $styles->[$position[$level]]; &$function($style, $level, (\@parents, \@position)); if ( defined($style->{'children'}) ) { $level++; $position[$level] = 0; push @parents, $styles; $styles = $style->{'children'}; } else { while ( $position[$level] == $#{$styles} ) { return 1 if $level == 0; $styles = pop @parents; $level--; } $position[$level]++; } } return 0; } sub copyTo { my ($self, $targetSelector) = @_; my ($rules, $children, $variables); # copy rules if ( defined($self->{'rules'}) ) { $targetSelector->{'rules'} = [] if !defined($targetSelector->{'rules'}); for my $rule ( @{$self->{'rules'}} ) { push @{$targetSelector->{'rules'}}, {%{$rule}}; } } # copy variables if ( defined($self->{'variables'}) ) { for my $variable ( keys %{$self->{'variables'}} ) { $targetSelector->{'variables'}->{$variable} = $variables->{$variable}; } } # copy children if ( defined($self->{'children'}) ) { my @targets = (); push @targets, $targetSelector; my $target = $targetSelector; my $l = 0; $self->process(sub { my ($style, $level) = @_; $target = $target->insertChild($style->{'name'}, \@targets); # # adding variables if ( defined($style->{'variables'}) ) { for my $variable ( keys %{$style->{'variables'}} ) { $target->insertVariable($variable, $style->{'variables'}->{$variable}); } } # # adding rules if ( defined($style->{'rules'}) ) { for my $rule ( @{$style->{'rules'}} ) { my $property = join("", keys %{$rule}); my $value = join("", values %{$rule}); $target->insertRule($property, $value); } } # # children leveling if ( defined($style->{'children'}) ) { push @targets, $target; } else { if ( $l != $level ) { $l = $level; $target = pop @targets; } } }); } return 0; } sub copyFunction { my ($self, $targetSelector, $variables, $parents) = @_; my ($rules, $children); my @variables = @{$variables}; my @parents = @{$parents}; # copy vars if ( defined($self->{'variables'}) ) { for ( my $position = 0; $position <= $#{$self->{'variables'}}; $position++ ) { my $variable = join("",keys %{$self->{'variables'}->[$position]}); my $value = join("", values %{$self->{'variables'}->[$position]}); $value = $variables[$position] if $variables[$position]; $targetSelector->{'variables'}->{$variable} = $value; } } # copy rules if ( defined($self->{'rules'}) ) { $targetSelector->{'rules'} = [] if !defined($targetSelector->{'rules'}); for my $rule ( @{$self->{'rules'}} ) { my $property = join("", keys %{$rule}); my $value = join("", values %{$rule}); while ( $value =~ /\@(\w+\-*\w*)/ ) { my $word = $1; # get the variable my $var = $targetSelector->getVariable($word, \@parents); $value =~ s/\@$word/$var/; # if variable value is negative if ( $var =~ s/^\-// ) { $value =~ s/\-\s*\-$var/\+ $var/g; $value =~ s/\+\s*\-$var/\- $var/g; } } # parse for other stuff $value = _parse_value($value); push @{$targetSelector->{'rules'}}, {$property => $value}; } } # copy children if ( defined($self->{'children'}) ) { my @targets = (); push @targets, $targetSelector; my $target = $targetSelector; my $l = 0; $self->process(sub { my ($style, $level) = @_; $target = $target->insertChild($style->{'name'}); # # adding variables if ( defined($style->{'variables'}) ) { for my $variable ( keys %{$style->{'variables'}} ) { $target->insertVariable($variable, $style->{'variables'}->{$variable}); } } # # adding rules if ( defined($style->{'rules'}) ) { for my $rule ( @{$style->{'rules'}} ) { my $property = join("", keys %{$rule}); my $value = join("", values %{$rule}); $target->insertRule($property, $value); } } # # children leveling if ( defined($style->{'children'}) ) { push @targets, $target; } else { if ( $l != $level ) { $l = $level; $target = pop @targets; } } }); } return 0; } sub dump { my ($self) = @_; my @return = (); if ( defined($self->{'rules'}) ) { for my $rule ( @{$self->{'rules'}} ) { push @return, join('', keys %{$rule}).join('', values %{$rule}).";\n"; } push @return, "\n"; } $self->process(sub { my ($style, $level, @arrays) = @_; my @parents = @{$arrays[0]}; my @position = @{$arrays[1]}; if ( defined($style->{'rules'}) ) { push @return, $style->{'fullname'} ." { "; push @return, "\n" if $#{$style->{'rules'}} > 0; for my $rule ( @{$style->{'rules'}} ) { push @return, "\t" if $#{$style->{'rules'}} > 0; push @return, join('', keys %{$rule}).": ".join('', values %{$rule})."; "; push @return, "\n" if $#{$style->{'rules'}} > 0; } push @return, "}\n"; } }); return @return; } sub _parse_value { my $value = shift; # convert rgb(255,255,255) to #ffffff ( hsl doesn't work right now ) while ( $value =~ /rgb\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/ ) { my $color = sprintf("#%0.2X%0.2X%0.2X", $1,$2,$3); $value =~ s/rgb\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/$color/; } # expand colors ( from #fff to #ffffff ) while ( $value =~ /\#([abcdef0123456789]{3})([^abcdef0123456789]|$)/i ) { my $color = $1; my $replace = join('', map { $_ x 2 } split(//, $color)); # equals to : for ( split(//, $color) ) { $replace .= $_ x 2; } $value =~ s/\#$color/\#$replace/; } # expressions in brackets while ( $value =~ /\(\s*(\-?\d+\s*((px|pt|em|cm|%))*\s*[\+\*\/\-]\s*\-?\d+\s*((px|pt|em|cm|%))*)\s*\)/ ) { my $expression = my $eval = $1; my ($removed) = $eval =~ m/(px|pt|em|cm|%)/; $eval =~ s/(px|pt|em|cm|%)//; if ( $eval !~ /[a-z]/i and defined(my $result = eval($eval)) ) { $result .= "$removed" if defined $result and $removed; $value =~ s/(\(\Q$expression\E\))/$result/; }; } # expression (+,-,*,/) ; whole expressions if ( $value =~ /(\d+)\s*(px|pt|em|cm|%)*\s*(\+|\*|\/)\s*((\d+)\s*(px|pt|em|cm|%)*|\d+)/ or $value =~ /(\d+)\s*(px|pt|em|cm|%)*\s*(\-)\s+((\d+)\s*(px|pt|em|cm|%)*|\d+)/ ) { my $eval = $value; my $removed = $1 if $eval =~ s/(px|pt|em|cm|%)//g; if ( $eval !~ /[a-z]/i ) { my $result = eval($eval); $result .= "$removed" if defined($result) and $removed; $value = $result if !$@ and defined $result; } } # expression with color if ( $value =~ /\#[abcdef0123456789]{6}/i and $value =~ /(\+|\-|\*|\/)/ ) { my @rgb = ( $value, $value, $value ); $rgb[0] =~ s/\#([abcdef0123456789]{2})[abcdef0123456789]{4}/\#$1/ig; $rgb[1] =~ s/\#[abcdef0123456789]{2}([abcdef0123456789]{2})[abcdef0123456789]{2}/\#$1/ig; $rgb[2] =~ s/\#[abcdef0123456789]{4}([abcdef0123456789]{2})/\#$1/ig; my $return = ""; for ( @rgb ) { while ( /\#([abcdef0123456789]{2})/i ) { my $dec = hex($1); s/\#$1/$dec/; } if ( !/[a-z]/i ) { my $eval = eval; if ( $eval < 0 ) { $eval = 0 }; if ( $eval > 255 ) { $eval = 255 }; $return .= sprintf("%0.2X", $eval); } } $value = "#".lc $return if $return; } return $value; } sub parse { my $self = shift; my $string = shift; my $styles = CSS::LESSp->new(); my $selector = $styles; my @parents; push @parents, $styles; # real parsing my $lastChar = my $buffer = my $mode = my $stop = ""; $string =~ s/^\xEF\xBB\xBF\x0A//; # removing special characters from front of file for ( split //, $string ) { $buffer .= $_; if ( $mode ) { $buffer =~ s/.$// if $mode eq "delete"; if ( length($stop) == 1 and $_ eq $stop ) { $mode = "" }; if ( length($stop) == 2 and $lastChar.$_ eq $stop ) { $mode = "" } else { $lastChar = $_ }; next; } next if /\n/; # # The program # if ( /\}/ or /\;/ ) { # clearing some buffer data $buffer =~ s/.$//; $buffer =~ s/^\s*|\s*$//g; # remove any spaces from front or back $buffer =~ s/\s*\n\s*/ /g; # removes any new line if ( $buffer ) { # if it's a property and rule if ( $buffer =~ s/^\s*([^:]*)\s*\:\s*(.*)\s*$// ) { my $property = $1; my $value = $2; $value =~ s/\n/ /g; $property =~ s/\s*$//; # remove any additional spaces left # different rule-set property ( mixins ) if ( $value =~ /^(#|.)(.*)\[(.*)\]$/ ) { my $targetSelectorName = $1.$2; my $targetProperty = $3; my $return; $targetProperty =~ s/['"]//g; $targetProperty =~ s/\s*//g; # get the target mixin selector my $targetSelector = $selector->getSelector($targetSelectorName, \@parents); # get the value if ( $targetProperty =~ /^\@/ ) { $targetProperty =~ s/^\@//; $return = $targetSelector->getVariable($targetProperty); } else { $return = $targetSelector->getValue($targetProperty); } $value = $return if $return; } # variable access if ( !$selector->isFunction ) { while ( $value =~ /\@(\w+\-*\w*)/ ) { my $word = $1; # get the variable my $var = $selector->getVariable($word, \@parents); $value =~ s/\@$word/$var/; # if variable value is negative if ( $var =~ s/^\-// ) { $value =~ s/\-\s*\-$var/\+ $var/g; $value =~ s/\+\s*\-$var/\- $var/g; } } # parse for other stuff $value = _parse_value($value); } # variable definition check ( after we have parsed the stuff ) if ( $property =~ /^\@(\w+\-*\w*)/ ) { $selector->insertVariable($1, $value); $property = $value = ""; } else { $selector->insertRule($property, $value); } } # nested rules (mixins) if ( $buffer =~ s/^(\..*)$// or $buffer =~ s/^(\#.*)$// ) { my $source = $1; $source =~ s/\s*\:\s*/\:/g; # for multiple mixins while ( $source =~ /\(.*,.*\)/ ) { $source =~ s/\(\s*(.*)\s*,\s*(.*)\s*\)/($1;$2)/ }; my @sources = $source =~ /\,/ ? split(/\s*\,\s*/, $source) : ( $source ); for my $source ( @sources ) { my @vars; # this is if any functions are found my $sourceSelector = $selector->getSelector($source , \@parents); if ( $source =~ /\>/ && !$sourceSelector ) { my ( $parent, $child ) = split(/\s*\>\s*/, $source); my $pSelector = $selector->getSelector($parent, \@parents); $sourceSelector = $pSelector->getSelector($child) if $pSelector; } if ( $source =~ /(.*)\((.*)\)/ && !$sourceSelector ) { my $function = $1; my $vars = $2; @vars = $vars =~ /\;/ ? split(/\;/, $vars) : ( $vars ); $sourceSelector = $selector->getSelector($function, \@parents); } next if !$sourceSelector; if ( $sourceSelector->isFunction ) { $sourceSelector->copyFunction($selector, \@vars, \@parents); } else { $sourceSelector->copyTo($selector); } } } # other stuff $selector->insertRule($buffer,"") if $buffer; } $selector = pop @parents if /\}/; $buffer = ""; } # # selectors if ( /\{/ ) { # clearing some buffer data $buffer =~ s/.$//g; $buffer =~ s/^\s*|\s*$//g; # insert the child if ( $buffer ) { push @parents, $selector; if ( $buffer =~ /(.*)\s*\((\@*.*)\)/ and $buffer !~ /^.*[:].*\(/ ) { my $function = $1; my $vars = $2; $function =~ s/^\s*|\s*$//g; $selector = $selector->insertFunction($function, \@parents); my @vars = $vars =~ /\,/ ? split(/\s*\,\s*/, $vars) : ( $vars ); for my $var ( @vars ) { next if !$var; my ($variable, $value) = split(/\s*\:\s*/, $var); $variable =~ s/^\@//; $selector->insertVariable($variable, $value); } } else { $selector = $selector->insertChild($buffer, \@parents); } } $buffer = ""; } # # # if ( /\"/ or /\'/ ) { $mode = "skip"; $stop = $_ }; if ( /\(/ ) { $mode = "skip"; $stop = ")" }; if ( $lastChar =~ /\// and /\// ) { $mode = "delete"; $stop = "\n"; $buffer =~ s/..$// } if ( $lastChar =~ /\// and /\*/ ) { $mode = "delete"; $stop = "*/"; $buffer =~ s/..$// }; $lastChar = $_; } return $styles->dump(); } 1; =head1 NAME CSS::LESSp - LESS for perl. Parse .less files and returns valid css (lesscss.org for more info about less files) =head1 SYNOPSIS use CSS::LESSp; my $buffer; open(IN, "file.less"); for ( ) { $buffer .= $_ }; close(IN); my @css = CSS::LESSp->parse($buffer); print join("", @css); or you could simply use the lessp.pl tool in the package $ lessp.pl css.less > css.css =head1 DESCRIPTION This module is designed to parse and compile .less files in to .css files. About the documentation and syntax of less files please visit lesscss.org =head1 DIFFERENCE WITH THE ORIGINAL LESS FOR RUBY What is the benefits of LESS for perl ... It's extremely fast : # time ./lessp.pl big.less > big.css real 0m2.198s user 0m2.174s sys 0m0.020s # time lessc big.less big.css real 0m18.805s user 0m18.437s sys 0m0.184s =head1 METHODS =head3 parse Main parse method, returns array of the css file =head3 copyFunction =head3 copyTo =head3 dump =head3 getSelector =head3 getValue =head3 getVariable =head3 insertChild =head3 insertFunction =head3 insertRule =head3 insertVariable =head3 isFunction =head3 new =head3 process =head1 BUGS a ) You can not import other less files ... You can't do this @import url('/other.less') It might be added in future versions b ) You can not use hsl as a color You can't do this color: hsl(125,125,125); All other bugs should be reported via L or L. =head1 AUTHOR Ivan Drinchev =head1 CONTRIBUTORS People who've helped with this project : Michael Schout =head1 COPYRIGHT AND LICENSE Copyright (c) 2010. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut libcss-lessp-perl-0.86/script/000077500000000000000000000000001223545707100163245ustar00rootroot00000000000000libcss-lessp-perl-0.86/script/lessp.pl000077500000000000000000000004211223545707100200070ustar00rootroot00000000000000#!/usr/bin/perl use warnings; use strict; use CSS::LESSp; my $file = $ARGV[0]; die "you must specify file" if !$file; my $buffer; open(IN, $file); for ( ) { $buffer .= $_ }; close(IN); my @css = CSS::LESSp->parse($buffer); print join("", @css); libcss-lessp-perl-0.86/t/000077500000000000000000000000001223545707100152635ustar00rootroot00000000000000libcss-lessp-perl-0.86/t/01-loads.t000066400000000000000000000001131223545707100167630ustar00rootroot00000000000000use strict; use Test::More tests=>1; BEGIN { use_ok( 'CSS::LESSp' ); } libcss-lessp-perl-0.86/t/02-parse.t000066400000000000000000000020251223545707100170000ustar00rootroot00000000000000use strict; use warnings; use IO::File; use Test::More; use CSS::LESSp; ############################################################################### # figure out how many JS files we're going to run through for testing my @files = ; plan tests => scalar @files; ############################################################################### # test each of the JS files in turn foreach my $file (@files) { (my $min_file = $file) =~ s/\.less$/\.css/; my $str = slurp( $file ); my $min = slurp( $min_file ); my @res = CSS::LESSp->parse( $str ); is( join("",@res), $min, $file ); } ############################################################################### # HELPER METHOD: slurp in contents of file to scalar. ############################################################################### sub slurp { my $filename = shift; my $fin = IO::File->new( $filename, '<' ) || die "can't open '$filename'; $!"; my $str = join('', <$fin>); $fin->close(); chomp( $str ); return $str; } libcss-lessp-perl-0.86/t/less/000077500000000000000000000000001223545707100162315ustar00rootroot00000000000000libcss-lessp-perl-0.86/t/less/css-3.css000066400000000000000000000016151223545707100176760ustar00rootroot00000000000000 .comma-delimited { background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); text-shadow: -1px -1px 1px red, 6px 5px 5px yellow; -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; } @font-face { font-family: Headline; src: local(Futura-Medium), url(fonts.svg#MyGeometricModern) format("svg"); } .other { -moz-transform: translate(0, 11em) rotate(-90deg); } p:not([class*="lead"]) { color: black; } input[type="text"].class#id[attr=32]:not(1) { color: white; } div#id.class[a=1][b=2].class:not(1) { color: white; } ul.comma > li:not(:only-child)::after { color: white; } ol.comma > li:nth-last-child(2)::after { color: white; } li:nth-child(4n+1), li:nth-child(-5n), li:nth-child(n+1), li:nth-child(-n+2) { color: white; } a[href^="http://"] { color: black; } a[href$="http://"] { color: black; } p::before { color: black; } libcss-lessp-perl-0.86/t/less/css-3.less000066400000000000000000000016631223545707100200570ustar00rootroot00000000000000.comma-delimited { background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg); text-shadow: -1px -1px 1px red, 6px 5px 5px yellow; -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; } @font-face { font-family: Headline; src: local(Futura-Medium), url(fonts.svg#MyGeometricModern) format("svg"); } .other { -moz-transform: translate(0, 11em) rotate(-90deg); } p:not([class*="lead"]) { color: black; } input[type="text"].class#id[attr=32]:not(1) { color: white; } div#id.class[a=1][b=2].class:not(1) { color: white; } ul.comma > li:not(:only-child)::after { color: white; } ol.comma > li:nth-last-child(2)::after { color: white; } li:nth-child(4n+1), li:nth-child(-5n), li:nth-child(n+1), li:nth-child(-n+2) { color: white; } a[href^="http://"] { color: black; } a[href$="http://"] { color: black; } p::before { color: black; } libcss-lessp-perl-0.86/t/less/css.css000066400000000000000000000031451223545707100175360ustar00rootroot00000000000000 div { color: black; } div { width: 99%; } * { min-width: 45em; } h1, h2 > a > p, h3 { color: none; } div.class { color: blue; } div#id { color: green; } .class#id { color: purple; } .one.two.three { color: grey; } @media print { font-size: 3em; } @media screen { font-size: 10px; } @font-face { font-family: 'Garamond Pro'; src: url("/fonts/garamond-pro.ttf"); } a:hover, a:link { color: #999999; } p, p:first-child { text-transform: none; } q:lang(no) { quotes: none; } p + h1 { font-size: 2.2em; } input[type="text"] { font-weight: normal; } h2[title] { font-size: 100%; } [disabled] { color: transparent; } #shorthands { border: 1px solid #000000; font: 12px/16px Arial; margin: 1px 0; padding: 0 auto; background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; } #more-shorthands { margin: 0; padding: 1px 0 2px 0; font: normal small/20px 'Trebuchet MS', Verdana, sans-serif; } .misc { -moz-border-radius: 2px; display: -moz-inline-stack; width: .1em; background-color: #009998; background-image: url(images/image.jpg); background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue)); background-color: -webkit-gradient(linear, left top, left bottom, from(#00abeb), to(#ffffff)); margin: ; } .misc .ivan { background-color: -webkit-gradient(linear, left top, right bottom, from(#ffff00), color-stop(0.5, orange), to(#FF0000); } .misc .kamen { background-color: -webkit-gradient(radial,45% 45%,5,60% 60%,40,from(yellow),color-stop(75%, green),to(rgba(255,255,255,0))); } #important { color: red !important; width: 100%!important; height: 20px ! important; } libcss-lessp-perl-0.86/t/less/css.less000066400000000000000000000032441223545707100177140ustar00rootroot00000000000000/* a CSS File */ div { color: black; } div { width: 99%; } * { min-width: 45em; } h1, h2 > a > p, h3 { color: none; } div.class { color: blue; } div#id { color: green; } .class#id { color: purple; } .one.two.three { color: grey; } @media print { font-size: 3em; } @media screen { font-size: 10px; } @font-face { font-family: 'Garamond Pro'; src: url("/fonts/garamond-pro.ttf"); } a:hover, a:link { color: #999; } p, p:first-child { text-transform: none; } q:lang(no) { quotes: none; } p + h1 { font-size: 2.2em; } input[type="text"] { font-weight: normal; } h2[title] { font-size: 100%; } [disabled] { color: transparent; } #shorthands { border: 1px solid #000; font: 12px/16px Arial; margin: 1px 0; padding: 0 auto; background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; } #more-shorthands { margin: 0; padding: 1px 0 2px 0; font: normal small/20px 'Trebuchet MS', Verdana, sans-serif; } .misc { -moz-border-radius: 2px; display: -moz-inline-stack; width: .1em; background-color: #009998; background-image: url(images/image.jpg); background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue)); background-color: -webkit-gradient(linear, left top, left bottom, from(#00abeb), to(#fff)); .ivan { background-color: -webkit-gradient(linear, left top, right bottom, from(#ff0), color-stop(0.5, orange), to(rgb(255, 0, 0)); } .kamen { background-color: -webkit-gradient(radial,45% 45%,5,60% 60%,40,from(yellow),color-stop(75%, green),to(rgba(255,255,255,0))); } margin: ; } #important { color: red !important; width: 100%!important; height: 20px ! important; } libcss-lessp-perl-0.86/t/less/mult-by-zero.css000077500000000000000000000000541223545707100213130ustar00rootroot00000000000000 div { width: 0px; margin: 0 -10px; } libcss-lessp-perl-0.86/t/less/mult-by-zero.less000077500000000000000000000001101223545707100214620ustar00rootroot00000000000000div { width: (10px * 0); margin: 0 (10px * -1); } libcss-lessp-perl-0.86/t/pod.t000066400000000000000000000003561223545707100162360ustar00rootroot00000000000000#!/usr/bin/perl use strict; use warnings; use Test::More; # Ensure a recent version of Test::Pod my $min_tp = 1.22; eval "use Test::Pod $min_tp"; plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; all_pod_files_ok();