1 package LaTeX::TikZ::Scope;
8 LaTeX::TikZ::Scope - An object modeling a TikZ scope or layer.
16 our $VERSION = '0.01';
20 use LaTeX::TikZ::Tools;
26 isa => 'Maybe[ArrayRef[LaTeX::TikZ::Mod::Formatted]]',
28 default => sub { [ ] },
31 sub mods { @{$_[0]->_mods} }
33 has '_mods_cache' => (
35 isa => 'Maybe[HashRef[LaTeX::TikZ::Mod::Formatted]]',
37 default => sub { +{ } },
42 isa => 'LaTeX::TikZ::Scope|Str',
46 my $my_tc = LaTeX::TikZ::Tools::type_constraint(__PACKAGE__);
47 my $ltmf_tc = LaTeX::TikZ::Tools::type_constraint('LaTeX::TikZ::Mod::Formatted');
52 my $cache = $scope->_mods_cache;
55 my $mod = $ltmf_tc->check($_) ? $_ : $ltmf_tc->coerce($_);
57 next if exists $cache->{$tag};
58 $cache->{$tag} = $mod;
59 push @{$scope->_mods}, $mod;
85 my $body = $scope->body;
86 return $scope unless $my_tc->check($body);
88 ->mod ($scope->mods, $body->mods)
93 my $inter = Sub::Name::subname('inter' => sub {
96 my (@left, @common, @right);
99 --$where{$_} for keys %$lh;
100 ++$where{$_} for keys %$rh;
102 while (my ($key, $where) = each %where) {
104 push @left, $lh->{$key};
105 } elsif ($where > 0) {
106 push @right, $rh->{$key};
108 push @common, $rh->{$key};
112 return \@left, \@common, \@right;
116 my ($scope, $str, $rev) = @_;
118 $scope = $scope->flatten;
120 my $body = $scope->body;
121 my @mods = $scope->mods;
123 if ($my_tc->check($str)) {
124 $str = $str->flatten;
126 my ($only_scope, $common, $only_str) = $inter->(
138 ($x, $y) = ($y, $x) if $rev;
145 my ($layer, @clips, @raw_mods);
148 if ($type eq 'clip') {
149 unshift @clips, $_->content;
150 } elsif ($type eq 'layer') {
151 confess("Can't apply two layers in a row") if defined $layer;
152 $layer = $_->content;
154 push @raw_mods, $_->content;
158 my $mods_string = @raw_mods ? ' [' . join(',', @raw_mods) . ']' : undef;
160 if (@raw_mods and $body =~ /^\s*\\draw\b\s*([^\[].*)\s*$/) {
161 $body = "\\draw$mods_string $1\n"; # Has trailing semicolon
162 $mods_string = undef; # Done with mods
166 my $clip = $clips[$_];
167 my $clip_string = "\\clip $clip ;";
168 my $mods_string = ($_ == $#clips and defined $mods_string)
172 \\begin{scope}$mods_string
179 if (not @clips and defined $mods_string) {
182 \\begin{scope}$mods_string
188 if (defined $layer) {
191 \\begin{pgfonlayer}{$layer}
197 $rev ? $str . $body : $body . $str;
200 sub stringify { $_[0]->concat('') }
202 __PACKAGE__->meta->make_immutable;
206 Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.
208 You can contact me by mail or on C<irc.perl.org> (vincent).
212 Please report any bugs or feature requests to C<bug-latex-tikz at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=LaTeX-TikZ>.
213 I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
217 You can find documentation for this module with the perldoc command.
221 =head1 COPYRIGHT & LICENSE
223 Copyright 2010 Vincent Pit, all rights reserved.
225 This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
229 1; # End of LaTeX::TikZ::Scope