line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
2
|
|
|
|
|
|
|
package Pod::Loom::Template; |
3
|
|
|
|
|
|
|
# |
4
|
|
|
|
|
|
|
# Copyright 2009 Christopher J. Madsen |
5
|
|
|
|
|
|
|
# |
6
|
|
|
|
|
|
|
# Author: Christopher J. Madsen <perl@cjmweb.net> |
7
|
|
|
|
|
|
|
# Created: 6 Oct 2009 |
8
|
|
|
|
|
|
|
# |
9
|
|
|
|
|
|
|
# This program is free software; you can redistribute it and/or modify |
10
|
|
|
|
|
|
|
# it under the same terms as Perl itself. |
11
|
|
|
|
|
|
|
# |
12
|
|
|
|
|
|
|
# This program is distributed in the hope that it will be useful, |
13
|
|
|
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
14
|
|
|
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either the |
15
|
|
|
|
|
|
|
# GNU General Public License or the Artistic License for more details. |
16
|
|
|
|
|
|
|
# |
17
|
|
|
|
|
|
|
# ABSTRACT: Standard base class for Pod::Loom templates |
18
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
19
|
|
|
|
|
|
|
|
20
|
1
|
|
|
1
|
|
14
|
use 5.008; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
44
|
|
21
|
|
|
|
|
|
|
our $VERSION = '0.07'; |
22
|
|
|
|
|
|
|
# This file is part of Pod-Loom 0.08 (March 23, 2014) |
23
|
|
|
|
|
|
|
|
24
|
1
|
|
|
1
|
|
3
|
use Moose; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
6
|
|
25
|
|
|
|
|
|
|
|
26
|
1
|
|
|
1
|
|
4811
|
use Pod::Loom::Parser (); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
116
|
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
has tmp_collected => ( |
30
|
|
|
|
|
|
|
is => 'rw', |
31
|
|
|
|
|
|
|
isa => 'HashRef[ArrayRef]', |
32
|
|
|
|
|
|
|
); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
has tmp_encoding => ( |
35
|
|
|
|
|
|
|
is => 'rw', |
36
|
|
|
|
|
|
|
isa => 'Object', |
37
|
|
|
|
|
|
|
); |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
has tmp_groups => ( |
40
|
|
|
|
|
|
|
is => 'rw', |
41
|
|
|
|
|
|
|
isa => 'HashRef[HashRef]', |
42
|
|
|
|
|
|
|
); |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
has tmp_filename => ( |
45
|
|
|
|
|
|
|
is => 'rw', |
46
|
|
|
|
|
|
|
isa => 'Str', |
47
|
|
|
|
|
|
|
); |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
50
|
|
|
|
|
|
|
# Tied hashes for interpolating function calls into strings: |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
{ package Pod::Loom::_Interpolation; |
53
|
|
|
|
|
|
|
|
54
|
1
|
|
|
1
|
|
3
|
sub TIEHASH { bless $_[1], $_[0] } |
55
|
0
|
|
|
0
|
|
0
|
sub FETCH { $_[0]->($_[1]) } |
56
|
|
|
|
|
|
|
} # end Pod::Loom::_Interpolation |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
our %E; |
59
|
|
|
|
|
|
|
tie %E, 'Pod::Loom::_Interpolation', sub { $_[0] }; # eval |
60
|
|
|
|
|
|
|
|
61
|
1
|
|
|
1
|
|
5
|
use Exporter 'import'; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
1916
|
|
62
|
|
|
|
|
|
|
our @EXPORT_OK = qw(%E); |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
65
|
|
|
|
|
|
|
has _tmp_warned => ( |
66
|
|
|
|
|
|
|
is => 'rw', |
67
|
|
|
|
|
|
|
isa => 'Bool', |
68
|
|
|
|
|
|
|
); |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
sub warning |
72
|
|
|
|
|
|
|
{ |
73
|
0
|
|
|
0
|
1
|
0
|
my ($self, $message) = @_; |
74
|
|
|
|
|
|
|
|
75
|
0
|
0
|
|
|
|
0
|
unless ($self->_tmp_warned) { |
76
|
0
|
|
|
|
|
0
|
warn "While processing " . $self->tmp_filename . "\n"; |
77
|
0
|
|
|
|
|
0
|
$self->_tmp_warned(1); |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
0
|
|
|
|
|
0
|
warn " $message"; |
81
|
|
|
|
|
|
|
} # end warning |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub error |
85
|
|
|
|
|
|
|
{ |
86
|
0
|
|
|
0
|
1
|
0
|
my ($self, $message) = @_; |
87
|
|
|
|
|
|
|
|
88
|
0
|
|
|
|
|
0
|
die 'Error procesing ' . $self->tmp_filename . "\n $message"; |
89
|
|
|
|
|
|
|
} # end error |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
92
|
|
|
|
|
|
|
# These methods are likely to be overloaded in subclasses: |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
|
95
|
0
|
|
|
0
|
1
|
0
|
sub collect_commands { [ 'head1' ] } |
96
|
0
|
|
|
0
|
1
|
0
|
sub override_section { 0 } |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
has sections => ( |
99
|
|
|
|
|
|
|
is => 'ro', |
100
|
|
|
|
|
|
|
isa => 'ArrayRef[Str]', |
101
|
|
|
|
|
|
|
required => 1, |
102
|
|
|
|
|
|
|
builder => '_build_sections', |
103
|
|
|
|
|
|
|
); |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
sub expect_sections |
109
|
|
|
|
|
|
|
{ |
110
|
13
|
|
|
13
|
1
|
12
|
my ($self) = @_; |
111
|
|
|
|
|
|
|
|
112
|
13
|
|
|
|
|
371
|
my $collected = $self->tmp_collected; |
113
|
|
|
|
|
|
|
|
114
|
13
|
|
|
|
|
16
|
my @sections; |
115
|
|
|
|
|
|
|
|
116
|
13
|
50
|
|
|
|
14
|
foreach my $block (@{ $collected->{'Pod::Loom-sections'} || [] }) { |
|
13
|
|
|
|
|
56
|
|
117
|
0
|
|
|
|
|
0
|
push @sections, split /\s*\n/, $block; |
118
|
|
|
|
|
|
|
} # end foreach $block |
119
|
|
|
|
|
|
|
|
120
|
13
|
50
|
|
|
|
27
|
@sections = @{ $self->sections } unless @sections; |
|
13
|
|
|
|
|
356
|
|
121
|
|
|
|
|
|
|
|
122
|
13
|
|
|
|
|
38
|
$self->_insert_sections(\@sections, before => -1); |
123
|
13
|
|
|
|
|
28
|
$self->_insert_sections(\@sections, after => 0); |
124
|
|
|
|
|
|
|
|
125
|
13
|
|
|
|
|
12
|
my %omit; |
126
|
|
|
|
|
|
|
|
127
|
13
|
100
|
|
|
|
12
|
foreach my $block (@{ $collected->{'Pod::Loom-omit'} || [] }) { |
|
13
|
|
|
|
|
43
|
|
128
|
12
|
|
|
|
|
278
|
$omit{$_} = 1 for split /\s*\n/, $block; |
129
|
|
|
|
|
|
|
} # end foreach $block |
130
|
|
|
|
|
|
|
|
131
|
13
|
|
|
|
|
23
|
return [ grep { not $omit{$_} } @sections ]; |
|
208
|
|
|
|
|
270
|
|
132
|
|
|
|
|
|
|
} # end expect_sections |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
135
|
|
|
|
|
|
|
# Insert sections before or after other sections: |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
sub _insert_sections |
138
|
|
|
|
|
|
|
{ |
139
|
26
|
|
|
26
|
|
31
|
my ($self, $sectionsList, $type, $index) = @_; |
140
|
|
|
|
|
|
|
|
141
|
26
|
50
|
|
|
|
636
|
my $blocks = $self->tmp_collected->{"Pod::Loom-insert_$type"} |
142
|
|
|
|
|
|
|
or return; |
143
|
|
|
|
|
|
|
|
144
|
0
|
|
|
|
|
0
|
my @empty; |
145
|
|
|
|
|
|
|
|
146
|
0
|
|
|
|
|
0
|
foreach my $block (@$blocks) { |
147
|
0
|
|
|
|
|
0
|
my @list = split /\s*\n/, $block; |
148
|
|
|
|
|
|
|
|
149
|
0
|
0
|
|
|
|
0
|
next unless @list; |
150
|
|
|
|
|
|
|
|
151
|
0
|
|
|
|
|
0
|
$self->error("Can't insert $type nonexistent section $list[$index]") |
152
|
0
|
0
|
|
|
|
0
|
unless grep { $_ eq $list[$index] } @$sectionsList; |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
# We remove each section listed: |
156
|
0
|
|
|
|
|
0
|
my %remap = map { $_ => \@empty } @list; |
|
0
|
|
|
|
|
0
|
|
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# Except the one at $index, where we insert the entire list: |
159
|
0
|
|
|
|
|
0
|
$remap{ $list[$index] } = \@list; |
160
|
|
|
|
|
|
|
|
161
|
0
|
0
|
|
|
|
0
|
@$sectionsList = map { $remap{$_} ? @{$remap{$_}} : $_ } @$sectionsList; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
162
|
|
|
|
|
|
|
} # end foreach $block |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
} # end _insert_sections |
165
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub required_attr |
169
|
|
|
|
|
|
|
{ |
170
|
24
|
|
|
24
|
1
|
28
|
my $self = shift; |
171
|
24
|
|
|
|
|
21
|
my $section = shift; |
172
|
|
|
|
|
|
|
|
173
|
46
|
|
|
|
|
1279
|
map { |
174
|
24
|
|
|
|
|
29
|
my $v = $self->$_; |
175
|
46
|
50
|
|
|
|
128
|
defined $v |
176
|
|
|
|
|
|
|
? $v |
177
|
|
|
|
|
|
|
: $self->error("The $section section requires you to set `$_'\n") |
178
|
|
|
|
|
|
|
} @_; |
179
|
|
|
|
|
|
|
} # end required_attr |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
182
|
|
|
|
|
|
|
# Sort each arrayref in tmp_collected (if appropriate): |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
sub _sort_collected |
185
|
|
|
|
|
|
|
{ |
186
|
13
|
|
|
13
|
|
15
|
my $self = shift; |
187
|
|
|
|
|
|
|
|
188
|
13
|
|
|
|
|
343
|
my $collected = $self->tmp_collected; |
189
|
13
|
|
|
|
|
299
|
my $groups = $self->tmp_groups; |
190
|
|
|
|
|
|
|
|
191
|
13
|
|
|
|
|
13
|
foreach my $type (@{ $self->collect_commands }) { |
|
13
|
|
|
|
|
31
|
|
192
|
|
|
|
|
|
|
# Is this type of entry sorted at all? |
193
|
65
|
50
|
|
|
|
91
|
my $sort = $self->_find_sort_order($type) or next; |
194
|
|
|
|
|
|
|
|
195
|
0
|
|
|
|
|
0
|
foreach my $group ($type, map { "$type-$_" } keys %{ $groups->{$type} }) { |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
196
|
|
|
|
|
|
|
# Begin Schwartzian transform (entry_name => entry): |
197
|
|
|
|
|
|
|
# We convert the keys to lower case to make it case insensitive. |
198
|
0
|
0
|
|
|
|
0
|
my @sortable = map { /^=\S+ \s+ (\S (?:.*\S)? )/x |
|
0
|
|
|
|
|
0
|
|
199
|
|
|
|
|
|
|
? [ lc $1 => $_ ] |
200
|
|
|
|
|
|
|
: [ '' => $_ ] # Should this even be allowed? |
201
|
0
|
|
|
|
|
0
|
} @{ $collected->{$group} }; |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
# Set up %special to handle any top-of-the-list entries: |
204
|
0
|
|
|
|
|
0
|
my $count = 1; |
205
|
0
|
|
|
|
|
0
|
my %special; |
206
|
0
|
0
|
|
|
|
0
|
%special = map { lc $_ => $count++ } @$sort if ref $sort; |
|
0
|
|
|
|
|
0
|
|
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
# Sort specials first, then the rest ASCIIbetically: |
209
|
0
|
|
|
|
|
0
|
my @sorted = |
210
|
0
|
0
|
0
|
|
|
0
|
map { $_->[1] } # finish the Schwartzian transform |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
211
|
0
|
|
|
|
|
0
|
sort { ($special{$a->[0]} || $count) <=> ($special{$b->[0]} || $count) |
212
|
|
|
|
|
|
|
or $a->[0] cmp $b->[0] # if the keys match |
213
|
|
|
|
|
|
|
or $a->[1] cmp $b->[1] } # compare the whole entry |
214
|
|
|
|
|
|
|
@sortable; |
215
|
|
|
|
|
|
|
|
216
|
0
|
|
|
|
|
0
|
$collected->{$group} = \@sorted; |
217
|
|
|
|
|
|
|
} # end foreach $group of $type |
218
|
|
|
|
|
|
|
} # end foreach $type of $collected entry |
219
|
|
|
|
|
|
|
} # end _sort_collected |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
222
|
|
|
|
|
|
|
# Determine whether a collected command should be sorted: |
223
|
|
|
|
|
|
|
# |
224
|
|
|
|
|
|
|
# Returns false if they should remain in document order |
225
|
|
|
|
|
|
|
# Returns true if they should be sorted |
226
|
|
|
|
|
|
|
# |
227
|
|
|
|
|
|
|
# If the return value is a reference, it is an arrayref of entry names |
228
|
|
|
|
|
|
|
# that should appear (in order) before any other entries. |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
sub _find_sort_order |
231
|
|
|
|
|
|
|
{ |
232
|
65
|
|
|
65
|
|
63
|
my ($self, $type) = @_; |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
# First, see if the document specifies the sort order: |
235
|
65
|
|
|
|
|
1503
|
my $blocks = $self->tmp_collected->{"Pod::Loom-sort_$type"}; |
236
|
|
|
|
|
|
|
|
237
|
65
|
50
|
|
|
|
1456
|
if ($self->tmp_collected->{"Pod::Loom-no_sort_$type"}) { |
238
|
0
|
0
|
|
|
|
0
|
$self->error("You used both no_sort_$type and sort_$type\n") |
239
|
|
|
|
|
|
|
if $blocks; |
240
|
|
|
|
|
|
|
|
241
|
0
|
|
|
|
|
0
|
return; |
242
|
|
|
|
|
|
|
} # end if document says no sorting |
243
|
|
|
|
|
|
|
|
244
|
65
|
50
|
|
|
|
89
|
if ($blocks) { |
245
|
0
|
|
|
|
|
0
|
my @sortFirst; |
246
|
0
|
|
|
|
|
0
|
foreach my $block (@$blocks) { |
247
|
0
|
|
|
|
|
0
|
push @sortFirst, split /\s*\n/, $block; |
248
|
|
|
|
|
|
|
} # end foreach $block |
249
|
|
|
|
|
|
|
|
250
|
0
|
|
|
|
|
0
|
return \@sortFirst; |
251
|
|
|
|
|
|
|
} # end if document specifies sort order |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
# The document said nothing, so ask the template: |
254
|
65
|
100
|
|
|
|
236
|
my $method = $self->can("sort_$type") or return; |
255
|
|
|
|
|
|
|
|
256
|
52
|
|
|
|
|
1317
|
$self->$method; |
257
|
|
|
|
|
|
|
} # end _find_sort_order |
258
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
sub weave |
262
|
|
|
|
|
|
|
{ |
263
|
13
|
|
|
13
|
1
|
19
|
my ($self, $podRef, $filename) = @_; |
264
|
|
|
|
|
|
|
|
265
|
13
|
|
|
|
|
391
|
$self->tmp_filename($filename); |
266
|
|
|
|
|
|
|
|
267
|
13
|
|
|
|
|
24
|
$self->parse_pod($podRef); |
268
|
|
|
|
|
|
|
|
269
|
13
|
|
|
|
|
30
|
$self->post_parse; |
270
|
|
|
|
|
|
|
|
271
|
13
|
|
|
|
|
42
|
my $sectionList = $self->expect_sections; |
272
|
|
|
|
|
|
|
|
273
|
13
|
|
|
|
|
38
|
$self->generate_pod($sectionList, $self->collect_sections($sectionList)); |
274
|
|
|
|
|
|
|
} # end weave |
275
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
sub parse_pod |
279
|
|
|
|
|
|
|
{ |
280
|
13
|
|
|
13
|
1
|
19
|
my ($self, $podRef) = @_; |
281
|
|
|
|
|
|
|
|
282
|
13
|
|
|
|
|
35
|
my $pe = Pod::Loom::Parser->new( $self->collect_commands ); |
283
|
|
|
|
|
|
|
# We can't use read_string, because that treats the string as |
284
|
|
|
|
|
|
|
# encoded in UTF-8, for which some byte sequences aren't valid. |
285
|
|
|
|
|
|
|
# Pod::Loom::Parser will determine the actual encoding. |
286
|
13
|
50
|
|
|
|
173
|
open my $handle, '<:encoding(iso-8859-1)', $podRef |
287
|
|
|
|
|
|
|
or die "error opening string for reading: $!"; |
288
|
13
|
|
|
|
|
270
|
$pe->read_handle($handle); |
289
|
13
|
|
|
|
|
221
|
$self->tmp_collected( $pe->collected ); |
290
|
13
|
|
|
|
|
36
|
$self->tmp_encoding( $pe->encoding ); |
291
|
13
|
|
|
|
|
33
|
$self->tmp_groups( $pe->groups ); |
292
|
|
|
|
|
|
|
} # end parse_pod |
293
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
sub post_parse |
297
|
|
|
|
|
|
|
{ |
298
|
13
|
|
|
13
|
1
|
16
|
my ($self) = @_; |
299
|
|
|
|
|
|
|
|
300
|
13
|
|
|
|
|
27
|
$self->_sort_collected; |
301
|
|
|
|
|
|
|
} # end post_parse |
302
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
sub collect_sections |
306
|
|
|
|
|
|
|
{ |
307
|
13
|
|
|
13
|
1
|
15
|
my ($self, $sectionList) = @_; |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
# Split out the expected sections: |
310
|
|
|
|
|
|
|
|
311
|
13
|
|
|
|
|
14
|
my %expectedSection = map { $_ => 1 } @$sectionList; |
|
144
|
|
|
|
|
221
|
|
312
|
|
|
|
|
|
|
|
313
|
13
|
|
|
|
|
362
|
my $heads = $self->tmp_collected->{head1}; |
314
|
13
|
|
|
|
|
12
|
my %section; |
315
|
|
|
|
|
|
|
|
316
|
13
|
|
|
|
|
23
|
foreach my $h (@$heads) { |
317
|
7
|
50
|
|
|
|
38
|
$h =~ /^=head1\s+(.+?)(?=\n*\z|\n\n)/ |
318
|
|
|
|
|
|
|
or $self->error("Can't find heading in $h"); |
319
|
7
|
|
|
|
|
10
|
my $title = $1; |
320
|
|
|
|
|
|
|
|
321
|
7
|
50
|
|
|
|
14
|
if ($expectedSection{$title}) { |
322
|
7
|
50
|
|
|
|
16
|
warn "Duplicate section $title" if $section{$title}; |
323
|
7
|
|
|
|
|
18
|
$section{$title} .= $h; |
324
|
|
|
|
|
|
|
} else { |
325
|
0
|
|
|
|
|
0
|
$section{'*'} .= $h; |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
} # end foreach $h in @$heads |
328
|
|
|
|
|
|
|
|
329
|
13
|
|
|
|
|
60
|
return \%section; |
330
|
|
|
|
|
|
|
} # end collect_sections |
331
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
sub generate_pod |
335
|
|
|
|
|
|
|
{ |
336
|
13
|
|
|
13
|
1
|
17
|
my ($self, $sectionList, $sectionText) = @_; |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
# Now build the new POD: |
339
|
13
|
|
|
|
|
16
|
my $pod = ''; |
340
|
|
|
|
|
|
|
|
341
|
13
|
|
|
|
|
17
|
foreach my $title (@$sectionList) { |
342
|
144
|
100
|
66
|
|
|
308
|
if ($sectionText->{$title} and not $self->override_section($title)) { |
343
|
7
|
|
|
|
|
12
|
$pod .= $sectionText->{$title}; |
344
|
|
|
|
|
|
|
} # end if document supplied section and we don't override it |
345
|
|
|
|
|
|
|
else { |
346
|
137
|
|
|
|
|
201
|
my $method = $self->method_for_section($title); |
347
|
|
|
|
|
|
|
|
348
|
137
|
100
|
|
|
|
390
|
$pod .= $self->$method($title, $sectionText->{$title}) |
349
|
|
|
|
|
|
|
if $method; |
350
|
|
|
|
|
|
|
} # end else let method generate section |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
# Make sure the document ends with a blank line: |
353
|
144
|
100
|
|
|
|
1532
|
$pod =~ s/\n*\z/\n\n/ if $pod; |
354
|
|
|
|
|
|
|
} # end foreach $title in @$sectionList |
355
|
|
|
|
|
|
|
|
356
|
13
|
|
|
|
|
324
|
my $encoding = $self->tmp_encoding; |
357
|
13
|
50
|
|
|
|
36
|
if (length $pod) { |
358
|
13
|
|
|
|
|
92
|
$pod = $encoding->encode($pod); |
359
|
13
|
|
|
|
|
45
|
my $name = $encoding->name; |
360
|
13
|
100
|
|
|
|
34
|
$pod = "=encoding " . $encoding->encode($name) . "\n\n$pod" |
361
|
|
|
|
|
|
|
unless $name eq 'iso-8859-1'; |
362
|
|
|
|
|
|
|
} |
363
|
|
|
|
|
|
|
|
364
|
13
|
|
|
|
|
46
|
$pod; |
365
|
|
|
|
|
|
|
} # end generate_pod |
366
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
sub method_for_section |
370
|
|
|
|
|
|
|
{ |
371
|
137
|
|
|
137
|
1
|
134
|
my ($self, $title) = @_; |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
# Generate the method name: |
374
|
137
|
|
|
|
|
143
|
my $method = "section_$title"; |
375
|
137
|
100
|
|
|
|
162
|
if ($title eq '*') { $method = "other_sections" } |
|
13
|
|
|
|
|
13
|
|
376
|
|
|
|
|
|
|
else { |
377
|
124
|
|
|
|
|
180
|
$method =~ s/[^A-Z0-9_]/_/gi; |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
# See if we actually have a method by that name: |
381
|
137
|
|
|
|
|
329
|
$self->can($method); |
382
|
|
|
|
|
|
|
} # end method_for_section |
383
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
sub joined_section |
387
|
|
|
|
|
|
|
{ |
388
|
52
|
|
|
52
|
1
|
84
|
my ($self, $cmd, $newcmd, $title, $pod) = @_; |
389
|
|
|
|
|
|
|
|
390
|
52
|
|
|
|
|
1286
|
my $entries = $self->tmp_collected->{$cmd}; |
391
|
52
|
|
|
|
|
1186
|
my $groups = $self->tmp_groups->{$cmd}; |
392
|
|
|
|
|
|
|
|
393
|
52
|
50
|
50
|
|
|
447
|
return ($pod || '') unless ($entries and @$entries) |
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
394
|
|
|
|
|
|
|
or ($groups and %$groups); |
395
|
|
|
|
|
|
|
|
396
|
0
|
0
|
|
|
|
|
$pod = "=head1 $title\n" unless $pod; |
397
|
|
|
|
|
|
|
|
398
|
0
|
0
|
0
|
|
|
|
return $self->_join_groups($cmd, $newcmd, $title, $pod, $groups) |
399
|
|
|
|
|
|
|
if $groups and %$groups; |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
|
402
|
0
|
0
|
|
|
|
|
warn("Found Pod::Loom-group_$cmd in " . $self->tmp_filename . |
403
|
|
|
|
|
|
|
", but no groups were used\n") |
404
|
|
|
|
|
|
|
if $self->tmp_collected->{"Pod::Loom-group_$cmd"}; |
405
|
|
|
|
|
|
|
|
406
|
0
|
|
|
|
|
|
return $pod . $self->join_entries($newcmd, $entries); |
407
|
|
|
|
|
|
|
} # end joined_section |
408
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
sub join_entries |
412
|
|
|
|
|
|
|
{ |
413
|
0
|
|
|
0
|
1
|
|
my ($self, $newcmd, $entries) = @_; |
414
|
|
|
|
|
|
|
|
415
|
0
|
|
|
|
|
|
my $pod = ''; |
416
|
|
|
|
|
|
|
|
417
|
0
|
0
|
|
|
|
|
$pod .= "\n=over\n" if $newcmd eq 'item'; |
418
|
|
|
|
|
|
|
|
419
|
0
|
|
|
|
|
|
foreach (@$entries) { |
420
|
0
|
0
|
|
|
|
|
s/^=\S+/=$newcmd/ or $self->error("Bad entry $_"); |
421
|
0
|
|
|
|
|
|
$pod .= "\n$_"; |
422
|
|
|
|
|
|
|
} # end foreach |
423
|
|
|
|
|
|
|
|
424
|
0
|
0
|
|
|
|
|
$pod .= "\n=back\n" if $newcmd eq 'item'; |
425
|
|
|
|
|
|
|
|
426
|
0
|
|
|
|
|
|
return $pod; |
427
|
|
|
|
|
|
|
} # end join_entries |
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
#--------------------------------------------------------------------- |
430
|
|
|
|
|
|
|
# Called by joined_section when it determines there are groups: |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
sub _join_groups |
433
|
|
|
|
|
|
|
{ |
434
|
0
|
|
|
0
|
|
|
my ($self, $cmd, $newcmd, $title, $pod, $groups) = @_; |
435
|
|
|
|
|
|
|
|
436
|
0
|
|
|
|
|
|
my $groupHeaders = $self->tmp_collected->{"Pod::Loom-group_$cmd"}; |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
|
439
|
0
|
0
|
|
|
|
|
die("=$cmd was grouped, but no Pod::Loom-group_$cmd found in " . |
440
|
|
|
|
|
|
|
$self->tmp_filename . "\n") |
441
|
|
|
|
|
|
|
unless $groupHeaders; |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
# We might need to go down a level: |
444
|
0
|
0
|
|
|
|
|
if ($newcmd =~ /^head\d/) { |
445
|
0
|
|
|
|
|
|
for (;;) { |
446
|
0
|
|
|
|
|
|
my $re = qr/^=\Q$newcmd\E/m; |
447
|
0
|
0
|
|
|
|
|
last unless grep { /$re/ } @$groupHeaders; |
|
0
|
|
|
|
|
|
|
448
|
0
|
|
|
|
|
|
++$newcmd; |
449
|
|
|
|
|
|
|
} # end for as long as $newcmd is used in any header |
450
|
|
|
|
|
|
|
} # end if $newcmd is headN |
451
|
|
|
|
|
|
|
|
452
|
0
|
|
|
|
|
|
my $collected = $self->tmp_collected; |
453
|
|
|
|
|
|
|
|
454
|
0
|
0
|
|
|
|
|
$groups->{''} = 1 if @{ $collected->{$cmd} }; |
|
0
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
|
456
|
0
|
|
|
|
|
|
foreach my $header (@$groupHeaders) { |
457
|
0
|
0
|
|
|
|
|
$header =~ s/^\s*(\S+)\s*?\n// |
458
|
|
|
|
|
|
|
or $self->error("No category in Pod::Loom-group_$cmd\n$header"); |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
|
461
|
0
|
|
|
|
|
|
my $type = $1; |
462
|
0
|
|
|
|
|
|
my $collectedUnder = "$cmd-$type"; |
463
|
|
|
|
|
|
|
|
464
|
0
|
0
|
|
|
|
|
if ($type eq '*') { |
465
|
0
|
|
|
|
|
|
$type = ''; |
466
|
0
|
|
|
|
|
|
$collectedUnder = $cmd; |
467
|
|
|
|
|
|
|
} |
468
|
|
|
|
|
|
|
|
469
|
0
|
0
|
|
|
|
|
unless (delete $groups->{$type}) { |
470
|
0
|
|
|
|
|
|
$self->warning("No entries for =$cmd-$type"); |
471
|
0
|
|
|
|
|
|
next; |
472
|
|
|
|
|
|
|
} |
473
|
|
|
|
|
|
|
|
474
|
0
|
|
|
|
|
|
$pod =~ s/\n*\z/\n\n/; # Make sure it ends with a blank line |
475
|
0
|
|
|
|
|
|
$pod .= ($header . |
476
|
|
|
|
|
|
|
$self->join_entries($newcmd, $collected->{$collectedUnder})); |
477
|
|
|
|
|
|
|
} # end foreach $header in @$groupHeaders |
478
|
|
|
|
|
|
|
|
479
|
0
|
0
|
|
|
|
|
if (%$groups) { |
480
|
0
|
0
|
|
|
|
|
$self->warning("You used =$cmd, but had no Pod::Loom-group_$cmd * section\n") |
481
|
|
|
|
|
|
|
if delete $groups->{''}; |
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
$self->warning("You used =$cmd-$_, but had no Pod::Loom-group_$cmd $_ section\n") |
485
|
0
|
|
|
|
|
|
for sort keys %$groups; |
486
|
|
|
|
|
|
|
|
487
|
0
|
|
|
|
|
|
die "Terminating because of errors\n"; |
488
|
|
|
|
|
|
|
} # end if used groups that had no header |
489
|
|
|
|
|
|
|
|
490
|
0
|
|
|
|
|
|
$pod; |
491
|
|
|
|
|
|
|
} # end _join_groups |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
#===================================================================== |
494
|
|
|
|
|
|
|
# Package Return Value: |
495
|
|
|
|
|
|
|
|
496
|
1
|
|
|
1
|
|
5
|
no Moose; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
5
|
|
497
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable; |
498
|
|
|
|
|
|
|
1; |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
__END__ |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
=head1 NAME |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
Pod::Loom::Template - Standard base class for Pod::Loom templates |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
=head1 VERSION |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
This document describes version 0.07 of |
509
|
|
|
|
|
|
|
Pod::Loom::Template, released March 23, 2014 |
510
|
|
|
|
|
|
|
as part of Pod-Loom version 0.08. |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
=head1 DESCRIPTION |
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
Pod::Loom::Template is intended as the standard base class for |
515
|
|
|
|
|
|
|
Pod::Loom templates. It provides the engine that splits apart the POD |
516
|
|
|
|
|
|
|
and reassembles it. The subclass needs to specify how the POD is |
517
|
|
|
|
|
|
|
reassembled. See the L</"weave"> method for details. |
518
|
|
|
|
|
|
|
|
519
|
|
|
|
|
|
|
=head2 Controlling the template |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
A POD document can contain special commands for the template. These |
522
|
|
|
|
|
|
|
commands should work with all templates based on Pod::Loom::Template. |
523
|
|
|
|
|
|
|
They are placed in a C<=for> command, and must not come in the middle |
524
|
|
|
|
|
|
|
of a section. |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
=over |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
=item Pod::Loom-insert_after |
529
|
|
|
|
|
|
|
|
530
|
|
|
|
|
|
|
=item Pod::Loom-insert_before |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
Insert (or move) one or more sections into the specified position. |
533
|
|
|
|
|
|
|
See L</"expect_sections">. |
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
=item Pod::Loom-omit |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
Omit the specified sections from the document. |
538
|
|
|
|
|
|
|
See L</"expect_sections">. |
539
|
|
|
|
|
|
|
|
540
|
|
|
|
|
|
|
=item Pod::Loom-sections |
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
Specify the complete list of sections for the document. |
543
|
|
|
|
|
|
|
See L</"expect_sections">. |
544
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
=item Pod::Loom-sort_COMMAND |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
If a template allows pseudo-POD commands like C<=method>, you can have |
548
|
|
|
|
|
|
|
the resulting entries sorted alphabetically. For example, to have |
549
|
|
|
|
|
|
|
your methods sorted, use |
550
|
|
|
|
|
|
|
|
551
|
|
|
|
|
|
|
=for Pod::Loom-sort_method |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
You can also supply a list of entries (one per line) that should come |
554
|
|
|
|
|
|
|
first. The list must match the corresponding entry exactly. For |
555
|
|
|
|
|
|
|
example: |
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
=for Pod::Loom-sort_method |
558
|
|
|
|
|
|
|
new |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
=method new |
561
|
|
|
|
|
|
|
|
562
|
|
|
|
|
|
|
or |
563
|
|
|
|
|
|
|
|
564
|
|
|
|
|
|
|
=for Pod::Loom-sort_method |
565
|
|
|
|
|
|
|
C<< $object = Class->new() >> |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
=method C<< $object = Class->new() >> |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
=item Pod::Loom-group_COMMAND |
570
|
|
|
|
|
|
|
|
571
|
|
|
|
|
|
|
If you have a lot of attributes or methods, you might want to group |
572
|
|
|
|
|
|
|
them into categories. You do this by appending the category (which is |
573
|
|
|
|
|
|
|
an arbitrary string without whitespace) to the command. For example: |
574
|
|
|
|
|
|
|
|
575
|
|
|
|
|
|
|
=attr-fmt font |
576
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
says that the font attribute is in the C<fmt> category. You must have |
578
|
|
|
|
|
|
|
a C<Pod::Loom-group_COMMAND> block for each category you use. The |
579
|
|
|
|
|
|
|
block begins with the category name on a line by itself. The rest of |
580
|
|
|
|
|
|
|
the block (which may be blank) is POD that will appear before the |
581
|
|
|
|
|
|
|
associated entries. |
582
|
|
|
|
|
|
|
|
583
|
|
|
|
|
|
|
=begin Pod::Loom-group_attr fmt |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
=head2 Formatting Attributes |
586
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
These attributes control formatting. |
588
|
|
|
|
|
|
|
|
589
|
|
|
|
|
|
|
Note: Because Pod::Eventual is not a full-fledged POD parser, you do |
590
|
|
|
|
|
|
|
not actually need a matching C<=end> after the C<=begin>, but it won't |
591
|
|
|
|
|
|
|
hurt if you use one. If you don't, the block ends at the next POD |
592
|
|
|
|
|
|
|
command in L</"collect_commands">. |
593
|
|
|
|
|
|
|
|
594
|
|
|
|
|
|
|
Entries that do not contain a category are placed in the special |
595
|
|
|
|
|
|
|
category C<*>. |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
The categories will be listed in the order that the |
598
|
|
|
|
|
|
|
Pod::Loom-group_COMMAND blocks appear in the document. The order of |
599
|
|
|
|
|
|
|
entries within each category is controlled as usual. See |
600
|
|
|
|
|
|
|
L</"Pod::Loom-sort_COMMAND">. (Just ignore the category when defining |
601
|
|
|
|
|
|
|
the sort order.) |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
=item Pod::Loom-template |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
Specify the template for the document. (This is actually handled by |
606
|
|
|
|
|
|
|
L<Pod::Loom>, and applies to all templates, whether or not they |
607
|
|
|
|
|
|
|
subclass Pod::Loom::Template.) |
608
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
=back |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
All attributes beginning with C<tmp_> are reserved and must not be |
614
|
|
|
|
|
|
|
defined by subclasses. In addition, attributes beginning with |
615
|
|
|
|
|
|
|
C<sort_> are reserved for indicating whether collected entries should |
616
|
|
|
|
|
|
|
be sorted. |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
|
619
|
|
|
|
|
|
|
=head2 sections |
620
|
|
|
|
|
|
|
|
621
|
|
|
|
|
|
|
Subclasses must provide a builder for this attribute named |
622
|
|
|
|
|
|
|
C<_build_sections>. It is an |
623
|
|
|
|
|
|
|
arrayref of section titles in the order they should appear. The |
624
|
|
|
|
|
|
|
special title C<*> indicates where sections that appear in the |
625
|
|
|
|
|
|
|
document but are not in this list will be placed. (If C<*> is not in |
626
|
|
|
|
|
|
|
this list, such sections will be dropped.) |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
The list can include sections that the template does not provide. In |
629
|
|
|
|
|
|
|
that case, it simply indicates where the section should be placed if |
630
|
|
|
|
|
|
|
the document provides it. |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
=head2 tmp_collected |
634
|
|
|
|
|
|
|
|
635
|
|
|
|
|
|
|
This is a hashref of arrayrefs. The keys are the POD commands |
636
|
|
|
|
|
|
|
returned by L</"collect_commands">, plus any format names that begin |
637
|
|
|
|
|
|
|
with C<Pod::Loom>. Each value is an arrayref of POD blocks. |
638
|
|
|
|
|
|
|
It is filled in by the L</"parse_pod"> method. |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
|
641
|
|
|
|
|
|
|
=head2 tmp_filename |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
This is the name of the file being processed. This is only for |
644
|
|
|
|
|
|
|
informational purposes; it need not represent an actual file on disk. |
645
|
|
|
|
|
|
|
(The L</"weave"> method stores the filename here.) |
646
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
=head2 tmp_groups |
649
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
This is a hashref of hashrefs. The keys are the POD commands returned |
651
|
|
|
|
|
|
|
by L</"collect_commands">, Each value is an hashref of group codes. |
652
|
|
|
|
|
|
|
It is filled in by the L</"parse_pod"> method. |
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
=head1 METHODS |
655
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
=head2 collect_commands |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
$arrayRef = $tmp->collect_commands; |
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
This method should be overriden in subclasses to indicate what POD |
661
|
|
|
|
|
|
|
commands should be collected for the template to stitch together. |
662
|
|
|
|
|
|
|
This should include C<head1>, or the template is unlikely to work |
663
|
|
|
|
|
|
|
properly. The default method indicates only C<head1> is collected. |
664
|
|
|
|
|
|
|
|
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
=head2 collect_sections |
667
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
$section_text = $tmp->collect_sections($section_list) |
669
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
This method collects the text of each section in the original document |
671
|
|
|
|
|
|
|
based on the $section_list (which comes from L</"expect_sections">). |
672
|
|
|
|
|
|
|
It returns a hashref keyed on section title. |
673
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
Any sections that appeared in the original document but are not in |
675
|
|
|
|
|
|
|
C<$section_list> are concatenated to form the C<*> section. |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
=head2 error |
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
$tmp->error($message); |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
This method calls Perl's C<die> builtin with the C<$message> after |
683
|
|
|
|
|
|
|
prepending the filename to it. |
684
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
=head2 expect_sections |
687
|
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
$section_titles = $tmp->expect_sections; |
689
|
|
|
|
|
|
|
|
690
|
|
|
|
|
|
|
This method returns an arrayref containing the section titles in the |
691
|
|
|
|
|
|
|
order they should appear. By default, this is the list from |
692
|
|
|
|
|
|
|
L</"sections">, but it can be overriden by the document: |
693
|
|
|
|
|
|
|
|
694
|
|
|
|
|
|
|
If the document contains C<=for Pod::Loom-sections>, the sections |
695
|
|
|
|
|
|
|
listed there (one per line) replace the template's normal section |
696
|
|
|
|
|
|
|
list. |
697
|
|
|
|
|
|
|
|
698
|
|
|
|
|
|
|
If the document contains C<=for Pod::Loom-omit>, the sections listed |
699
|
|
|
|
|
|
|
there will not appear in the final document. (Unless they appeared in |
700
|
|
|
|
|
|
|
the document, in which case they will be with the other C<*> |
701
|
|
|
|
|
|
|
sections.) |
702
|
|
|
|
|
|
|
|
703
|
|
|
|
|
|
|
If the document contains C<=for Pod::Loom-insert_before>, the sections |
704
|
|
|
|
|
|
|
listed there will be inserted before the last section in the list |
705
|
|
|
|
|
|
|
(which must already be in the section list). If the sections were |
706
|
|
|
|
|
|
|
already in the section list, they are moved to the new location. |
707
|
|
|
|
|
|
|
|
708
|
|
|
|
|
|
|
If the document contains C<=for Pod::Loom-insert_after>, the sections |
709
|
|
|
|
|
|
|
listed there will be inserted after the first section in the list. |
710
|
|
|
|
|
|
|
For example, |
711
|
|
|
|
|
|
|
|
712
|
|
|
|
|
|
|
=for Pod::Loom-insert_after |
713
|
|
|
|
|
|
|
DESCRIPTION |
714
|
|
|
|
|
|
|
NOTES |
715
|
|
|
|
|
|
|
|
716
|
|
|
|
|
|
|
will cause the NOTES section to appear immediately after the DESCRIPTION. |
717
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
=head2 generate_pod |
720
|
|
|
|
|
|
|
|
721
|
|
|
|
|
|
|
$pod = $tmp->generate_pod($section_list, $section_text) |
722
|
|
|
|
|
|
|
|
723
|
|
|
|
|
|
|
This method is passed a list of section titles (from |
724
|
|
|
|
|
|
|
L</"expect_sections">) and a hash containing the original text of each |
725
|
|
|
|
|
|
|
section (from L</"collect_sections">. It then considers each section |
726
|
|
|
|
|
|
|
in order: |
727
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
=over |
729
|
|
|
|
|
|
|
|
730
|
|
|
|
|
|
|
=item 1. |
731
|
|
|
|
|
|
|
|
732
|
|
|
|
|
|
|
If the section appeared in the original document, it calls |
733
|
|
|
|
|
|
|
C<< $tmp->override_section($title) >>. If that returns false, |
734
|
|
|
|
|
|
|
it copies the section from the original document to the new document |
735
|
|
|
|
|
|
|
and proceeds to the next section. Otherwise, it continues to step 2. |
736
|
|
|
|
|
|
|
|
737
|
|
|
|
|
|
|
=item 2. |
738
|
|
|
|
|
|
|
|
739
|
|
|
|
|
|
|
It calls C<< $tmp->method_for_section($title) >> to get the method |
740
|
|
|
|
|
|
|
that will handle that section. If that returns no method, it proceeds |
741
|
|
|
|
|
|
|
to the next section. |
742
|
|
|
|
|
|
|
|
743
|
|
|
|
|
|
|
=item 3. |
744
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
It calls the method from step 2, passing it two parameters: the |
746
|
|
|
|
|
|
|
section title and the text of the section from the original document |
747
|
|
|
|
|
|
|
(or undef). Whatever text the method returns is appended to the new |
748
|
|
|
|
|
|
|
document. (The method may return the empty string, but should not |
749
|
|
|
|
|
|
|
return undef). |
750
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
=back |
752
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
|
754
|
|
|
|
|
|
|
=head2 join_entries |
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
$podText = $tmp->join_entries($newcmd, \@entries); |
757
|
|
|
|
|
|
|
|
758
|
|
|
|
|
|
|
This method is used by L</"joined_section">, but may be useful to |
759
|
|
|
|
|
|
|
subclasses also. Each element of C<@entries> must begin with a POD |
760
|
|
|
|
|
|
|
command, which will be changed to C<$newcmd>. It returns the entries |
761
|
|
|
|
|
|
|
joined together, surrounded by C<=over> and C<=back> if C<$newcmd> is |
762
|
|
|
|
|
|
|
C<item>. |
763
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
|
765
|
|
|
|
|
|
|
=head2 joined_section |
766
|
|
|
|
|
|
|
|
767
|
|
|
|
|
|
|
$podText = $tmp->joined_section($oldcmd, $newcmd, $title, $pod); |
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
This method may be useful to subclasses that want to build sections |
770
|
|
|
|
|
|
|
out of collected commands. C<$oldcmd> must be one of the entries from |
771
|
|
|
|
|
|
|
L</"collect_commands">. C<$newcmd> is the POD command that should be |
772
|
|
|
|
|
|
|
used for each entry (like C<head2> or C<item>). C<$title> is the |
773
|
|
|
|
|
|
|
section title, and C<$pod> is the text of that section from the |
774
|
|
|
|
|
|
|
original document (if any). |
775
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
Each collected entry is appended to the original section. If there |
777
|
|
|
|
|
|
|
was no original section, a simple C<=head1 $title> command is added. |
778
|
|
|
|
|
|
|
If C<$newcmd> is C<item>, then C<=over> and C<=back> are added |
779
|
|
|
|
|
|
|
automatically. |
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
If the document divided this section into groups (see |
782
|
|
|
|
|
|
|
L</"Pod::Loom-group_COMMAND">), that is handled automatically by this |
783
|
|
|
|
|
|
|
method. If C<$newcmd> is a C<headN>, and any of the category headers |
784
|
|
|
|
|
|
|
contains a C<=headN> command, then C<$newcmd> is automatically |
785
|
|
|
|
|
|
|
incremented. (E.g., C<head2> becomes C<head3>). |
786
|
|
|
|
|
|
|
|
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
=head2 method_for_section |
789
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
$methodRef = $tmp->method_for_section($section_title); |
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
This associates a section title with the template method that |
793
|
|
|
|
|
|
|
implements it. By default, it prepends C<section_> to the title, and |
794
|
|
|
|
|
|
|
then converts any non-alphanumeric characters to underscores. |
795
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
The special C<*> section is associated with the method C<other_sections>. |
797
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
=head2 override_section |
800
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
$boolean = $tmp->override_section($section_title); |
802
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
Normally, if a section appears in the document, it remains unchanged |
804
|
|
|
|
|
|
|
by the template. However, a template may want to rewrite certain |
805
|
|
|
|
|
|
|
sections. C<override_section> is called when the specified section is |
806
|
|
|
|
|
|
|
present in the document. If it returns true, then the normal |
807
|
|
|
|
|
|
|
C<section_TITLE> method will be called. (If it returns true but the |
808
|
|
|
|
|
|
|
C<section_TITLE> method doesn't exist, the section will be dropped.) |
809
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
|
811
|
|
|
|
|
|
|
=head2 parse_pod |
812
|
|
|
|
|
|
|
|
813
|
|
|
|
|
|
|
$tmp->parse_pod(\$pod); |
814
|
|
|
|
|
|
|
|
815
|
|
|
|
|
|
|
Parse the document, which is passed by reference. The default |
816
|
|
|
|
|
|
|
implementation splits up the POD using L<Pod::Loom::Parser>, breaking |
817
|
|
|
|
|
|
|
it up according to L</"collect_commands">. The resulting chunks are |
818
|
|
|
|
|
|
|
stored in the C<tmp_collected> attribute. |
819
|
|
|
|
|
|
|
|
820
|
|
|
|
|
|
|
|
821
|
|
|
|
|
|
|
=head2 post_parse |
822
|
|
|
|
|
|
|
|
823
|
|
|
|
|
|
|
$tmp->post_parse() |
824
|
|
|
|
|
|
|
|
825
|
|
|
|
|
|
|
This method is called after C<parse_pod>. The default implementation |
826
|
|
|
|
|
|
|
sorts the collected POD chunks if requested to by the document or the |
827
|
|
|
|
|
|
|
C<sort_> attributes. |
828
|
|
|
|
|
|
|
|
829
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
=head2 required_attr |
831
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
@values = $tmp->required_attr($section_title, @attribute_names); |
833
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
Returns the value of each attribute specified in C<@attribute_names>. |
835
|
|
|
|
|
|
|
If any attribute is C<undef>, dies with a message that |
836
|
|
|
|
|
|
|
C<$section_title> requires that attribute. |
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
|
839
|
|
|
|
|
|
|
=head2 warning |
840
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
$tmp->warning($message); |
842
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
This method calls Perl's C<warn> builtin with the C<$message>. If |
844
|
|
|
|
|
|
|
this is the first warning, it first prints a warning with the filename. |
845
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
|
847
|
|
|
|
|
|
|
=head2 weave |
848
|
|
|
|
|
|
|
|
849
|
|
|
|
|
|
|
$new_pod = $tmp->weave(\$old_pod, $filename); |
850
|
|
|
|
|
|
|
|
851
|
|
|
|
|
|
|
This is the primary entry point, normally called by Pod::Loom's |
852
|
|
|
|
|
|
|
C<weave> method. |
853
|
|
|
|
|
|
|
|
854
|
|
|
|
|
|
|
First, it stores the filename in the C<tmp_filename> attribute. |
855
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
It then calls: |
857
|
|
|
|
|
|
|
|
858
|
|
|
|
|
|
|
=over |
859
|
|
|
|
|
|
|
|
860
|
|
|
|
|
|
|
=item 1. |
861
|
|
|
|
|
|
|
|
862
|
|
|
|
|
|
|
L</"parse_pod"> to parse the POD. |
863
|
|
|
|
|
|
|
|
864
|
|
|
|
|
|
|
=item 2. |
865
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
L</"post_parse"> to do additional processing. |
867
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
=item 3. |
869
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
L</"expect_sections"> to get the list of section titles. |
871
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
=item 4. |
873
|
|
|
|
|
|
|
|
874
|
|
|
|
|
|
|
L</"collect_sections"> to get the text of each section from |
875
|
|
|
|
|
|
|
the original document. |
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
=item 5. |
878
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
L</"generate_pod"> to produce the new document. |
880
|
|
|
|
|
|
|
|
881
|
|
|
|
|
|
|
=back |
882
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
=head1 DIAGNOSTICS |
884
|
|
|
|
|
|
|
|
885
|
|
|
|
|
|
|
The following errors are classified like Perl's built-in diagnostics |
886
|
|
|
|
|
|
|
(L<perldiag>): |
887
|
|
|
|
|
|
|
|
888
|
|
|
|
|
|
|
(S) A severe warning |
889
|
|
|
|
|
|
|
(F) A fatal error (trappable) |
890
|
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
=over |
892
|
|
|
|
|
|
|
|
893
|
|
|
|
|
|
|
=item C<< %s was grouped, but no Pod::Loom-group_%s found in %s >> |
894
|
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
(F) You used categories with a command (like C<=method-cat>), but didn't |
896
|
|
|
|
|
|
|
have any Pod::Loom-group_COMMAND blocks. See L</"Pod::Loom-group_COMMAND">. |
897
|
|
|
|
|
|
|
|
898
|
|
|
|
|
|
|
|
899
|
|
|
|
|
|
|
=item C<< Can't find heading in %s >> |
900
|
|
|
|
|
|
|
|
901
|
|
|
|
|
|
|
(F) Pod::Loom couldn't determine the section title for the specified |
902
|
|
|
|
|
|
|
section. Is it formatted properly? |
903
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
|
905
|
|
|
|
|
|
|
=item C<< Can't insert before/after nonexistent section %s >> |
906
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
(F) You can't insert sections near a section title that isn't already in |
908
|
|
|
|
|
|
|
the list of sections. Make sure you spelled it right. |
909
|
|
|
|
|
|
|
|
910
|
|
|
|
|
|
|
|
911
|
|
|
|
|
|
|
=item C<< Found Pod::Loom-group_%s in %s, but no groups were used >> |
912
|
|
|
|
|
|
|
|
913
|
|
|
|
|
|
|
(S) You indicated that a command (like C<=method>) was going to be |
914
|
|
|
|
|
|
|
grouped, but didn't actually use any groups. |
915
|
|
|
|
|
|
|
See L</"Pod::Loom-group_COMMAND">. |
916
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
|
918
|
|
|
|
|
|
|
=item C<< No category in Pod::Loom-group_%s >> |
919
|
|
|
|
|
|
|
|
920
|
|
|
|
|
|
|
(F) A Pod::Loom-group_COMMAND block must begin with the category. |
921
|
|
|
|
|
|
|
|
922
|
|
|
|
|
|
|
|
923
|
|
|
|
|
|
|
=item C<< The %s section requires you to set `%s' >> |
924
|
|
|
|
|
|
|
|
925
|
|
|
|
|
|
|
(F) The specified section of the template requires an attribute that |
926
|
|
|
|
|
|
|
you did not set. |
927
|
|
|
|
|
|
|
|
928
|
|
|
|
|
|
|
|
929
|
|
|
|
|
|
|
=item C<< You used =%s, but had no Pod::Loom-group_$cmd %s section >> |
930
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
(F) You must have one Pod::Loom-group_COMMAND block for each category |
932
|
|
|
|
|
|
|
you use. Entries without a category are placed in the C<*> category. |
933
|
|
|
|
|
|
|
|
934
|
|
|
|
|
|
|
|
935
|
|
|
|
|
|
|
=back |
936
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
=head1 CONFIGURATION AND ENVIRONMENT |
938
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
Pod::Loom::Template requires no configuration files or environment variables. |
940
|
|
|
|
|
|
|
|
941
|
|
|
|
|
|
|
=head1 INCOMPATIBILITIES |
942
|
|
|
|
|
|
|
|
943
|
|
|
|
|
|
|
None reported. |
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
=head1 BUGS AND LIMITATIONS |
946
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
No bugs have been reported. |
948
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
=head1 AUTHOR |
950
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
Christopher J. Madsen S<C<< <perl AT cjmweb.net> >>> |
952
|
|
|
|
|
|
|
|
953
|
|
|
|
|
|
|
Please report any bugs or feature requests |
954
|
|
|
|
|
|
|
to S<C<< <bug-Pod-Loom AT rt.cpan.org> >>> |
955
|
|
|
|
|
|
|
or through the web interface at |
956
|
|
|
|
|
|
|
L<< http://rt.cpan.org/Public/Bug/Report.html?Queue=Pod-Loom >>. |
957
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
You can follow or contribute to Pod-Loom's development at |
959
|
|
|
|
|
|
|
L<< https://github.com/madsen/pod-loom >>. |
960
|
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
This software is copyright (c) 2014 by Christopher J. Madsen. |
964
|
|
|
|
|
|
|
|
965
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
966
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
967
|
|
|
|
|
|
|
|
968
|
|
|
|
|
|
|
=head1 DISCLAIMER OF WARRANTY |
969
|
|
|
|
|
|
|
|
970
|
|
|
|
|
|
|
BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
971
|
|
|
|
|
|
|
FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
972
|
|
|
|
|
|
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
973
|
|
|
|
|
|
|
PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER |
974
|
|
|
|
|
|
|
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
975
|
|
|
|
|
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE |
976
|
|
|
|
|
|
|
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH |
977
|
|
|
|
|
|
|
YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL |
978
|
|
|
|
|
|
|
NECESSARY SERVICING, REPAIR, OR CORRECTION. |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
981
|
|
|
|
|
|
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
982
|
|
|
|
|
|
|
REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENSE, BE |
983
|
|
|
|
|
|
|
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, |
984
|
|
|
|
|
|
|
OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE |
985
|
|
|
|
|
|
|
THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING |
986
|
|
|
|
|
|
|
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A |
987
|
|
|
|
|
|
|
FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF |
988
|
|
|
|
|
|
|
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF |
989
|
|
|
|
|
|
|
SUCH DAMAGES. |
990
|
|
|
|
|
|
|
|
991
|
|
|
|
|
|
|
=cut |