Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[WIP] Implement new features in libsass 3.2 #10

Merged
merged 3 commits into from
Apr 27, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Build.PL
Original file line number Diff line number Diff line change
Expand Up @@ -211,13 +211,12 @@ my %config = (
extend.cpp file.cpp output.cpp parser.cpp prelexer.cpp emitter.cpp position.cpp
sass.cpp sass_interface.cpp sass_functions.cpp sass_values.cpp sass_context.cpp
source_map.cpp to_c.cpp to_string.cpp units.cpp utf8_string.cpp util.cpp cssize.cpp
contextualize_eval.cpp listize.cpp lexer.cpp
) ]
},
config => { ld => 'c++' }, # Need to link with a C++ linker since libsass is C++ (even though the .xs file is not)
);

$config{'requires'}->{'Win32::Unicode::File'} = 0 if ($^O eq "MSWin32");

my $builder = Module::Build::Custom->new(%config);

$builder->create_build_script();
12 changes: 12 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
CSS::Sass (3.2.0)

* Update to latest libsass release (3.2.0)
* Add options for remaining output styles
* Add indent and linefeed config options
* Add benchmark option to command line tool
* Add watcher option to recompile on changes
* Refactor for libsass context option initializing
* Expose `resolve_file` function on the C-API
* Add experimental API for multiple importers
* Add highly experimental API for custom headers

CSS::Sass (3.1.0)

* Updates to latest libsass version (3.1.0)
Expand Down
50 changes: 46 additions & 4 deletions bin/psass.pl
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
use File::Slurp qw(write_file);

# load constants from libsass
use CSS::Sass qw(SASS_STYLE_EXPANDED);
use CSS::Sass qw(SASS_STYLE_NESTED);
use CSS::Sass qw(SASS_STYLE_COMPRESSED);
use CSS::Sass qw(SASS_STYLE_COMPACT);
use CSS::Sass::Watchdog qw(start_watchdog);

####################################################################################################
Expand All @@ -39,6 +41,7 @@

# init options
my $watchdog;
my $benchmark;
my $precision;
my $output_file;
my $output_style;
Expand All @@ -60,11 +63,18 @@ sub version {
my @plugin_paths;
my @include_paths;

# output styles
my $indent = " ";
my $linefeed = "auto";

# get options
GetOptions (
'help|h' => sub { pod2usage(1); },
'watch|w' => \ $watchdog,
'watch|w!' => \ $watchdog,
'version|v' => \ &version,
'benchmark|b!' => \ $benchmark,
'indent=s' => \ $indent,
'linefeed=s' => \ $linefeed,
'precision|p=s' => \ $precision,
'output-file|o=s' => \ $output_file,
'output-style|t=s' => \ $output_style,
Expand All @@ -84,15 +94,34 @@ sub version {
# parse string to constant
elsif ($output_style =~ m/^n/i)
{ $output_style = SASS_STYLE_NESTED }
elsif ($output_style =~ m/^c/i)
elsif ($output_style =~ m/^compa/i)
{ $output_style = SASS_STYLE_COMPACT }
elsif ($output_style =~ m/^compr/i)
{ $output_style = SASS_STYLE_COMPRESSED }
elsif ($output_style =~ m/^e/i)
{ $output_style = SASS_STYLE_EXPANDED }
# die with message if style is unknown
else { die "unknown output style: $output_style" }

# resolve linefeed options
if ($linefeed =~ m/^a/i)
{ $linefeed = undef; }
elsif ($linefeed =~ m/^w/i)
{ $linefeed = "\r\n"; }
elsif ($linefeed =~ m/^[u]/i)
{ $linefeed = "\n"; }
elsif ($linefeed =~ m/^[n]/i)
{ $linefeed = ""; }
# die with message if linefeed type is unknown
else { die "unknown linefeed type: $linefeed" }

# do we have output path in second arg?
if (defined $ARGV[1] && $ARGV[1] ne '-')
{ $output_file = $ARGV[1]; }

# check if the benchmark module is available
if ($benchmark && ! eval "use Benchmark; 1" )
{ die "Error loading Benchmark module\n", $@; }

####################################################################################################
# get sass standard option list
Expand All @@ -102,6 +131,8 @@ ()
{
return (
dont_die => $watchdog,
indent => $indent,
linefeed => $linefeed,
precision => $precision,
output_path => $output_file,
output_style => $output_style,
Expand All @@ -128,6 +159,9 @@ ()
# variables
my ($css, $err, $stats);

# get benchmark stamp before compiling
my $t0 = $benchmark ? Benchmark->new : 0;

# open filehandle if path is given
if (defined $ARGV[0] && $ARGV[0] ne '-')
{
Expand All @@ -143,6 +177,11 @@ ()
);
}

# get benchmark stamp after compiling
my $t1 = $benchmark ? Benchmark->new : 0;
# only print benchmark result when module is available
if ($benchmark) { print timestr(timediff($t1, $t0)), "\n"; }

# process return status values
if (defined $css)
{
Expand Down Expand Up @@ -195,16 +234,19 @@ =head1 SYNOPSIS
-v, --version print version
-h, --help print this help
-w, --watch start watchdog mode
-p, --precision precision for float output
-p, --precision=int precision for float output
--indent=string set indent string used for output
--linefeed=type linefeed used for output [auto|unix|win|none]
-o, --output-file=file output file to write result to
-t, --output-style=style output style [nested|compressed]
-t, --output-style=style output style [expanded|nested|compressed|compact]
-L, --plugin-path=path plugin load path (repeatable)
-I, --include-path=path sass include path (repeatable)
-c, --source-comments enable source debug comments
-e, --source-map-embed embed source-map in mapping url
-s, --source-map-contents include original contents
-m, --source-map-file=file create and write source-map to file
--no-source-map-url omit sourceMappingUrl from output
--benchmark print benchmark for compilation time

=head1 OPTIONS

Expand Down
121 changes: 85 additions & 36 deletions lib/CSS/Sass.pm
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ require XSLoader;
XSLoader::load('CSS::Sass', $VERSION);
require CSS::Sass::Type;

sub new {
sub new
{
my ($class, %options) = @_;
# Ensure initial sub structures on options
$options{plugin_paths} = [] unless exists $options{plugin_paths};
Expand All @@ -66,64 +67,100 @@ sub new {
bless { options => \%options }, $class;
};

sub options {
sub options
{
shift->{options}
}

sub last_error {
sub last_error
{
my ($self) = @_;
$self->{last_error}
}

sub sass_compile {
my @path_types = (
'plugin_paths',
'include_paths'
);

# directory delimiter according to platform
my $dir_delim = $^O eq 'MSWin32' ? ';' : ':';

# normalize option hash
my $normalize_options = sub
{
my ($options) = @_;
# gather all functions
# they need to be hashes
my %functions =
(
%{$options->{'functions'} || {}},
%{$options->{'sass_functions'} || {}}
);
# create functions array
# help the c code a little
my @functions = map { [
$_, $functions{$_}
] } keys %functions;
# gather all importers
# they need to be arrays
my @importers =
map {
ref($_) eq "ARRAY" ?
$_ : [ $_, 0 ];
}
grep { defined }
(
$options->{'importer'},
@{$options->{'importers'} || []},
@{$options->{'sass_importers'} || []}
);
# gather all paths strings
foreach my $type (@path_types)
{
$options->{$type} = join $dir_delim,
map { split $dir_delim, $_ }
@{$options->{$type} || []};
}
# now normalize the original hash
$options->{'functions'} = \@functions;
$options->{'importers'} = \@importers;
# remove importer from options
# it is now included in importers
delete $options->{'importer'};
# return pointer
return $options;
};

sub sass_compile
{
my ($sass_code, %options) = @_;
no warnings 'uninitialized';
my $r = compile_sass($sass_code, { %options,
# Override sass_functions with the arrayref of arrayrefs that the XS expects.
!$options{sass_functions} ? ()
: (sass_functions => [ map { [ $_ => $options{sass_functions}->{$_} ]
} keys %{$options{sass_functions}} ]),
# Override include_paths with a ':' separated list
!$options{include_paths} ? ()
: (include_paths => join($^O eq 'MSWin32' ? ';' : ':',
@{$options{include_paths}})),
# Override plugin_paths with a ':' separated list
!$options{plugin_paths} ? ()
: (plugin_paths => join($^O eq 'MSWin32' ? ';' : ':',
@{$options{plugin_paths}})),
});
$normalize_options->(\%options);
my $r = compile_sass($sass_code, \%options);
wantarray ? ($r->{output_string}, $r->{error_message}, $r) : $r->{output_string}
}

sub sass_compile_file {
sub sass_compile_file
{
my ($input_path, %options) = @_;
no warnings 'uninitialized';
my $r = compile_sass_file($input_path, { %options,
# Override sass_functions with the arrayref of arrayrefs that the XS expects.
!$options{sass_functions} ? ()
: (sass_functions => [ map { [ $_ => $options{sass_functions}->{$_} ]
} keys %{$options{sass_functions}} ]),
# Override include_paths with a ':' separated list
!$options{include_paths} ? ()
: (include_paths => join($^O eq 'MSWin32' ? ';' : ':',
@{$options{include_paths}})),
# Override plugin_paths with a ':' separated list
!$options{plugin_paths} ? ()
: (plugin_paths => join($^O eq 'MSWin32' ? ';' : ':',
@{$options{plugin_paths}})),
});
$normalize_options->(\%options);
my $r = compile_sass_file($input_path, \%options);
wantarray ? ($r->{output_string}, $r->{error_message}, $r) : $r->{output_string}
}

sub compile {
sub compile
{
my ($self, $sass_code) = @_;
my ($compiled, $stats);
($compiled, $self->{last_error}, $stats) = sass_compile($sass_code, %{$self->options});
croak $self->{last_error} if $self->{last_error} && !$self->options->{dont_die};
wantarray ? ($compiled, $stats) : $compiled
}

sub compile_file {
sub compile_file
{
my ($self, $sass_file) = @_;
my ($compiled, $stats);
($compiled, $self->{last_error}, $stats) = sass_compile_file($sass_file, %{$self->options});
Expand Down Expand Up @@ -283,6 +320,18 @@ C<undef>, but never both.
The default is C<SASS_STYLE_NESTED>. Set to C<SASS_STYLE_COMPRESSED> to
eliminate all whitespace (for your production CSS).

=item C<precision>

Set the floating point precision for output.

=item C<linefeed>

Set the linefeed string used for css output.

=item C<indentation>

Set the indentation string used for css output.

=item C<source_comments>

Set to C<true> to get extra comments in the output, indicating what input
Expand Down Expand Up @@ -482,7 +531,7 @@ L<The CSS::Sass Home Page|https://github.com/sass/perl-libsass>

=head1 AUTHOR

David Caldwell E<lt>david@porkrind.orgE<gt>
David Caldwell E<lt>david@porkrind.orgE<gt>
Marcel Greter E<lt>perl-libsass@ocbnet.chE<gt>

=head1 LICENSE
Expand Down
Loading