SPUG: multi-line substition, all at once.
Joshua ben Jore
twists at gmail.com
Mon Jun 29 08:29:18 PDT 2009
=email
On Thu, Jun 25, 2009 at 4:25 AM, Jacinta
Richardson<jarich at perltraining.com.au> wrote:
I found I liked your approach quite a bit so I've written this email
as a program for you. Starting off, I'm using your suggestion to be
explicit about my heredoc quoting. What follows is an example of using
single-quoting so I know there's no interpolation.
=cut
use strict;
use warnings;
use Test::More tests => 1;
my $code=<<'__CODE__';
...
: sub hello {
: say "Hello World!";
: }
...
__CODE__
=email
The core regexp is rather simple. I found it nicer to put it into its
own variable so I could go back later and test that it was working
correctly with Test::Regexp. The base regexp just finds a series of
lines starting with some spaces and a colon. The modification work is
delegated to an s{$RX}{ code }e expression. Now that the pattern is
separate, I can pay more attention to each in its own idiom.
=cut
my $RX = qr/(?mx) # allow whitespace and comments, ^ matches some line beginning
# Capture...
(
(?: # A series...
^\ +:[^\n]*\n # of colon marked lines
)+
)
/;
=email
I'll also use Jacinta's no_colon to remove the leading colon markers.
=cut
sub no_colon {
my ( $code ) = @_;
$code =~ s/^ +://mg;
return $code;
}
=email
I added one more function for adding the [code] tags. The point being,
while I was doing all this mucking around, I might as well make the
eventual expression as readable as possible.
=cut
sub code_tag {
my ( $code ) = @_;
"[code]$code\[/$code]";
}
=email
All the work happens in a very small space now and I hope is more
readable. In particular, I learned to use {} bracing for expressions
I'm going to use with /e because then it looks more like normal code
bracing. It's a small hint to the reader to expect code.
=cut
$code =~ s{$RX}{
code_tag(
no_colon(
$1 ));
}e;
=email
Lastly, since I was going to this effort, I wrote a test to check that
I was doing what I expected.
=cut
is( $code, <<'__EXPECTED__' );
...
[code] sub hello {
say "Hello World!";
}
[/code]
...
__EXPECTED__
=email
Cheers,
Josh
=cut
More information about the spug-list
mailing list