package Filter::QuasiLiterate; use strict; use Carp; use Filter::Util::Call; sub import { my $me = { sections => { }, defining => undef, }; filter_add(bless $me); } sub filter { my $me = shift; my $status = filter_read; ($status > 0) or return $status; (/^\s*\#([<>])/ ? (($1 eq '<') ? (/^\s*\#[<>]([a-zA-Z0-9\-.\/: ]+)(\>?)(?:\#.*)?$/ ? (($2 eq '>') ? (exists $me->{sections}->{$1} ? ($_ = $me->{sections}->{$1}) : (croak "QuasiLiterate filter: chunk does not exist: \"$1\"") ) : (push @ {$me->{defining}}, (((scalar @ {$me->{defining}}) ? $me->{defining}->[-1] . '.' : '') . $1)) ) : (croak "QuasiLiterate filter: invalid command: \"$_\"") ) : (pop @ {$me->{defining}}) ) : ((scalar @ {$me->{defining}})? do { foreach my $def (@ {$me->{defining}}) { $me->{sections}->{$def} .= $_ } $_ = ''; } : ())); return $status; } =head1 NAME Filter::QuasiLiterate =head1 SYNOPSIS use Filter::QuasiLiterate; # # # etc. if ($Run) { # } else { print <<'//'; # Or some other string you're sure won't be a # line in foo_doc # // } # gork; #> # # Gives bork then gork # # Gives bork by itself # # # # # Gives xyzzy then fizzy =head1 DESCRIPTION Filter::QuasiLiterate allows you to do quasi-literate programming, using chunks of code / documentation / comments / whatever which can get reused, shuffled arbitrarily, and/or disused. Chunks can also be defined in pieces, and nested. QuasiLiterate commands are indicated by lines with any amount of whitespace, followed by # and then either < or >. They are terminated by newline or #. Chunk names may contain any of the characters a-z, A-Z, 0-9, or [-./: ]. # stops defining the innermost chunk. Note that if a nested chunk is added to explicitly, i.e. with a specified name of outer.inner, the outer chunk will I be added to. # (note the >) includes the contents of a previously defined chunk at the current position. =head1 BUGS There should be more options. Chunks can't be used before their definitions. Documentation could be I better. There are undoubtedly more bugs lurking here somewhere. =head1 SEE ALSO This is the mandatory SEE ALSO section. There is no useful information here. :-) =cut 1; __END__