- (my $pm = $target) =~ s{::}{/}g;
- $pm .= '.pm';
- require $pm;
-
- my $meta = find_meta($target);
- Carp::confess("No meta object associated with target $target")
- unless defined $meta;
- my $is_role = $meta->isa(any_moose('Meta::Role'));
-
- my $is_set;
- if (does_role($target, 'LaTeX::TikZ::Set')) {
- $is_set = 1;
- } elsif (does_role($target, 'LaTeX::TikZ::Mod')) {
- $is_set = 0;
- } else {
- Carp::confess("Target $target is neither a set nor a mod");
- }
-
- Carp::confess("Invalid handler for rule spec $spec")
- unless defined $handler and ref $handler eq 'CODE';
-
- return [ $target, $handler, $replace, $is_role, $is_set ];
- });
-
- $insert_rule = Sub::Name::subname('insert_rule' => sub {
- my ($rule, $list, $overwrite) = @_;
-
- my ($target, $replace, $is_role) = @{$rule}[0, 2, 3];
-
- if ($replace) {
- my @remove;
-
- for my $i (0 .. $#$list) {
- my $old_target = $list->[$i]->[0];
- if ($is_role ? does_role($old_target, $target)
- : $old_target->isa($target)) {
- if (defined $rule) {
- splice @$list, $i, 1, $rule;
- $rule = undef;
- } else {
- push @remove, $i;
- }
- }
- }
-
- my $shift;
- for (@remove) {
- splice @$list, $_ - $shift, 1;
- ++$shift;
- }
- return 1 unless defined $rule;
-
- } else { # Replace only an existent rule
-
- for my $i (0 .. $#$list) {
- my $old_target = $list->[$i]->[0];
- if ($old_target eq $target) {
- Carp::confess("Default rule already defined for target $target")
- unless $overwrite;
- splice @$list, $i, 1, $rule;
- return 1;
- }
- }
- }
-
- push @$list, $rule;
- return 0;