0: package Filter::QuasiLiterate;
1: use strict;
2: use Carp;
3: use Filter::Util::Call;
4:
5: sub import
6: {
7: my $me =
8: {
9: sections => { },
10: defining => undef,
11: };
12: filter_add(bless $me);
13: }
14:
15: sub filter
16: {
17: my $me = shift;
18: my $status = filter_read;
19: ($status > 0) or return $status;
20:
21: (/^\s*\#([<>])/ ?
22: (($1 eq '<') ?
23: (/^\s*\#[<>]([a-zA-Z0-9\-.\/: ]+)(\>?)(?:\#.*)?$/ ?
24: (($2 eq '>') ?
25: (exists $me->{sections}->{$1} ?
26: ($_ = $me->{sections}->{$1}) :
27: (croak "QuasiLiterate filter: chunk does not exist: \"$1\"")
28: ) :
29: (push @ {$me->{defining}},
30: (((scalar @ {$me->{defining}}) ? $me->{defining}->[-1] . '.' : '')
31: . $1))
32: ) :
33: (croak "QuasiLiterate filter: invalid command: \"$_\"")
34: ) :
35: (pop @ {$me->{defining}})
36: ) :
37: ((scalar @ {$me->{defining}})? do
38: {
39: foreach my $def (@ {$me->{defining}}) { $me->{sections}->{$def}
40: .= $_ }
41: $_ = '';
42: } :
43: ()));
44:
45: return $status;
46: }
47:
48: =head1 NAME
49:
50: Filter::QuasiLiterate
51:
52: =head1 SYNOPSIS
53:
54: use Filter::QuasiLiterate;
55: #<foo_code
56: # Put code that does foo here.
57: #>
58: #<foo_doc
59: It then does foo, by first calling bar...
60: #>
61: # etc.
62:
63: if ($Run)
64: {
65: #<foo_code>
66: }
67: else
68: {
69: print <<'//'; # Or some other string you're sure won't be a
70: # line in foo_doc
71: #<foo_doc>
72: //
73: }
74: #<nested-section
75: #<bork
76: # now in nested-section.bork
77: bork;
78: #>
79: gork;
80: #>
81:
82: #<nested-section> # Gives bork then gork
83: #<nested-section.bork> # Gives bork by itself
84:
85: #<blorple
86: xyzzy;
87: #>
88: #<baz
89: rumple;
90: #>
91: #<blorple
92: fizzy;
93: #>
94: #<blorple> # Gives xyzzy then fizzy
95:
96:
97: =head1 DESCRIPTION
98:
99: Filter::QuasiLiterate allows you to do quasi-literate programming, using
100: chunks of code / documentation / comments / whatever which can get reused,
101: shuffled arbitrarily, and/or disused. Chunks can also be defined in pieces,
102: and nested. QuasiLiterate commands are indicated by lines with any amount
103: of whitespace, followed by # and then either < or >. They are terminated by
104: newline or #. Chunk names may contain any of the characters a-z, A-Z, 0-9,
105: or [-./: ]. #<chunk-name will start defining a chunk, or adding to it if
106: a chunk with that name already exists. If a chunk is already
107: being defined, the new chunk will have the name outer.inner, where outer and
108: inner are placeholders for the outer and inner chunks. Anything inside the
109: inner chunk is added to both the outer and inner chunks. Chunks can be
110: nested to an infinite (theoretically) number of levels. #> stops defining
111: the innermost chunk. Note that if a nested chunk is added to explicitly,
112: i.e. with a specified name of outer.inner, the outer chunk will I<not> be
113: added to. #<chunk-name> (note the >) includes the contents
114: of a previously defined chunk at the current position.
115:
116: =head1 BUGS
117:
118: There should be more options. Chunks can't be used before their definitions.
119: Documentation could be I<much> better.
120:
121: There are undoubtedly more bugs lurking here somewhere.
122:
123: =head1 SEE ALSO
124:
125: This is the mandatory SEE ALSO section. There is no useful information here. :-)
126:
127: =cut
128:
129: 1;
130:
131: __END__ In reply to Filter::QuasiLiterate by premchai21
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |