Mike South wrote:
> Am I right in thinking that TT does not currently give me easy access to
> this information?

Yes, you're right.  It doesn't.

> How hard would it be for me to subclass Parser or modify the grammar or
> whatever to make it do what I want (or is there a better approach)?

Not hard at all.  You could do something like this:

  package My::Template::Directive;
  use base qw( Template::Directive );

  our $OUTPUT  = '$output .=';
  our $LINEPOS = '$stash->set( tt_char_pos =>   # this should be on one line
                               ($output =~ /\n(.*)$/ ? length($1) + 1 : 1) )';
  sub get {
      my ($class, $expr) = @_;
      return "$LINEPOS; $OUTPUT $expr;";
  }

Note that I've shown $LINEPOS definition split across lines for mailer
friendliness, but it should all be on one line, to keep the Perl line
counting mechanism working as expected.

Then you use the FACTORY option to enable your directive factory:

  my $tt = Template->new( FACTORY => 'My::Template::Directive' );

(alternately, you can just redefine the regular Template::Directive::get()
subroutine if you don't fancy subclassing)

Now all GET directives will set the tt_char_pos variable to the current
output character position after the last newline, before returning the 
requested value from the stash.

e.g. 
  This directive starts at character [% tt_char_pos %]

Generates the following output:
  This directive starts at character 36

While this solves your problem, it would slow down all GET directives
by performing the extra set.  If this is an issue, you could perhaps adopt
a naming convention for variables that require this magic and then examine
$expr in the get() method to see if the $LINEPOS code should be added or not.

Hopefully that gives you some ideas about where to explore next...

Cheers
A


_______________________________________________
templates mailing list
[email protected]
http://lists.template-toolkit.org/mailman/listinfo/templates

Reply via email to