[Templates-cvs] cvs commit: TT3/lib/Template/Tag Directive.pm

cvs@template-toolkit.org cvs@template-toolkit.org
Mon, 15 Nov 2004 19:33:20 +0000


cvs         04/11/15 19:33:20

  Modified:    lib/Template/Tag Directive.pm
  Log:
  * some fixes to allow the parser to correctly identify the end of an open tag,
    particularly in comments
  
  * some of what is implemented in here has since been re-implemented in the parser
    init() method and can be removed from here.
  
  Revision  Changes    Path
  1.5       +40 -13    TT3/lib/Template/Tag/Directive.pm
  
  Index: Directive.pm
  ===================================================================
  RCS file: /template-toolkit/TT3/lib/Template/Tag/Directive.pm,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Directive.pm	2004/11/12 18:36:03	1.4
  +++ Directive.pm	2004/11/15 19:33:20	1.5
  @@ -16,7 +16,7 @@
   #   modify it under the same terms as Perl itself.
   #
   # REVISION
  -#   $Id: Directive.pm,v 1.4 2004/11/12 18:36:03 abw Exp $
  +#   $Id: Directive.pm,v 1.5 2004/11/15 19:33:20 abw Exp $
   #
   #========================================================================
   
  @@ -29,7 +29,7 @@
   use Template::Tag;
   use base qw( Template::Tag );
   
  -our $VERSION = sprintf("%d.%02d", q$Revision: 1.4 $ =~ /(\d+)\.(\d+)/);
  +our $VERSION = sprintf("%d.%02d", q$Revision: 1.5 $ =~ /(\d+)\.(\d+)/);
   our $DEBUG   = 0 unless defined $DEBUG;
   our $ERROR   = '';
   our $PARSER  = 'Template::Parser';
  @@ -37,7 +37,7 @@
   our $WHITESPACE = $Template::Parser::WSPACE 
       unless defined $WHITESPACE;
   
  -our $DELIMITER = qr/ (?: $WHITESPACE ; $WHITESPACE )+ /ox 
  +our $DELIMITER = qr/ (?: $WHITESPACE ; $WHITESPACE )+ /sox 
       unless defined $DELIMITER;
   
   our $TAG_STYLES = {
  @@ -80,7 +80,7 @@
       side_effect => 1,
       multi_dirs  => 1,
       comment     => 1,
  -    ignore      => $WHITESPACE,
  +    ignore      => $WHITESPACE,     # TODO: remove this
       delimiter   => $DELIMITER,
   } unless defined $TAG;
   
  @@ -140,28 +140,55 @@
       # save match info locally to make protect re-entrancy
       local $self->{ match } = $match;
       $match->{ lines  } = 0;
  -#   $match->{ ignore } = $ignore;
  -#   $match->{ end    } = $endtag;
  +    $match->{ ignore } = $ignore;
  +    $match->{ end    } = $endtag;
   
       # we must have an end tag defined
       return $self->error('no end token defined for tag') 
           unless defined $endtag and length $endtag;
   
       # compile regex to match end token and any flag that comes
  -    # immediately before it.  any leading whitespace is ignored, but
  +    # immediately before it.  Any leading whitespace is ignored, but
       # we keep an eye open for any other text coming before the end
  -    # flag/token that shouldn't be there (unless the entire directive
  -    # is commented out, in which case we ignore it
  +    # flag/token that shouldn't be there.  We also compile a regex 
  +    # which looks ahead for the end tag (no intermediate text) but 
  +    # doesn't consume it (a negative width positive lookahead assertion).
  +    # This is set in the $match hash for the parser to use to detect the 
  +    # end of a tag
  +    
       my $regex = $self->{ end_regex } ||= do {
           $self->debug("compiling new end_regex ($endtag)\n") if $DEBUG;
           $endtag = ref $endtag eq 'Regexp' ? $endtag : quotemeta($endtag);
  +
  +        # TODO: don't need this - now done in the parser
  +        $ignore = qr/        # compile regex to ignore comments, whitespace, etc.
  +            \s*              # ignore any leading whitespace
  +            (?:              # repeat block for multiple comments
  +              \# .*?         # capture everything after '#', but non-greedily
  +              (?:            # group of end tokens to terminate comment, either:
  +                \n           # a newline character, which is consumed
  +               |             # or:
  +                (?=          # look ahead for, but don't consume
  +                  [-=+]?     # any optional closing flag
  +                  $endtag    # token or regex marking end of tag
  +                ) 
  +              )
  +              \s*            # trailing whitespace after comment
  +            )*
  +            /sx;
  +
  +        $self->{ match_end_regex } = qr/ (?= \G $ignore [-=+]? $endtag ) /sx;
  +        $self->{ match_ignore    } = qr/ \G $ignore /sx;
           qr/ \G $ignore (.*?) $ignore ([-=+])? ($endtag) /sx;
       };
  +    $match->{ end_regex } = $self->{ match_end_regex };
  +    $match->{ ignore } = $self->{ ignore };
   
       # check for opening comment/chomp flag and remove leading whitespace
       # or anything else deemed ignorable
  -    $$textref =~ / \G ([-=+\#])? $ignore /cogsx;
  +    $$textref =~ / \G ([-=+\#])? /cgsx;
       $match->{ start_flag } = $flag = $1 || '';
  +    $$textref =~ / \G $ignore /sx;
   
       # TODO: other options to enable/disable flags: comment_flag,
       # chomp_flag, etc?
  @@ -255,8 +282,8 @@
       my ($directive, $start_pos, $end_pos, $substr, $sublines);
       my $lines = 0;
   
  -    my $parser = $self->{ parser } 
  -        || $match->{ parser }
  +    my $parser = $match->{ parser } 
  +        ||= $self->{ parser }
   #        || $handler->parser()
           || return $self->error('no parser defined for directive tag');
   
  @@ -405,7 +432,7 @@
   
   =head1 VERSION
   
  -$Revision: 1.4 $
  +$Revision: 1.5 $
   
   =head1 COPYRIGHT