X-Git-Url: http://git.vpit.fr/?a=blobdiff_plain;f=lib%2FLaTeX%2FTikZ%2FScope.pm;h=8edad60f9d67019ebe1149ba72b06d603faf812e;hb=f54cadb836315572aa2c4bcb16f221da1687df7a;hp=05308ddb07a067041770ff797aad66eedc28815b;hpb=93bfe14caec156fc11587863a486220b986b6b2e;p=perl%2Fmodules%2FLaTeX-TikZ.git diff --git a/lib/LaTeX/TikZ/Scope.pm b/lib/LaTeX/TikZ/Scope.pm index 05308dd..8edad60 100644 --- a/lib/LaTeX/TikZ/Scope.pm +++ b/lib/LaTeX/TikZ/Scope.pm @@ -9,11 +9,11 @@ LaTeX::TikZ::Scope - An object modeling a TikZ scope or layer. =head1 VERSION -Version 0.01 +Version 0.02 =cut -our $VERSION = '0.01'; +our $VERSION = '0.02'; use Sub::Name (); @@ -21,6 +21,12 @@ use LaTeX::TikZ::Tools; use Any::Moose; +=head1 ATTRIBUTES + +=head2 C + +=cut + has '_mods' => ( is => 'ro', isa => 'Maybe[ArrayRef[LaTeX::TikZ::Mod::Formatted]]', @@ -37,6 +43,10 @@ has '_mods_cache' => ( default => sub { +{ } }, ); +=head2 C + +=cut + has '_body' => ( is => 'rw', isa => 'LaTeX::TikZ::Scope|ArrayRef[Str]', @@ -48,13 +58,20 @@ my $ltmf_tc = LaTeX::TikZ::Tools::type_constraint('LaTeX::TikZ::Mod::Formatted' my $_body_tc = __PACKAGE__->meta->find_attribute_by_name('_body') ->type_constraint; +=head1 METHODS + +=head2 C + +=cut + sub mod { my $scope = shift; my $cache = $scope->_mods_cache; for (@_) { - my $mod = $ltmf_tc->check($_) ? $_ : $ltmf_tc->coerce($_); + my $mod = $ltmf_tc->coerce($_); + $ltmf_tc->assert_valid($mod); my $tag = $mod->tag; next if exists $cache->{$tag}; $cache->{$tag} = $mod; @@ -64,6 +81,10 @@ sub mod { $scope; } +=head2 C + +=cut + sub body { my $scope = shift; @@ -76,9 +97,13 @@ sub body { } use overload ( - '.' => \&concat, + '@{}' => 'dereference', ); +=head2 C + +=cut + sub flatten { my ($scope) = @_; @@ -113,6 +138,10 @@ my $inter = Sub::Name::subname('inter' => sub { return \@left, \@common, \@right; }); +=head2 C + +=cut + sub instantiate { my ($scope) = @_; @@ -163,49 +192,86 @@ sub instantiate { return @body; } -sub concat { - my ($left, $right, $rev) = @_; +=head2 C + +=cut + +sub dereference { [ $_[0]->instantiate ] } + +=head2 C - $_body_tc->assert_valid($right); +=cut - $left = $left->flatten; +sub fold { + my ($left, $right, $rev) = @_; my (@left, @right); - if ($my_tc->check($right)) { - $right = $right->flatten; - - my ($only_left, $common, $only_right) = $inter->( - $left->_mods_cache, - $right->_mods_cache, - ); - - if (@$common) { - my $x = $left->new - ->mod(@$only_left) - ->body($left->_body); - my $y = $left->new - ->mod(@$only_right) - ->body($right->_body); - ($x, $y) = ($y, $x) if $rev; - return $left->new - ->mod(@$common) - ->body($x . $y); + if ($my_tc->check($left)) { + $left = $left->flatten; + + if ($my_tc->check($right)) { + $right = $right->flatten; + + my ($only_left, $common, $only_right) = $inter->( + $left->_mods_cache, + $right->_mods_cache, + ); + + my $has_different_layers; + for (@$only_left) { + if ($_->type eq 'layer') { + $has_different_layers = 1; + last; + } + } + unless ($has_different_layers) { + for (@$only_right) { + if ($_->type eq 'layer') { + $has_different_layers = 1; + last; + } + } + } + + if (!$has_different_layers and @$common) { + my $x = $left->new + ->mod(@$only_left) + ->body($left->_body); + my $y = $left->new + ->mod(@$only_right) + ->body($right->_body); + return $left->new + ->mod(@$common) + ->body(fold($x, $y, $rev)); + } else { + @right = $right->instantiate; + } } else { - @right = $right->instantiate; + $_body_tc->assert_valid($right); + @right = @$right; } + + @left = $left->instantiate; } else { - @right = @$right; + if ($my_tc->check($right)) { + return fold($right, $left, 1); + } else { + $_body_tc->assert_valid($_) for $left, $right; + @left = @$left; + @right = @$right; + } } - @left = $left->instantiate; - - $left->new - ->body($rev ? [ @right, @left ] : [ @left, @right ]); + $rev ? [ @right, @left ] : [ @left, @right ]; } __PACKAGE__->meta->make_immutable; +=head1 SEE ALSO + +L. + =head1 AUTHOR Vincent Pit, C<< >>, L.