line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
|
2
|
|
|
|
|
|
|
require 5; |
3
|
|
|
|
|
|
|
package Pod::Simple; |
4
|
67
|
|
|
67
|
|
139620
|
use strict; |
|
67
|
|
|
|
|
140
|
|
|
67
|
|
|
|
|
1871
|
|
5
|
67
|
|
|
67
|
|
322
|
use Carp (); |
|
67
|
|
|
|
|
441
|
|
|
67
|
|
|
|
|
3039
|
|
6
|
67
|
50
|
|
67
|
|
2064
|
BEGIN { *DEBUG = sub () {0} unless defined &DEBUG } |
7
|
67
|
|
|
67
|
|
31953
|
use integer; |
|
67
|
|
|
|
|
866
|
|
|
67
|
|
|
|
|
309
|
|
8
|
67
|
|
|
67
|
|
31315
|
use Pod::Escapes 1.04 (); |
|
67
|
|
|
|
|
278989
|
|
|
67
|
|
|
|
|
2638
|
|
9
|
67
|
|
|
67
|
|
28236
|
use Pod::Simple::LinkSection (); |
|
67
|
|
|
|
|
213
|
|
|
67
|
|
|
|
|
1657
|
|
10
|
67
|
|
|
67
|
|
356
|
use Pod::Simple::BlackBox (); |
|
67
|
|
|
|
|
108
|
|
|
67
|
|
|
|
|
1514
|
|
11
|
|
|
|
|
|
|
#use utf8; |
12
|
|
|
|
|
|
|
|
13
|
67
|
|
|
|
|
19317
|
use vars qw( |
14
|
|
|
|
|
|
|
$VERSION @ISA |
15
|
|
|
|
|
|
|
@Known_formatting_codes @Known_directives |
16
|
|
|
|
|
|
|
%Known_formatting_codes %Known_directives |
17
|
|
|
|
|
|
|
$NL |
18
|
67
|
|
|
67
|
|
291
|
); |
|
67
|
|
|
|
|
112
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
@ISA = ('Pod::Simple::BlackBox'); |
21
|
|
|
|
|
|
|
$VERSION = '3.42'; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
@Known_formatting_codes = qw(I B C L E F S X Z); |
24
|
|
|
|
|
|
|
%Known_formatting_codes = map(($_=>1), @Known_formatting_codes); |
25
|
|
|
|
|
|
|
@Known_directives = qw(head1 head2 head3 head4 head5 head6 item over back); |
26
|
|
|
|
|
|
|
%Known_directives = map(($_=>'Plain'), @Known_directives); |
27
|
|
|
|
|
|
|
$NL = $/ unless defined $NL; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
30
|
|
|
|
|
|
|
# Set up some constants: |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
BEGIN { |
33
|
67
|
50
|
|
67
|
|
367
|
if(defined &ASCII) { } |
34
|
67
|
|
|
|
|
181
|
elsif(chr(65) eq 'A') { *ASCII = sub () {1} } |
35
|
|
|
|
|
|
|
else { *ASCII = sub () {''} } |
36
|
|
|
|
|
|
|
|
37
|
67
|
50
|
|
|
|
318
|
unless(defined &MANY_LINES) { *MANY_LINES = sub () {20} } |
|
67
|
|
|
|
|
131
|
|
38
|
67
|
|
|
|
|
105
|
DEBUG > 4 and print STDERR "MANY_LINES is ", MANY_LINES(), "\n"; |
39
|
67
|
50
|
|
|
|
289
|
unless(MANY_LINES() >= 1) { |
40
|
0
|
|
|
|
|
0
|
die "MANY_LINES is too small (", MANY_LINES(), ")!\nAborting"; |
41
|
|
|
|
|
|
|
} |
42
|
67
|
50
|
|
|
|
277
|
if(defined &UNICODE) { } |
|
|
50
|
|
|
|
|
|
43
|
67
|
|
|
|
|
25818
|
elsif($] >= 5.008) { *UNICODE = sub() {1} } |
44
|
0
|
|
|
|
|
0
|
else { *UNICODE = sub() {''} } |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
if(DEBUG > 2) { |
47
|
|
|
|
|
|
|
print STDERR "# We are ", ASCII ? '' : 'not ', "in ASCII-land\n"; |
48
|
|
|
|
|
|
|
print STDERR "# We are under a Unicode-safe Perl.\n"; |
49
|
|
|
|
|
|
|
} |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
# The NO BREAK SPACE and SOFT HYHPEN are used in several submodules. |
52
|
|
|
|
|
|
|
if ($] ge 5.007_003) { # On sufficiently modern Perls we can handle any |
53
|
|
|
|
|
|
|
# character set |
54
|
|
|
|
|
|
|
$Pod::Simple::nbsp = chr utf8::unicode_to_native(0xA0); |
55
|
|
|
|
|
|
|
$Pod::Simple::shy = chr utf8::unicode_to_native(0xAD); |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
elsif (Pod::Simple::ASCII) { # Hard code ASCII early Perl |
58
|
|
|
|
|
|
|
$Pod::Simple::nbsp = "\xA0"; |
59
|
|
|
|
|
|
|
$Pod::Simple::shy = "\xAD"; |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
else { # EBCDIC on early Perl. We know what the values are for the code |
62
|
|
|
|
|
|
|
# pages supported then. |
63
|
|
|
|
|
|
|
$Pod::Simple::nbsp = "\x41"; |
64
|
|
|
|
|
|
|
$Pod::Simple::shy = "\xCA"; |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
# Design note: |
68
|
|
|
|
|
|
|
# This is a parser for Pod. It is not a parser for the set of Pod-like |
69
|
|
|
|
|
|
|
# languages which happens to contain Pod -- it is just for Pod, plus possibly |
70
|
|
|
|
|
|
|
# some extensions. |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
# @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ |
73
|
|
|
|
|
|
|
#@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ |
74
|
|
|
|
|
|
|
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
__PACKAGE__->_accessorize( |
77
|
|
|
|
|
|
|
'_output_is_for_JustPod', # For use only by Pod::Simple::JustPod, |
78
|
|
|
|
|
|
|
# If non-zero, don't expand Z<> E<> S<> L<>, |
79
|
|
|
|
|
|
|
# and count how many brackets in format codes |
80
|
|
|
|
|
|
|
'nbsp_for_S', # Whether to map S<...>'s to \xA0 characters |
81
|
|
|
|
|
|
|
'source_filename', # Filename of the source, for use in warnings |
82
|
|
|
|
|
|
|
'source_dead', # Whether to consider this parser's source dead |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
'output_fh', # The filehandle we're writing to, if applicable. |
85
|
|
|
|
|
|
|
# Used only in some derived classes. |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
'hide_line_numbers', # For some dumping subclasses: whether to pointedly |
88
|
|
|
|
|
|
|
# suppress the start_line attribute |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
'line_count', # the current line number |
91
|
|
|
|
|
|
|
'pod_para_count', # count of pod paragraphs seen so far |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
'no_whining', # whether to suppress whining |
94
|
|
|
|
|
|
|
'no_errata_section', # whether to suppress the errata section |
95
|
|
|
|
|
|
|
'complain_stderr', # whether to complain to stderr |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
'doc_has_started', # whether we've fired the open-Document event yet |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
'bare_output', # For some subclasses: whether to prepend |
100
|
|
|
|
|
|
|
# header-code and postpend footer-code |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
'keep_encoding_directive', # whether to emit =encoding |
103
|
|
|
|
|
|
|
'nix_X_codes', # whether to ignore X<...> codes |
104
|
|
|
|
|
|
|
'merge_text', # whether to avoid breaking a single piece of |
105
|
|
|
|
|
|
|
# text up into several events |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
'preserve_whitespace', # whether to try to keep whitespace as-is |
108
|
|
|
|
|
|
|
'strip_verbatim_indent', # What indent to strip from verbatim |
109
|
|
|
|
|
|
|
'expand_verbatim_tabs', # 0: preserve tabs in verbatim blocks |
110
|
|
|
|
|
|
|
# n: expand tabs to stops every n columns |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
'parse_characters', # Whether parser should expect chars rather than octets |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
'content_seen', # whether we've seen any real Pod content |
115
|
|
|
|
|
|
|
'errors_seen', # TODO: document. whether we've seen any errors (fatal or not) |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
'codes_in_verbatim', # for PseudoPod extensions |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
'code_handler', # coderef to call when a code (non-pod) line is seen |
120
|
|
|
|
|
|
|
'cut_handler', # ... when a =cut line is seen |
121
|
|
|
|
|
|
|
'pod_handler', # ... when a =pod line is seen |
122
|
|
|
|
|
|
|
'whiteline_handler', # ... when a line with only whitespace is seen |
123
|
|
|
|
|
|
|
#Called like: |
124
|
|
|
|
|
|
|
# $code_handler->($line, $self->{'line_count'}, $self) if $code_handler; |
125
|
|
|
|
|
|
|
# $cut_handler->($line, $self->{'line_count'}, $self) if $cut_handler; |
126
|
|
|
|
|
|
|
# $pod_handler->($line, $self->{'line_count'}, $self) if $pod_handler; |
127
|
|
|
|
|
|
|
# $wl_handler->($line, $self->{'line_count'}, $self) if $wl_handler; |
128
|
|
|
|
|
|
|
'parse_empty_lists', # whether to acknowledge empty =over/=back blocks |
129
|
|
|
|
|
|
|
'raw_mode', # to report entire raw lines instead of Pod elements |
130
|
|
|
|
|
|
|
); |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
sub any_errata_seen { # good for using as an exit() value... |
135
|
19
|
|
100
|
19
|
1
|
151
|
return shift->{'errors_seen'} || 0; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
sub errata_seen { |
139
|
8
|
|
50
|
8
|
1
|
918
|
return shift->{'all_errata'} || {}; |
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# Returns the encoding only if it was recognized as being handled and set |
143
|
|
|
|
|
|
|
sub detected_encoding { |
144
|
0
|
|
|
0
|
1
|
0
|
return shift->{'detected_encoding'}; |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
sub encoding { |
148
|
19
|
|
|
19
|
1
|
133
|
my $this = shift; |
149
|
19
|
50
|
|
|
|
120
|
return $this->{'encoding'} unless @_; # GET. |
150
|
|
|
|
|
|
|
|
151
|
0
|
|
|
|
|
0
|
$this->_handle_encoding_line("=encoding $_[0]"); |
152
|
0
|
0
|
|
|
|
0
|
if ($this->{'_processed_encoding'}) { |
153
|
0
|
|
|
|
|
0
|
delete $this->{'_processed_encoding'}; |
154
|
0
|
0
|
|
|
|
0
|
if(! $this->{'encoding_command_statuses'} ) { |
|
|
0
|
|
|
|
|
|
155
|
0
|
|
|
|
|
0
|
DEBUG > 2 and print STDERR " CRAZY ERROR: encoding wasn't really handled?!\n"; |
156
|
|
|
|
|
|
|
} elsif( $this->{'encoding_command_statuses'}[-1] ) { |
157
|
|
|
|
|
|
|
$this->scream( "=encoding $_[0]", |
158
|
|
|
|
|
|
|
sprintf "Couldn't do %s: %s", |
159
|
|
|
|
|
|
|
$this->{'encoding_command_reqs' }[-1], |
160
|
0
|
|
|
|
|
0
|
$this->{'encoding_command_statuses'}[-1], |
161
|
|
|
|
|
|
|
); |
162
|
|
|
|
|
|
|
} else { |
163
|
0
|
|
|
|
|
0
|
DEBUG > 2 and print STDERR " (encoding successfully handled.)\n"; |
164
|
|
|
|
|
|
|
} |
165
|
0
|
|
|
|
|
0
|
return $this->{'encoding'}; |
166
|
|
|
|
|
|
|
} else { |
167
|
0
|
|
|
|
|
0
|
return undef; |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
172
|
|
|
|
|
|
|
# Pull in some functions that, for some reason, I expect to see here too: |
173
|
|
|
|
|
|
|
BEGIN { |
174
|
67
|
|
|
67
|
|
304
|
*pretty = \&Pod::Simple::BlackBox::pretty; |
175
|
67
|
|
|
|
|
144
|
*stringify_lol = \&Pod::Simple::BlackBox::stringify_lol; |
176
|
67
|
|
|
|
|
454148
|
*my_qr = \&Pod::Simple::BlackBox::my_qr; |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
sub version_report { |
182
|
0
|
|
0
|
0
|
1
|
0
|
my $class = ref($_[0]) || $_[0]; |
183
|
0
|
0
|
|
|
|
0
|
if($class eq __PACKAGE__) { |
184
|
0
|
|
|
|
|
0
|
return "$class $VERSION"; |
185
|
|
|
|
|
|
|
} else { |
186
|
0
|
|
|
|
|
0
|
my $v = $class->VERSION; |
187
|
0
|
|
|
|
|
0
|
return "$class $v (" . __PACKAGE__ . " $VERSION)"; |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
#sub curr_open { # read-only list accessor |
194
|
|
|
|
|
|
|
# return @{ $_[0]{'curr_open'} || return() }; |
195
|
|
|
|
|
|
|
#} |
196
|
|
|
|
|
|
|
#sub _curr_open_listref { $_[0]{'curr_open'} ||= [] } |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
sub output_string { |
200
|
|
|
|
|
|
|
# Works by faking out output_fh. Simplifies our code. |
201
|
|
|
|
|
|
|
# |
202
|
877
|
|
|
877
|
1
|
10796
|
my $this = shift; |
203
|
877
|
100
|
|
|
|
1819
|
return $this->{'output_string'} unless @_; # GET. |
204
|
|
|
|
|
|
|
|
205
|
867
|
|
|
|
|
27159
|
require Pod::Simple::TiedOutFH; |
206
|
867
|
50
|
33
|
|
|
3674
|
my $x = (defined($_[0]) and ref($_[0])) ? $_[0] : \( $_[0] ); |
207
|
867
|
100
|
|
|
|
1855
|
$$x = '' unless defined $$x; |
208
|
867
|
|
|
|
|
1040
|
DEBUG > 4 and print STDERR "# Output string set to $x ($$x)\n"; |
209
|
867
|
|
|
|
|
3066
|
$this->{'output_fh'} = Pod::Simple::TiedOutFH->handle_on($_[0]); |
210
|
|
|
|
|
|
|
return |
211
|
867
|
|
|
|
|
2289
|
$this->{'output_string'} = $_[0]; |
212
|
|
|
|
|
|
|
#${ ${ $this->{'output_fh'} } }; |
213
|
|
|
|
|
|
|
} |
214
|
|
|
|
|
|
|
|
215
|
10
|
|
|
10
|
1
|
46
|
sub abandon_output_string { $_[0]->abandon_output_fh; delete $_[0]{'output_string'} } |
|
10
|
|
|
|
|
28
|
|
216
|
10
|
|
|
10
|
1
|
26
|
sub abandon_output_fh { $_[0]->output_fh(undef) } |
217
|
|
|
|
|
|
|
# These don't delete the string or close the FH -- they just delete our |
218
|
|
|
|
|
|
|
# references to it/them. |
219
|
|
|
|
|
|
|
# TODO: document these |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
sub new { |
224
|
|
|
|
|
|
|
# takes no parameters |
225
|
907
|
|
33
|
907
|
1
|
7744
|
my $class = ref($_[0]) || $_[0]; |
226
|
|
|
|
|
|
|
#Carp::croak(__PACKAGE__ . " is a virtual base class -- see perldoc " |
227
|
|
|
|
|
|
|
# . __PACKAGE__ ); |
228
|
907
|
|
|
|
|
14858
|
my $obj = bless { |
229
|
|
|
|
|
|
|
'accept_codes' => { map( ($_=>$_), @Known_formatting_codes ) }, |
230
|
|
|
|
|
|
|
'accept_directives' => { %Known_directives }, |
231
|
|
|
|
|
|
|
'accept_targets' => {}, |
232
|
|
|
|
|
|
|
}, $class; |
233
|
|
|
|
|
|
|
|
234
|
907
|
|
|
|
|
4099
|
$obj->expand_verbatim_tabs(8); |
235
|
907
|
|
|
|
|
2044
|
return $obj; |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
# TODO: an option for whether to interpolate E<...>'s, or just resolve to codes. |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
sub _handle_element_start { # OVERRIDE IN DERIVED CLASS |
245
|
0
|
|
|
0
|
|
0
|
my($self, $element_name, $attr_hash_r) = @_; |
246
|
0
|
|
|
|
|
0
|
return; |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
sub _handle_element_end { # OVERRIDE IN DERIVED CLASS |
250
|
0
|
|
|
0
|
|
0
|
my($self, $element_name) = @_; |
251
|
0
|
|
|
|
|
0
|
return; |
252
|
|
|
|
|
|
|
} |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
sub _handle_text { # OVERRIDE IN DERIVED CLASS |
255
|
0
|
|
|
0
|
|
0
|
my($self, $text) = @_; |
256
|
0
|
|
|
|
|
0
|
return; |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
260
|
|
|
|
|
|
|
# |
261
|
|
|
|
|
|
|
# And now directives (not targets) |
262
|
|
|
|
|
|
|
|
263
|
3
|
|
|
3
|
1
|
20
|
sub accept_directive_as_verbatim { shift->_accept_directives('Verbatim', @_) } |
264
|
3
|
|
|
3
|
1
|
18
|
sub accept_directive_as_data { shift->_accept_directives('Data', @_) } |
265
|
3
|
|
|
3
|
1
|
21
|
sub accept_directive_as_processed { shift->_accept_directives('Plain', @_) } |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
sub _accept_directives { |
268
|
9
|
|
|
9
|
|
25
|
my($this, $type) = splice @_,0,2; |
269
|
9
|
|
|
|
|
20
|
foreach my $d (@_) { |
270
|
9
|
50
|
33
|
|
|
46
|
next unless defined $d and length $d; |
271
|
9
|
50
|
|
|
|
52
|
Carp::croak "\"$d\" isn't a valid directive name" |
272
|
|
|
|
|
|
|
unless $d =~ m/^[a-zA-Z][a-zA-Z0-9]*$/s; |
273
|
|
|
|
|
|
|
Carp::croak "\"$d\" is already a reserved Pod directive name" |
274
|
9
|
50
|
|
|
|
22
|
if exists $Known_directives{$d}; |
275
|
9
|
|
|
|
|
22
|
$this->{'accept_directives'}{$d} = $type; |
276
|
9
|
|
|
|
|
17
|
DEBUG > 2 and print STDERR "Learning to accept \"=$d\" as directive of type $type\n"; |
277
|
|
|
|
|
|
|
} |
278
|
|
|
|
|
|
|
DEBUG > 6 and print STDERR "$this\'s accept_directives : ", |
279
|
9
|
|
|
|
|
12
|
pretty($this->{'accept_directives'}), "\n"; |
280
|
|
|
|
|
|
|
|
281
|
9
|
50
|
|
|
|
20
|
return sort keys %{ $this->{'accept_directives'} } if wantarray; |
|
0
|
|
|
|
|
0
|
|
282
|
9
|
|
|
|
|
18
|
return; |
283
|
|
|
|
|
|
|
} |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
#-------------------------------------------------------------------------- |
286
|
|
|
|
|
|
|
# TODO: document these: |
287
|
|
|
|
|
|
|
|
288
|
0
|
|
|
0
|
1
|
0
|
sub unaccept_directive { shift->unaccept_directives(@_) }; |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
sub unaccept_directives { |
291
|
0
|
|
|
0
|
1
|
0
|
my $this = shift; |
292
|
0
|
|
|
|
|
0
|
foreach my $d (@_) { |
293
|
0
|
0
|
0
|
|
|
0
|
next unless defined $d and length $d; |
294
|
0
|
0
|
|
|
|
0
|
Carp::croak "\"$d\" isn't a valid directive name" |
295
|
|
|
|
|
|
|
unless $d =~ m/^[a-zA-Z][a-zA-Z0-9]*$/s; |
296
|
|
|
|
|
|
|
Carp::croak "But you must accept \"$d\" directives -- it's a builtin!" |
297
|
0
|
0
|
|
|
|
0
|
if exists $Known_directives{$d}; |
298
|
0
|
|
|
|
|
0
|
delete $this->{'accept_directives'}{$d}; |
299
|
0
|
|
|
|
|
0
|
DEBUG > 2 and print STDERR "OK, won't accept \"=$d\" as directive.\n"; |
300
|
|
|
|
|
|
|
} |
301
|
0
|
0
|
|
|
|
0
|
return sort keys %{ $this->{'accept_directives'} } if wantarray; |
|
0
|
|
|
|
|
0
|
|
302
|
|
|
|
|
|
|
return |
303
|
0
|
|
|
|
|
0
|
} |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
306
|
|
|
|
|
|
|
# |
307
|
|
|
|
|
|
|
# And now targets (not directives) |
308
|
|
|
|
|
|
|
|
309
|
35
|
|
|
35
|
1
|
168
|
sub accept_target { shift->accept_targets(@_) } # alias |
310
|
49
|
|
|
49
|
1
|
197
|
sub accept_target_as_text { shift->accept_targets_as_text(@_) } # alias |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
|
313
|
258
|
|
|
258
|
1
|
1064
|
sub accept_targets { shift->_accept_targets('1', @_) } |
314
|
|
|
|
|
|
|
|
315
|
53
|
|
|
53
|
1
|
165
|
sub accept_targets_as_text { shift->_accept_targets('force_resolve', @_) } |
316
|
|
|
|
|
|
|
# forces them to be processed, even when there's no ":". |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
sub _accept_targets { |
319
|
311
|
|
|
311
|
|
735
|
my($this, $type) = splice @_,0,2; |
320
|
311
|
|
|
|
|
568
|
foreach my $t (@_) { |
321
|
570
|
50
|
33
|
|
|
1711
|
next unless defined $t and length $t; |
322
|
|
|
|
|
|
|
# TODO: enforce some limitations on what a target name can be? |
323
|
570
|
|
|
|
|
1105
|
$this->{'accept_targets'}{$t} = $type; |
324
|
570
|
|
|
|
|
791
|
DEBUG > 2 and print STDERR "Learning to accept \"$t\" as target of type $type\n"; |
325
|
|
|
|
|
|
|
} |
326
|
311
|
50
|
|
|
|
611
|
return sort keys %{ $this->{'accept_targets'} } if wantarray; |
|
0
|
|
|
|
|
0
|
|
327
|
311
|
|
|
|
|
570
|
return; |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
#-------------------------------------------------------------------------- |
331
|
0
|
|
|
0
|
1
|
0
|
sub unaccept_target { shift->unaccept_targets(@_) } |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
sub unaccept_targets { |
334
|
0
|
|
|
0
|
1
|
0
|
my $this = shift; |
335
|
0
|
|
|
|
|
0
|
foreach my $t (@_) { |
336
|
0
|
0
|
0
|
|
|
0
|
next unless defined $t and length $t; |
337
|
|
|
|
|
|
|
# TODO: enforce some limitations on what a target name can be? |
338
|
0
|
|
|
|
|
0
|
delete $this->{'accept_targets'}{$t}; |
339
|
0
|
|
|
|
|
0
|
DEBUG > 2 and print STDERR "OK, won't accept \"$t\" as target.\n"; |
340
|
|
|
|
|
|
|
} |
341
|
0
|
0
|
|
|
|
0
|
return sort keys %{ $this->{'accept_targets'} } if wantarray; |
|
0
|
|
|
|
|
0
|
|
342
|
0
|
|
|
|
|
0
|
return; |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
346
|
|
|
|
|
|
|
# |
347
|
|
|
|
|
|
|
# And now codes (not targets or directives) |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
# XXX Probably it is an error that the digit '9' is excluded from these re's. |
350
|
|
|
|
|
|
|
# Broken for early Perls on EBCDIC |
351
|
|
|
|
|
|
|
my $xml_name_re = my_qr('[^-.0-8:A-Z_a-z[:^ascii:]]', '9'); |
352
|
|
|
|
|
|
|
$xml_name_re = qr/[\x00-\x2C\x2F\x39\x3B-\x40\x5B-\x5E\x60\x7B-\x7F]/ |
353
|
|
|
|
|
|
|
unless $xml_name_re; |
354
|
|
|
|
|
|
|
|
355
|
0
|
|
|
0
|
1
|
0
|
sub accept_code { shift->accept_codes(@_) } # alias |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
sub accept_codes { # Add some codes |
358
|
337
|
|
|
337
|
1
|
643
|
my $this = shift; |
359
|
|
|
|
|
|
|
|
360
|
337
|
|
|
|
|
611
|
foreach my $new_code (@_) { |
361
|
1211
|
50
|
33
|
|
|
3222
|
next unless defined $new_code and length $new_code; |
362
|
|
|
|
|
|
|
# A good-enough check that it's good as an XML Name symbol: |
363
|
1211
|
50
|
33
|
|
|
6909
|
Carp::croak "\"$new_code\" isn't a valid element name" |
|
|
|
33
|
|
|
|
|
364
|
|
|
|
|
|
|
if $new_code =~ $xml_name_re |
365
|
|
|
|
|
|
|
# Characters under 0x80 that aren't legal in an XML Name. |
366
|
|
|
|
|
|
|
or $new_code =~ m/^[-\.0-9]/s |
367
|
|
|
|
|
|
|
or $new_code =~ m/:[-\.0-9]/s; |
368
|
|
|
|
|
|
|
# The legal under-0x80 Name characters that |
369
|
|
|
|
|
|
|
# an XML Name still can't start with. |
370
|
|
|
|
|
|
|
|
371
|
1211
|
|
|
|
|
2707
|
$this->{'accept_codes'}{$new_code} = $new_code; |
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
# Yes, map to itself -- just so that when we |
374
|
|
|
|
|
|
|
# see "=extend W [whatever] thatelementname", we say that W maps |
375
|
|
|
|
|
|
|
# to whatever $this->{accept_codes}{thatelementname} is, |
376
|
|
|
|
|
|
|
# i.e., "thatelementname". Then when we go re-mapping, |
377
|
|
|
|
|
|
|
# a "W" in the treelet turns into "thatelementname". We only |
378
|
|
|
|
|
|
|
# remap once. |
379
|
|
|
|
|
|
|
# If we say we accept "W", then a "W" in the treelet simply turns |
380
|
|
|
|
|
|
|
# into "W". |
381
|
|
|
|
|
|
|
} |
382
|
|
|
|
|
|
|
|
383
|
337
|
|
|
|
|
598
|
return; |
384
|
|
|
|
|
|
|
} |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
#-------------------------------------------------------------------------- |
387
|
0
|
|
|
0
|
1
|
0
|
sub unaccept_code { shift->unaccept_codes(@_) } |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
sub unaccept_codes { # remove some codes |
390
|
29
|
|
|
29
|
1
|
152
|
my $this = shift; |
391
|
|
|
|
|
|
|
|
392
|
29
|
|
|
|
|
69
|
foreach my $new_code (@_) { |
393
|
29
|
50
|
33
|
|
|
101
|
next unless defined $new_code and length $new_code; |
394
|
|
|
|
|
|
|
# A good-enough check that it's good as an XML Name symbol: |
395
|
29
|
50
|
33
|
|
|
275
|
Carp::croak "\"$new_code\" isn't a valid element name" |
|
|
|
33
|
|
|
|
|
396
|
|
|
|
|
|
|
if $new_code =~ $xml_name_re |
397
|
|
|
|
|
|
|
# Characters under 0x80 that aren't legal in an XML Name. |
398
|
|
|
|
|
|
|
or $new_code =~ m/^[-\.0-9]/s |
399
|
|
|
|
|
|
|
or $new_code =~ m/:[-\.0-9]/s; |
400
|
|
|
|
|
|
|
# The legal under-0x80 Name characters that |
401
|
|
|
|
|
|
|
# an XML Name still can't start with. |
402
|
|
|
|
|
|
|
|
403
|
29
|
50
|
|
|
|
114
|
Carp::croak "But you must accept \"$new_code\" codes -- it's a builtin!" |
404
|
|
|
|
|
|
|
if grep $new_code eq $_, @Known_formatting_codes; |
405
|
|
|
|
|
|
|
|
406
|
29
|
|
|
|
|
56
|
delete $this->{'accept_codes'}{$new_code}; |
407
|
|
|
|
|
|
|
|
408
|
29
|
|
|
|
|
55
|
DEBUG > 2 and print STDERR "OK, won't accept the code $new_code<...>.\n"; |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
|
411
|
29
|
|
|
|
|
47
|
return; |
412
|
|
|
|
|
|
|
} |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
416
|
|
|
|
|
|
|
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
sub parse_string_document { |
419
|
761
|
|
|
761
|
1
|
11807
|
my $self = shift; |
420
|
761
|
|
|
|
|
1033
|
my @lines; |
421
|
761
|
|
|
|
|
1360
|
foreach my $line_group (@_) { |
422
|
761
|
100
|
66
|
|
|
2954
|
next unless defined $line_group and length $line_group; |
423
|
743
|
|
|
|
|
1957
|
pos($line_group) = 0; |
424
|
743
|
|
|
|
|
4243
|
while($line_group =~ |
425
|
|
|
|
|
|
|
m/([^\n\r]*)(\r?\n?)/g # supports \r, \n ,\r\n |
426
|
|
|
|
|
|
|
#m/([^\n\r]*)((?:\r?\n)?)/g |
427
|
|
|
|
|
|
|
) { |
428
|
|
|
|
|
|
|
#print(">> $1\n"), |
429
|
8508
|
100
|
100
|
|
|
39078
|
$self->parse_lines($1) |
|
|
|
66
|
|
|
|
|
430
|
|
|
|
|
|
|
if length($1) or length($2) |
431
|
|
|
|
|
|
|
or pos($line_group) != length($line_group); |
432
|
|
|
|
|
|
|
# I.e., unless it's a zero-length "empty line" at the very |
433
|
|
|
|
|
|
|
# end of "foo\nbar\n" (i.e., between the \n and the EOS). |
434
|
|
|
|
|
|
|
} |
435
|
|
|
|
|
|
|
} |
436
|
761
|
|
|
|
|
2258
|
$self->parse_lines(undef); # to signal EOF |
437
|
761
|
|
|
|
|
2233
|
return $self; |
438
|
|
|
|
|
|
|
} |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
sub _init_fh_source { |
441
|
51
|
|
|
51
|
|
117
|
my($self, $source) = @_; |
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
#DEBUG > 1 and print STDERR "Declaring $source as :raw for starters\n"; |
444
|
|
|
|
|
|
|
#$self->_apply_binmode($source, ':raw'); |
445
|
|
|
|
|
|
|
#binmode($source, ":raw"); |
446
|
|
|
|
|
|
|
|
447
|
51
|
|
|
|
|
101
|
return; |
448
|
|
|
|
|
|
|
} |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
#:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:. |
451
|
|
|
|
|
|
|
# |
452
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
sub parse_file { |
454
|
51
|
|
|
51
|
1
|
348
|
my($self, $source) = (@_); |
455
|
|
|
|
|
|
|
|
456
|
51
|
50
|
|
|
|
275
|
if(!defined $source) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
457
|
0
|
|
|
|
|
0
|
Carp::croak("Can't use empty-string as a source for parse_file"); |
458
|
|
|
|
|
|
|
} elsif(ref(\$source) eq 'GLOB') { |
459
|
0
|
|
|
|
|
0
|
$self->{'source_filename'} = '' . ($source); |
460
|
|
|
|
|
|
|
} elsif(ref $source) { |
461
|
0
|
|
|
|
|
0
|
$self->{'source_filename'} = '' . ($source); |
462
|
|
|
|
|
|
|
} elsif(!length $source) { |
463
|
0
|
|
|
|
|
0
|
Carp::croak("Can't use empty-string as a source for parse_file"); |
464
|
|
|
|
|
|
|
} else { |
465
|
|
|
|
|
|
|
{ |
466
|
51
|
|
|
|
|
105
|
local *PODSOURCE; |
|
51
|
|
|
|
|
119
|
|
467
|
51
|
50
|
|
|
|
1943
|
open(PODSOURCE, "<$source") || Carp::croak("Can't open $source: $!"); |
468
|
51
|
|
|
|
|
297
|
$self->{'source_filename'} = $source; |
469
|
51
|
|
|
|
|
172
|
$source = *PODSOURCE{IO}; |
470
|
|
|
|
|
|
|
} |
471
|
51
|
|
|
|
|
275
|
$self->_init_fh_source($source); |
472
|
|
|
|
|
|
|
} |
473
|
|
|
|
|
|
|
# By here, $source is a FH. |
474
|
|
|
|
|
|
|
|
475
|
51
|
|
|
|
|
110
|
$self->{'source_fh'} = $source; |
476
|
|
|
|
|
|
|
|
477
|
51
|
|
|
|
|
91
|
my($i, @lines); |
478
|
51
|
|
|
|
|
131
|
until( $self->{'source_dead'} ) { |
479
|
490
|
|
|
|
|
1460
|
splice @lines; |
480
|
|
|
|
|
|
|
|
481
|
490
|
|
|
|
|
1046
|
for($i = MANY_LINES; $i--;) { # read those many lines at a time |
482
|
9326
|
|
|
|
|
16797
|
local $/ = $NL; |
483
|
9326
|
|
|
|
|
21075
|
push @lines, scalar(<$source>); # readline |
484
|
9326
|
100
|
|
|
|
23413
|
last unless defined $lines[-1]; |
485
|
|
|
|
|
|
|
# but pass thru the undef, which will set source_dead to true |
486
|
|
|
|
|
|
|
} |
487
|
|
|
|
|
|
|
|
488
|
490
|
|
|
|
|
767
|
my $at_eof = ! $lines[-1]; # keep track of the undef |
489
|
490
|
100
|
|
|
|
822
|
pop @lines if $at_eof; # silence warnings |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
# be eol agnostic |
492
|
490
|
|
|
|
|
2796
|
s/\r\n?/\n/g for @lines; |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
# make sure there are only one line elements for parse_lines |
495
|
490
|
|
|
|
|
22585
|
@lines = split(/(?<=\n)/, join('', @lines)); |
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
# push the undef back after popping it to set source_dead to true |
498
|
490
|
100
|
|
|
|
1014
|
push @lines, undef if $at_eof; |
499
|
|
|
|
|
|
|
|
500
|
490
|
|
|
|
|
1368
|
$self->parse_lines(@lines); |
501
|
|
|
|
|
|
|
} |
502
|
51
|
|
|
|
|
117
|
delete($self->{'source_fh'}); # so it can be GC'd |
503
|
51
|
|
|
|
|
970
|
return $self; |
504
|
|
|
|
|
|
|
} |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
#:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:. |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
sub parse_from_file { |
509
|
|
|
|
|
|
|
# An emulation of Pod::Parser's interface, for the sake of Perldoc. |
510
|
|
|
|
|
|
|
# Basically just a wrapper around parse_file. |
511
|
|
|
|
|
|
|
|
512
|
10
|
|
|
10
|
1
|
30
|
my($self, $source, $to) = @_; |
513
|
10
|
50
|
|
|
|
22
|
$self = $self->new unless ref($self); # so we tolerate being a class method |
514
|
|
|
|
|
|
|
|
515
|
10
|
50
|
33
|
|
|
112
|
if(!defined $source) { $source = *STDIN{IO} |
|
|
50
|
33
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
516
|
0
|
|
|
|
|
0
|
} elsif(ref(\$source) eq 'GLOB') { # stet |
517
|
|
|
|
|
|
|
} elsif(ref($source) ) { # stet |
518
|
|
|
|
|
|
|
} elsif(!length $source |
519
|
|
|
|
|
|
|
or $source eq '-' or $source =~ m/^<&(?:STDIN|0)$/i |
520
|
|
|
|
|
|
|
) { |
521
|
0
|
|
|
|
|
0
|
$source = *STDIN{IO}; |
522
|
|
|
|
|
|
|
} |
523
|
|
|
|
|
|
|
|
524
|
10
|
50
|
33
|
|
|
93
|
if(!defined $to) { $self->output_fh( *STDOUT{IO} ); |
|
0
|
50
|
33
|
|
|
0
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
525
|
0
|
|
|
|
|
0
|
} elsif(ref(\$to) eq 'GLOB') { $self->output_fh( $to ); |
526
|
0
|
|
|
|
|
0
|
} elsif(ref($to)) { $self->output_fh( $to ); |
527
|
|
|
|
|
|
|
} elsif(!length $to |
528
|
|
|
|
|
|
|
or $to eq '-' or $to =~ m/^>&?(?:STDOUT|1)$/i |
529
|
|
|
|
|
|
|
) { |
530
|
0
|
|
|
|
|
0
|
$self->output_fh( *STDOUT{IO} ); |
531
|
|
|
|
|
|
|
} elsif($to =~ m/^>&(?:STDERR|2)$/i) { |
532
|
0
|
|
|
|
|
0
|
$self->output_fh( *STDERR{IO} ); |
533
|
|
|
|
|
|
|
} else { |
534
|
10
|
|
|
|
|
69
|
require Symbol; |
535
|
10
|
|
|
|
|
57
|
my $out_fh = Symbol::gensym(); |
536
|
10
|
|
|
|
|
140
|
DEBUG and print STDERR "Write-opening to $to\n"; |
537
|
10
|
50
|
|
|
|
692
|
open($out_fh, ">$to") or Carp::croak "Can't write-open $to: $!"; |
538
|
10
|
50
|
33
|
|
|
99
|
binmode($out_fh) |
539
|
|
|
|
|
|
|
if $self->can('write_with_binmode') and $self->write_with_binmode; |
540
|
10
|
|
|
|
|
32
|
$self->output_fh($out_fh); |
541
|
|
|
|
|
|
|
} |
542
|
|
|
|
|
|
|
|
543
|
10
|
|
|
|
|
55
|
return $self->parse_file($source); |
544
|
|
|
|
|
|
|
} |
545
|
|
|
|
|
|
|
|
546
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
sub whine { |
549
|
|
|
|
|
|
|
#my($self,$line,$complaint) = @_; |
550
|
79
|
|
|
79
|
1
|
154
|
my $self = shift(@_); |
551
|
79
|
|
|
|
|
175
|
++$self->{'errors_seen'}; |
552
|
79
|
100
|
|
|
|
220
|
if($self->{'no_whining'}) { |
553
|
9
|
|
|
|
|
14
|
DEBUG > 9 and print STDERR "Discarding complaint (at line $_[0]) $_[1]\n because no_whining is on.\n"; |
554
|
9
|
|
|
|
|
18
|
return; |
555
|
|
|
|
|
|
|
} |
556
|
70
|
|
|
|
|
106
|
push @{$self->{'all_errata'}{$_[0]}}, $_[1]; |
|
70
|
|
|
|
|
290
|
|
557
|
70
|
50
|
|
|
|
196
|
return $self->_complain_warn(@_) if $self->{'complain_stderr'}; |
558
|
70
|
|
|
|
|
285
|
return $self->_complain_errata(@_); |
559
|
|
|
|
|
|
|
} |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
sub scream { # like whine, but not suppressible |
562
|
|
|
|
|
|
|
#my($self,$line,$complaint) = @_; |
563
|
8
|
|
|
8
|
1
|
25
|
my $self = shift(@_); |
564
|
8
|
|
|
|
|
21
|
++$self->{'errors_seen'}; |
565
|
8
|
|
|
|
|
14
|
push @{$self->{'all_errata'}{$_[0]}}, $_[1]; |
|
8
|
|
|
|
|
43
|
|
566
|
8
|
50
|
|
|
|
32
|
return $self->_complain_warn(@_) if $self->{'complain_stderr'}; |
567
|
8
|
|
|
|
|
71
|
return $self->_complain_errata(@_); |
568
|
|
|
|
|
|
|
} |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
sub _complain_warn { |
571
|
0
|
|
|
0
|
|
0
|
my($self,$line,$complaint) = @_; |
572
|
|
|
|
|
|
|
return printf STDERR "%s around line %s: %s\n", |
573
|
0
|
|
0
|
|
|
0
|
$self->{'source_filename'} || 'Pod input', $line, $complaint; |
574
|
|
|
|
|
|
|
} |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
sub _complain_errata { |
577
|
78
|
|
|
78
|
|
232
|
my($self,$line,$complaint) = @_; |
578
|
78
|
100
|
|
|
|
182
|
if( $self->{'no_errata_section'} ) { |
579
|
10
|
|
|
|
|
15
|
DEBUG > 9 and print STDERR "Discarding erratum (at line $line) $complaint\n because no_errata_section is on.\n"; |
580
|
|
|
|
|
|
|
} else { |
581
|
68
|
|
|
|
|
86
|
DEBUG > 9 and print STDERR "Queuing erratum (at line $line) $complaint\n"; |
582
|
68
|
|
|
|
|
97
|
push @{$self->{'errata'}{$line}}, $complaint |
|
68
|
|
|
|
|
284
|
|
583
|
|
|
|
|
|
|
# for a report to be generated later! |
584
|
|
|
|
|
|
|
} |
585
|
78
|
|
|
|
|
504
|
return 1; |
586
|
|
|
|
|
|
|
} |
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
589
|
|
|
|
|
|
|
|
590
|
|
|
|
|
|
|
sub _get_initial_item_type { |
591
|
|
|
|
|
|
|
# A hack-wrapper here for when you have like "=over\n\n=item 456\n\n" |
592
|
185
|
|
|
185
|
|
397
|
my($self, $para) = @_; |
593
|
185
|
50
|
|
|
|
499
|
return $para->[1]{'~type'} if $para->[1]{'~type'}; |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
return $para->[1]{'~type'} = 'text' |
596
|
185
|
100
|
100
|
|
|
524
|
if join("\n", @{$para}[2 .. $#$para]) =~ m/^\s*(\d+)\.?\s*$/s and $1 ne '1'; |
|
185
|
|
|
|
|
1233
|
|
597
|
|
|
|
|
|
|
# Else fall thru to the general case: |
598
|
183
|
|
|
|
|
703
|
return $self->_get_item_type($para); |
599
|
|
|
|
|
|
|
} |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
sub _get_item_type { # mutates the item!! |
604
|
1205
|
|
|
1205
|
|
2301
|
my($self, $para) = @_; |
605
|
1205
|
100
|
|
|
|
2483
|
return $para->[1]{'~type'} if $para->[1]{'~type'}; |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
# Otherwise we haven't yet been to this node. Maybe alter it... |
609
|
|
|
|
|
|
|
|
610
|
1020
|
|
|
|
|
1744
|
my $content = join "\n", @{$para}[2 .. $#$para]; |
|
1020
|
|
|
|
|
2076
|
|
611
|
|
|
|
|
|
|
|
612
|
1020
|
100
|
100
|
|
|
6222
|
if($content =~ m/^\s*\*\s*$/s or $content =~ m/^\s*$/s) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
613
|
|
|
|
|
|
|
# Like: "=item *", "=item * ", "=item" |
614
|
59
|
|
|
|
|
133
|
splice @$para, 2; # so it ends up just being ['=item', { attrhash } ] |
615
|
59
|
|
|
|
|
128
|
$para->[1]{'~orig_content'} = $content; |
616
|
59
|
|
|
|
|
192
|
return $para->[1]{'~type'} = 'bullet'; |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
} elsif($content =~ m/^\s*\*\s+(.+)/s) { # tolerance |
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
# Like: "=item * Foo bar baz"; |
621
|
101
|
|
|
|
|
253
|
$para->[1]{'~orig_content'} = $content; |
622
|
101
|
|
|
|
|
243
|
$para->[1]{'~_freaky_para_hack'} = $1; |
623
|
101
|
|
|
|
|
111
|
DEBUG > 2 and print STDERR " Tolerating $$para[2] as =item *\\n\\n$1\n"; |
624
|
101
|
|
|
|
|
344
|
splice @$para, 2; # so it ends up just being ['=item', { attrhash } ] |
625
|
101
|
|
|
|
|
362
|
return $para->[1]{'~type'} = 'bullet'; |
626
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
} elsif($content =~ m/^\s*(\d+)\.?\s*$/s) { |
628
|
|
|
|
|
|
|
# Like: "=item 1.", "=item 123412" |
629
|
|
|
|
|
|
|
|
630
|
31
|
|
|
|
|
73
|
$para->[1]{'~orig_content'} = $content; |
631
|
31
|
|
|
|
|
92
|
$para->[1]{'number'} = $1; # Yes, stores the number there! |
632
|
|
|
|
|
|
|
|
633
|
31
|
|
|
|
|
62
|
splice @$para, 2; # so it ends up just being ['=item', { attrhash } ] |
634
|
31
|
|
|
|
|
126
|
return $para->[1]{'~type'} = 'number'; |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
} else { |
637
|
|
|
|
|
|
|
# It's anything else. |
638
|
829
|
|
|
|
|
2669
|
return $para->[1]{'~type'} = 'text'; |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
} |
641
|
|
|
|
|
|
|
} |
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
644
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
sub _make_treelet { |
646
|
4443
|
|
|
4443
|
|
6475
|
my $self = shift; # and ($para, $start_line) |
647
|
4443
|
|
|
|
|
5130
|
my $treelet; |
648
|
4443
|
50
|
|
|
|
7774
|
if(!@_) { |
649
|
0
|
|
|
|
|
0
|
return ['']; |
650
|
4443
|
50
|
33
|
|
|
10248
|
} if(ref $_[0] and ref $_[0][0] and $_[0][0][0] eq '~Top') { |
|
|
|
33
|
|
|
|
|
651
|
|
|
|
|
|
|
# Hack so we can pass in fake-o pre-cooked paragraphs: |
652
|
|
|
|
|
|
|
# just have the first line be a reference to a ['~Top', {}, ...] |
653
|
|
|
|
|
|
|
# We use this feechure in gen_errata and stuff. |
654
|
|
|
|
|
|
|
|
655
|
0
|
|
|
|
|
0
|
DEBUG and print STDERR "Applying precooked treelet hack to $_[0][0]\n"; |
656
|
0
|
|
|
|
|
0
|
$treelet = $_[0][0]; |
657
|
0
|
|
|
|
|
0
|
splice @$treelet, 0, 2; # lop the top off |
658
|
0
|
|
|
|
|
0
|
return $treelet; |
659
|
|
|
|
|
|
|
} else { |
660
|
4443
|
|
|
|
|
10643
|
$treelet = $self->_treelet_from_formatting_codes(@_); |
661
|
|
|
|
|
|
|
} |
662
|
|
|
|
|
|
|
|
663
|
4443
|
100
|
100
|
|
|
13242
|
if( ! $self->{'_output_is_for_JustPod'} # Retain these as-is for pod output |
664
|
|
|
|
|
|
|
&& $self->_remap_sequences($treelet) ) |
665
|
|
|
|
|
|
|
{ |
666
|
1080
|
|
|
|
|
2857
|
$self->_treat_Zs($treelet); # Might as well nix these first |
667
|
1080
|
|
|
|
|
2452
|
$self->_treat_Ls($treelet); # L has to precede E and S |
668
|
1080
|
|
|
|
|
2657
|
$self->_treat_Es($treelet); |
669
|
1080
|
|
|
|
|
2532
|
$self->_treat_Ss($treelet); # S has to come after E |
670
|
1080
|
|
|
|
|
2024
|
$self->_wrap_up($treelet); # Nix X's and merge texties |
671
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
} else { |
673
|
3363
|
|
|
|
|
3862
|
DEBUG and print STDERR "Formatless treelet gets fast-tracked.\n"; |
674
|
|
|
|
|
|
|
# Very common case! |
675
|
|
|
|
|
|
|
} |
676
|
|
|
|
|
|
|
|
677
|
4443
|
|
|
|
|
7093
|
splice @$treelet, 0, 2; # lop the top off |
678
|
|
|
|
|
|
|
|
679
|
4443
|
|
|
|
|
14270
|
return $treelet; |
680
|
|
|
|
|
|
|
} |
681
|
|
|
|
|
|
|
|
682
|
|
|
|
|
|
|
#:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:. |
683
|
|
|
|
|
|
|
|
684
|
|
|
|
|
|
|
sub _wrap_up { |
685
|
1080
|
|
|
1080
|
|
1641
|
my($self, @stack) = @_; |
686
|
1080
|
|
|
|
|
1503
|
my $nixx = $self->{'nix_X_codes'}; |
687
|
1080
|
|
|
|
|
1472
|
my $merge = $self->{'merge_text' }; |
688
|
1080
|
100
|
100
|
|
|
2434
|
return unless $nixx or $merge; |
689
|
|
|
|
|
|
|
|
690
|
739
|
|
|
|
|
719
|
DEBUG > 2 and print STDERR "\nStarting _wrap_up traversal.\n", |
691
|
|
|
|
|
|
|
$merge ? (" Merge mode on\n") : (), |
692
|
|
|
|
|
|
|
$nixx ? (" Nix-X mode on\n") : (), |
693
|
|
|
|
|
|
|
; |
694
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
|
696
|
739
|
|
|
|
|
1005
|
my($i, $treelet); |
697
|
739
|
|
|
|
|
1148
|
while($treelet = shift @stack) { |
698
|
2717
|
|
|
|
|
2717
|
DEBUG > 3 and print STDERR " Considering children of this $treelet->[0] node...\n"; |
699
|
2717
|
|
|
|
|
4076
|
for($i = 2; $i < @$treelet; ++$i) { # iterate over children |
700
|
6192
|
|
|
|
|
5459
|
DEBUG > 3 and print STDERR " Considering child at $i ", pretty($treelet->[$i]), "\n"; |
701
|
6192
|
100
|
100
|
|
|
24929
|
if($nixx and ref $treelet->[$i] and $treelet->[$i][0] eq 'X') { |
|
|
100
|
100
|
|
|
|
|
|
|
100
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
702
|
6
|
|
|
|
|
9
|
DEBUG > 3 and print STDERR " Nixing X node at $i\n"; |
703
|
6
|
|
|
|
|
9
|
splice(@$treelet, $i, 1); # just nix this node (and its descendants) |
704
|
|
|
|
|
|
|
# no need to back-update the counter just yet |
705
|
6
|
|
|
|
|
11
|
redo; |
706
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
} elsif($merge and $i != 2 and # non-initial |
708
|
|
|
|
|
|
|
!ref $treelet->[$i] and !ref $treelet->[$i - 1] |
709
|
|
|
|
|
|
|
) { |
710
|
25
|
|
|
|
|
29
|
DEBUG > 3 and print STDERR " Merging ", $i-1, |
711
|
|
|
|
|
|
|
":[$treelet->[$i-1]] and $i\:[$treelet->[$i]]\n"; |
712
|
25
|
|
|
|
|
50
|
$treelet->[$i-1] .= ( splice(@$treelet, $i, 1) )[0]; |
713
|
25
|
|
|
|
|
28
|
DEBUG > 4 and print STDERR " Now: ", $i-1, ":[$treelet->[$i-1]]\n"; |
714
|
25
|
|
|
|
|
26
|
--$i; |
715
|
25
|
|
|
|
|
55
|
next; |
716
|
|
|
|
|
|
|
# since we just pulled the possibly last node out from under |
717
|
|
|
|
|
|
|
# ourselves, we can't just redo() |
718
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
} elsif( ref $treelet->[$i] ) { |
720
|
1742
|
|
|
|
|
1656
|
DEBUG > 4 and print STDERR " Enqueuing ", pretty($treelet->[$i]), " for traversal.\n"; |
721
|
1742
|
|
|
|
|
1951
|
push @stack, $treelet->[$i]; |
722
|
|
|
|
|
|
|
|
723
|
1742
|
100
|
|
|
|
3165
|
if($treelet->[$i][0] eq 'L') { |
724
|
206
|
|
|
|
|
236
|
my $thing; |
725
|
206
|
|
|
|
|
293
|
foreach my $attrname ('section', 'to') { |
726
|
412
|
100
|
66
|
|
|
1159
|
if(defined($thing = $treelet->[$i][1]{$attrname}) and ref $thing) { |
727
|
236
|
|
|
|
|
320
|
unshift @stack, $thing; |
728
|
|
|
|
|
|
|
DEBUG > 4 and print STDERR " +Enqueuing ", |
729
|
236
|
|
|
|
|
467
|
pretty( $treelet->[$i][1]{$attrname} ), |
730
|
|
|
|
|
|
|
" as an attribute value to tweak.\n"; |
731
|
|
|
|
|
|
|
} |
732
|
|
|
|
|
|
|
} |
733
|
|
|
|
|
|
|
} |
734
|
|
|
|
|
|
|
} |
735
|
|
|
|
|
|
|
} |
736
|
|
|
|
|
|
|
} |
737
|
739
|
|
|
|
|
770
|
DEBUG > 2 and print STDERR "End of _wrap_up traversal.\n\n"; |
738
|
|
|
|
|
|
|
|
739
|
739
|
|
|
|
|
965
|
return; |
740
|
|
|
|
|
|
|
} |
741
|
|
|
|
|
|
|
|
742
|
|
|
|
|
|
|
#:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:. |
743
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
sub _remap_sequences { |
745
|
3581
|
|
|
3581
|
|
6170
|
my($self,@stack) = @_; |
746
|
|
|
|
|
|
|
|
747
|
3581
|
100
|
66
|
|
|
6723
|
if(@stack == 1 and @{ $stack[0] } == 3 and !ref $stack[0][2]) { |
|
3581
|
|
100
|
|
|
12494
|
|
748
|
|
|
|
|
|
|
# VERY common case: abort it. |
749
|
2501
|
|
|
|
|
2757
|
DEBUG and print STDERR "Skipping _remap_sequences: formatless treelet.\n"; |
750
|
2501
|
|
|
|
|
6843
|
return 0; |
751
|
|
|
|
|
|
|
} |
752
|
|
|
|
|
|
|
|
753
|
1080
|
|
50
|
|
|
2505
|
my $map = ($self->{'accept_codes'} || die "NO accept_codes in $self?!?"); |
754
|
|
|
|
|
|
|
|
755
|
1080
|
|
|
|
|
1587
|
my $start_line = $stack[0][1]{'start_line'}; |
756
|
1080
|
|
|
|
|
1132
|
DEBUG > 2 and printf |
757
|
|
|
|
|
|
|
"\nAbout to start _remap_sequences on treelet from line %s.\n", |
758
|
|
|
|
|
|
|
$start_line || '[?]' |
759
|
|
|
|
|
|
|
; |
760
|
|
|
|
|
|
|
DEBUG > 3 and print STDERR " Map: ", |
761
|
|
|
|
|
|
|
join('; ', map "$_=" . ( |
762
|
1080
|
|
|
|
|
1068
|
ref($map->{$_}) ? join(",", @{$map->{$_}}) : $map->{$_} |
763
|
|
|
|
|
|
|
), |
764
|
|
|
|
|
|
|
sort keys %$map ), |
765
|
|
|
|
|
|
|
("B~C~E~F~I~L~S~X~Z" eq join '~', sort keys %$map) |
766
|
|
|
|
|
|
|
? " (all normal)\n" : "\n" |
767
|
|
|
|
|
|
|
; |
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
# A recursive algorithm implemented iteratively! Whee! |
770
|
|
|
|
|
|
|
|
771
|
1080
|
|
|
|
|
1525
|
my($is, $was, $i, $treelet); # scratch |
772
|
1080
|
|
|
|
|
2016
|
while($treelet = shift @stack) { |
773
|
3478
|
|
|
|
|
3694
|
DEBUG > 3 and print STDERR " Considering children of this $treelet->[0] node...\n"; |
774
|
3478
|
|
|
|
|
5351
|
for($i = 2; $i < @$treelet; ++$i) { # iterate over children |
775
|
7551
|
100
|
|
|
|
14982
|
next unless ref $treelet->[$i]; # text nodes are uninteresting |
776
|
|
|
|
|
|
|
|
777
|
2404
|
|
|
|
|
2358
|
DEBUG > 4 and print STDERR " Noting child $i : $treelet->[$i][0]<...>\n"; |
778
|
|
|
|
|
|
|
|
779
|
2404
|
|
|
|
|
4294
|
$is = $treelet->[$i][0] = $map->{ $was = $treelet->[$i][0] }; |
780
|
2404
|
|
|
|
|
2424
|
if( DEBUG > 3 ) { |
781
|
|
|
|
|
|
|
if(!defined $is) { |
782
|
|
|
|
|
|
|
print STDERR " Code $was<> is UNKNOWN!\n"; |
783
|
|
|
|
|
|
|
} elsif($is eq $was) { |
784
|
|
|
|
|
|
|
DEBUG > 4 and print STDERR " Code $was<> stays the same.\n"; |
785
|
|
|
|
|
|
|
} else { |
786
|
|
|
|
|
|
|
print STDERR " Code $was<> maps to ", |
787
|
|
|
|
|
|
|
ref($is) |
788
|
|
|
|
|
|
|
? ( "tags ", map("$_<", @$is), '...', map('>', @$is), "\n" ) |
789
|
|
|
|
|
|
|
: "tag $is<...>.\n"; |
790
|
|
|
|
|
|
|
} |
791
|
|
|
|
|
|
|
} |
792
|
|
|
|
|
|
|
|
793
|
2404
|
100
|
|
|
|
3519
|
if(!defined $is) { |
794
|
4
|
|
|
|
|
23
|
$self->whine($start_line, "Deleting unknown formatting code $was<>"); |
795
|
4
|
|
|
|
|
8
|
$is = $treelet->[$i][0] = '1'; # But saving the children! |
796
|
|
|
|
|
|
|
# I could also insert a leading "$was<" and tailing ">" as |
797
|
|
|
|
|
|
|
# children of this node, but something about that seems icky. |
798
|
|
|
|
|
|
|
} |
799
|
2404
|
100
|
|
|
|
4673
|
if(ref $is) { |
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
800
|
2
|
|
|
|
|
5
|
my @dynasty = @$is; |
801
|
2
|
|
|
|
|
3
|
DEBUG > 4 and print STDERR " Renaming $was node to $dynasty[-1]\n"; |
802
|
2
|
|
|
|
|
3
|
$treelet->[$i][0] = pop @dynasty; |
803
|
2
|
|
|
|
|
2
|
my $nugget; |
804
|
2
|
|
|
|
|
6
|
while(@dynasty) { |
805
|
3
|
|
|
|
|
3
|
DEBUG > 4 and printf |
806
|
|
|
|
|
|
|
" Grafting a new %s node between %s and %s\n", |
807
|
|
|
|
|
|
|
$dynasty[-1], $treelet->[0], $treelet->[$i][0], |
808
|
|
|
|
|
|
|
; |
809
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
#$nugget = ; |
811
|
3
|
|
|
|
|
12
|
splice @$treelet, $i, 1, [pop(@dynasty), {}, $treelet->[$i]]; |
812
|
|
|
|
|
|
|
# relace node with a new parent |
813
|
|
|
|
|
|
|
} |
814
|
|
|
|
|
|
|
} elsif($is eq '0') { |
815
|
0
|
|
|
|
|
0
|
splice(@$treelet, $i, 1); # just nix this node (and its descendants) |
816
|
0
|
|
|
|
|
0
|
--$i; # back-update the counter |
817
|
|
|
|
|
|
|
} elsif($is eq '1') { |
818
|
|
|
|
|
|
|
splice(@$treelet, $i, 1 # replace this node with its children! |
819
|
4
|
|
|
|
|
5
|
=> splice @{ $treelet->[$i] },2 |
|
4
|
|
|
|
|
25
|
|
820
|
|
|
|
|
|
|
# (not catching its first two (non-child) items) |
821
|
|
|
|
|
|
|
); |
822
|
4
|
|
|
|
|
13
|
--$i; # back up for new stuff |
823
|
|
|
|
|
|
|
} else { |
824
|
|
|
|
|
|
|
# otherwise it's unremarkable |
825
|
2398
|
|
|
|
|
4753
|
unshift @stack, $treelet->[$i]; # just recurse |
826
|
|
|
|
|
|
|
} |
827
|
|
|
|
|
|
|
} |
828
|
|
|
|
|
|
|
} |
829
|
|
|
|
|
|
|
|
830
|
1080
|
|
|
|
|
1195
|
DEBUG > 2 and print STDERR "End of _remap_sequences traversal.\n\n"; |
831
|
|
|
|
|
|
|
|
832
|
1080
|
50
|
66
|
|
|
1970
|
if(@_ == 2 and @{ $_[1] } == 3 and !ref $_[1][2]) { |
|
1080
|
|
66
|
|
|
3103
|
|
833
|
0
|
|
|
|
|
0
|
DEBUG and print STDERR "Noting that the treelet is now formatless.\n"; |
834
|
0
|
|
|
|
|
0
|
return 0; |
835
|
|
|
|
|
|
|
} |
836
|
1080
|
|
|
|
|
2934
|
return 1; |
837
|
|
|
|
|
|
|
} |
838
|
|
|
|
|
|
|
|
839
|
|
|
|
|
|
|
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
840
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
sub _ponder_extend { |
842
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
# "Go to an extreme, move back to a more comfortable place" |
844
|
|
|
|
|
|
|
# -- /Oblique Strategies/, Brian Eno and Peter Schmidt |
845
|
|
|
|
|
|
|
|
846
|
21
|
|
|
21
|
|
34
|
my($self, $para) = @_; |
847
|
21
|
|
|
|
|
56
|
my $content = join ' ', splice @$para, 2; |
848
|
21
|
|
|
|
|
82
|
$content =~ s/^\s+//s; |
849
|
21
|
|
|
|
|
55
|
$content =~ s/\s+$//s; |
850
|
|
|
|
|
|
|
|
851
|
21
|
|
|
|
|
23
|
DEBUG > 2 and print STDERR "Ogling extensor: =extend $content\n"; |
852
|
|
|
|
|
|
|
|
853
|
21
|
50
|
|
|
|
75
|
if($content =~ |
854
|
|
|
|
|
|
|
m/^ |
855
|
|
|
|
|
|
|
(\S+) # 1 : new item |
856
|
|
|
|
|
|
|
\s+ |
857
|
|
|
|
|
|
|
(\S+) # 2 : fallback(s) |
858
|
|
|
|
|
|
|
(?:\s+(\S+))? # 3 : element name(s) |
859
|
|
|
|
|
|
|
\s* |
860
|
|
|
|
|
|
|
$ |
861
|
|
|
|
|
|
|
/xs |
862
|
|
|
|
|
|
|
) { |
863
|
21
|
|
|
|
|
42
|
my $new_letter = $1; |
864
|
21
|
|
|
|
|
26
|
my $fallbacks_one = $2; |
865
|
21
|
|
|
|
|
25
|
my $elements_one; |
866
|
21
|
50
|
|
|
|
49
|
$elements_one = defined($3) ? $3 : $1; |
867
|
|
|
|
|
|
|
|
868
|
21
|
|
|
|
|
22
|
DEBUG > 2 and print STDERR "Extensor has good syntax.\n"; |
869
|
|
|
|
|
|
|
|
870
|
21
|
50
|
33
|
|
|
54
|
unless($new_letter =~ m/^[A-Z]$/s or $new_letter) { |
871
|
0
|
|
|
|
|
0
|
DEBUG > 2 and print STDERR " $new_letter isn't a valid thing to entend.\n"; |
872
|
|
|
|
|
|
|
$self->whine( |
873
|
0
|
|
|
|
|
0
|
$para->[1]{'start_line'}, |
874
|
|
|
|
|
|
|
"You can extend only formatting codes A-Z, not like \"$new_letter\"" |
875
|
|
|
|
|
|
|
); |
876
|
0
|
|
|
|
|
0
|
return; |
877
|
|
|
|
|
|
|
} |
878
|
|
|
|
|
|
|
|
879
|
21
|
50
|
|
|
|
76
|
if(grep $new_letter eq $_, @Known_formatting_codes) { |
880
|
0
|
|
|
|
|
0
|
DEBUG > 2 and print STDERR " $new_letter isn't a good thing to extend, because known.\n"; |
881
|
|
|
|
|
|
|
$self->whine( |
882
|
0
|
|
|
|
|
0
|
$para->[1]{'start_line'}, |
883
|
|
|
|
|
|
|
"You can't extend an established code like \"$new_letter\"" |
884
|
|
|
|
|
|
|
); |
885
|
|
|
|
|
|
|
|
886
|
|
|
|
|
|
|
#TODO: or allow if last bit is same? |
887
|
|
|
|
|
|
|
|
888
|
0
|
|
|
|
|
0
|
return; |
889
|
|
|
|
|
|
|
} |
890
|
|
|
|
|
|
|
|
891
|
21
|
0
|
33
|
|
|
231
|
unless($fallbacks_one =~ m/^[A-Z](,[A-Z])*$/s # like "B", "M,I", etc. |
|
|
|
33
|
|
|
|
|
892
|
|
|
|
|
|
|
or $fallbacks_one eq '0' or $fallbacks_one eq '1' |
893
|
|
|
|
|
|
|
) { |
894
|
|
|
|
|
|
|
$self->whine( |
895
|
0
|
|
|
|
|
0
|
$para->[1]{'start_line'}, |
896
|
|
|
|
|
|
|
"Format for second =extend parameter must be like" |
897
|
|
|
|
|
|
|
. " M or 1 or 0 or M,N or M,N,O but you have it like " |
898
|
|
|
|
|
|
|
. $fallbacks_one |
899
|
|
|
|
|
|
|
); |
900
|
0
|
|
|
|
|
0
|
return; |
901
|
|
|
|
|
|
|
} |
902
|
|
|
|
|
|
|
|
903
|
21
|
50
|
|
|
|
81
|
unless($elements_one =~ m/^[^ ,]+(,[^ ,]+)*$/s) { # like "B", "M,I", etc. |
904
|
|
|
|
|
|
|
$self->whine( |
905
|
0
|
|
|
|
|
0
|
$para->[1]{'start_line'}, |
906
|
|
|
|
|
|
|
"Format for third =extend parameter: like foo or bar,Baz,qu:ux but not like " |
907
|
|
|
|
|
|
|
. $elements_one |
908
|
|
|
|
|
|
|
); |
909
|
0
|
|
|
|
|
0
|
return; |
910
|
|
|
|
|
|
|
} |
911
|
|
|
|
|
|
|
|
912
|
21
|
|
|
|
|
51
|
my @fallbacks = split ',', $fallbacks_one, -1; |
913
|
21
|
|
|
|
|
40
|
my @elements = split ',', $elements_one, -1; |
914
|
|
|
|
|
|
|
|
915
|
21
|
|
|
|
|
36
|
foreach my $f (@fallbacks) { |
916
|
42
|
0
|
33
|
|
|
96
|
next if exists $Known_formatting_codes{$f} or $f eq '0' or $f eq '1'; |
|
|
|
33
|
|
|
|
|
917
|
0
|
|
|
|
|
0
|
DEBUG > 2 and print STDERR " Can't fall back on unknown code $f\n"; |
918
|
|
|
|
|
|
|
$self->whine( |
919
|
0
|
|
|
|
|
0
|
$para->[1]{'start_line'}, |
920
|
|
|
|
|
|
|
"Can't use unknown formatting code '$f' as a fallback for '$new_letter'" |
921
|
|
|
|
|
|
|
); |
922
|
0
|
|
|
|
|
0
|
return; |
923
|
|
|
|
|
|
|
} |
924
|
|
|
|
|
|
|
|
925
|
21
|
|
|
|
|
22
|
DEBUG > 3 and printf STDERR "Extensor: Fallbacks <%s> Elements <%s>.\n", |
926
|
|
|
|
|
|
|
@fallbacks, @elements; |
927
|
|
|
|
|
|
|
|
928
|
21
|
|
|
|
|
23
|
my $canonical_form; |
929
|
21
|
|
|
|
|
26
|
foreach my $e (@elements) { |
930
|
42
|
100
|
|
|
|
66
|
if(exists $self->{'accept_codes'}{$e}) { |
931
|
15
|
|
|
|
|
12
|
DEBUG > 1 and print STDERR " Mapping '$new_letter' to known extension '$e'\n"; |
932
|
15
|
|
|
|
|
112
|
$canonical_form = $e; |
933
|
15
|
|
|
|
|
22
|
last; # first acceptable elementname wins! |
934
|
|
|
|
|
|
|
} else { |
935
|
27
|
|
|
|
|
34
|
DEBUG > 1 and print STDERR " Can't map '$new_letter' to unknown extension '$e'\n"; |
936
|
|
|
|
|
|
|
} |
937
|
|
|
|
|
|
|
} |
938
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
|
940
|
21
|
100
|
|
|
|
27
|
if( defined $canonical_form ) { |
941
|
|
|
|
|
|
|
# We found a good N => elementname mapping |
942
|
15
|
|
|
|
|
34
|
$self->{'accept_codes'}{$new_letter} = $canonical_form; |
943
|
15
|
|
|
|
|
26
|
DEBUG > 2 and print |
944
|
|
|
|
|
|
|
"Extensor maps $new_letter => known element $canonical_form.\n"; |
945
|
|
|
|
|
|
|
} else { |
946
|
|
|
|
|
|
|
# We have to use the fallback(s), which might be '0', or '1'. |
947
|
6
|
100
|
|
|
|
16
|
$self->{'accept_codes'}{$new_letter} |
948
|
|
|
|
|
|
|
= (@fallbacks == 1) ? $fallbacks[0] : \@fallbacks; |
949
|
6
|
|
|
|
|
13
|
DEBUG > 2 and print |
950
|
|
|
|
|
|
|
"Extensor maps $new_letter => fallbacks @fallbacks.\n"; |
951
|
|
|
|
|
|
|
} |
952
|
|
|
|
|
|
|
|
953
|
|
|
|
|
|
|
} else { |
954
|
0
|
|
|
|
|
0
|
DEBUG > 2 and print STDERR "Extensor has bad syntax.\n"; |
955
|
|
|
|
|
|
|
$self->whine( |
956
|
0
|
|
|
|
|
0
|
$para->[1]{'start_line'}, |
957
|
|
|
|
|
|
|
"Unknown =extend syntax: $content" |
958
|
|
|
|
|
|
|
) |
959
|
|
|
|
|
|
|
} |
960
|
21
|
|
|
|
|
36
|
return; |
961
|
|
|
|
|
|
|
} |
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
|
964
|
|
|
|
|
|
|
#:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:.:. |
965
|
|
|
|
|
|
|
|
966
|
|
|
|
|
|
|
sub _treat_Zs { # Nix Z<...>'s |
967
|
1080
|
|
|
1080
|
|
1708
|
my($self,@stack) = @_; |
968
|
|
|
|
|
|
|
|
969
|
1080
|
|
|
|
|
1307
|
my($i, $treelet); |
970
|
1080
|
|
|
|
|
1640
|
my $start_line = $stack[0][1]{'start_line'}; |
971
|
|
|
|
|
|
|
|
972
|
|
|
|
|
|
|
# A recursive algorithm implemented iteratively! Whee! |
973
|
|
|
|
|
|
|
|
974
|
1080
|
|
|
|
|
1835
|
while($treelet = shift @stack) { |
975
|
3446
|
|
|
|
|
5760
|
for($i = 2; $i < @$treelet; ++$i) { # iterate over children |
976
|
7515
|
100
|
|
|
|
14095
|
next unless ref $treelet->[$i]; # text nodes are uninteresting |
977
|
2403
|
100
|
|
|
|
4145
|
unless($treelet->[$i][0] eq 'Z') { |
978
|
2366
|
|
|
|
|
2858
|
unshift @stack, $treelet->[$i]; # recurse |
979
|
2366
|
|
|
|
|
3691
|
next; |
980
|
|
|
|
|
|
|
} |
981
|
|
|
|
|
|
|
|
982
|
37
|
|
|
|
|
46
|
DEBUG > 1 and print STDERR "Nixing Z node @{$treelet->[$i]}\n"; |
983
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
# bitch UNLESS it's empty |
985
|
37
|
50
|
33
|
|
|
54
|
unless( @{$treelet->[$i]} == 2 |
|
37
|
|
33
|
|
|
90
|
|
986
|
37
|
|
|
|
|
142
|
or (@{$treelet->[$i]} == 3 and $treelet->[$i][2] eq '') |
987
|
|
|
|
|
|
|
) { |
988
|
0
|
|
|
|
|
0
|
$self->whine( $start_line, "A non-empty Z<>" ); |
989
|
|
|
|
|
|
|
} # but kill it anyway |
990
|
|
|
|
|
|
|
|
991
|
37
|
|
|
|
|
66
|
splice(@$treelet, $i, 1); # thereby just nix this node. |
992
|
37
|
|
|
|
|
95
|
--$i; |
993
|
|
|
|
|
|
|
|
994
|
|
|
|
|
|
|
} |
995
|
|
|
|
|
|
|
} |
996
|
|
|
|
|
|
|
|
997
|
1080
|
|
|
|
|
1473
|
return; |
998
|
|
|
|
|
|
|
} |
999
|
|
|
|
|
|
|
|
1000
|
|
|
|
|
|
|
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
1001
|
|
|
|
|
|
|
|
1002
|
|
|
|
|
|
|
# Quoting perlpodspec: |
1003
|
|
|
|
|
|
|
|
1004
|
|
|
|
|
|
|
# In parsing an L<...> code, Pod parsers must distinguish at least four |
1005
|
|
|
|
|
|
|
# attributes: |
1006
|
|
|
|
|
|
|
|
1007
|
|
|
|
|
|
|
############# Not used. Expressed via the element children plus |
1008
|
|
|
|
|
|
|
############# the value of the "content-implicit" flag. |
1009
|
|
|
|
|
|
|
# First: |
1010
|
|
|
|
|
|
|
# The link-text. If there is none, this must be undef. (E.g., in "L
|
1011
|
|
|
|
|
|
|
# Functions|perlfunc>", the link-text is "Perl Functions". In |
1012
|
|
|
|
|
|
|
# "L" and even "L<|Time::HiRes>", there is no link text. Note |
1013
|
|
|
|
|
|
|
# that link text may contain formatting.) |
1014
|
|
|
|
|
|
|
# |
1015
|
|
|
|
|
|
|
|
1016
|
|
|
|
|
|
|
############# The element children |
1017
|
|
|
|
|
|
|
# Second: |
1018
|
|
|
|
|
|
|
# The possibly inferred link-text -- i.e., if there was no real link text, |
1019
|
|
|
|
|
|
|
# then this is the text that we'll infer in its place. (E.g., for |
1020
|
|
|
|
|
|
|
# "L", the inferred link text is "Getopt::Std".) |
1021
|
|
|
|
|
|
|
# |
1022
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
############# The "to" attribute (which might be text, or a treelet) |
1024
|
|
|
|
|
|
|
# Third: |
1025
|
|
|
|
|
|
|
# The name or URL, or undef if none. (E.g., in "L
|
1026
|
|
|
|
|
|
|
# Functions|perlfunc>", the name -- also sometimes called the page -- is |
1027
|
|
|
|
|
|
|
# "perlfunc". In "L", the name is undef.) |
1028
|
|
|
|
|
|
|
# |
1029
|
|
|
|
|
|
|
|
1030
|
|
|
|
|
|
|
############# The "section" attribute (which might be next, or a treelet) |
1031
|
|
|
|
|
|
|
# Fourth: |
1032
|
|
|
|
|
|
|
# The section (AKA "item" in older perlpods), or undef if none. E.g., in |
1033
|
|
|
|
|
|
|
# Getopt::Std/DESCRIPTION, "DESCRIPTION" is the section. (Note that this |
1034
|
|
|
|
|
|
|
# is not the same as a manpage section like the "5" in "man 5 crontab". |
1035
|
|
|
|
|
|
|
# "Section Foo" in the Pod sense means the part of the text that's |
1036
|
|
|
|
|
|
|
# introduced by the heading or item whose text is "Foo".) |
1037
|
|
|
|
|
|
|
# |
1038
|
|
|
|
|
|
|
# Pod parsers may also note additional attributes including: |
1039
|
|
|
|
|
|
|
# |
1040
|
|
|
|
|
|
|
|
1041
|
|
|
|
|
|
|
############# The "type" attribute. |
1042
|
|
|
|
|
|
|
# Fifth: |
1043
|
|
|
|
|
|
|
# A flag for whether item 3 (if present) is a URL (like |
1044
|
|
|
|
|
|
|
# "http://lists.perl.org" is), in which case there should be no section |
1045
|
|
|
|
|
|
|
# attribute; a Pod name (like "perldoc" and "Getopt::Std" are); or |
1046
|
|
|
|
|
|
|
# possibly a man page name (like "crontab(5)" is). |
1047
|
|
|
|
|
|
|
# |
1048
|
|
|
|
|
|
|
|
1049
|
|
|
|
|
|
|
############# The "raw" attribute that is already there. |
1050
|
|
|
|
|
|
|
# Sixth: |
1051
|
|
|
|
|
|
|
# The raw original L<...> content, before text is split on "|", "/", etc, |
1052
|
|
|
|
|
|
|
# and before E<...> codes are expanded. |
1053
|
|
|
|
|
|
|
|
1054
|
|
|
|
|
|
|
|
1055
|
|
|
|
|
|
|
# For L<...> codes without a "name|" part, only E<...> and Z<> codes may |
1056
|
|
|
|
|
|
|
# occur -- no other formatting codes. That is, authors should not use |
1057
|
|
|
|
|
|
|
# "L>". |
1058
|
|
|
|
|
|
|
# |
1059
|
|
|
|
|
|
|
# Note, however, that formatting codes and Z<>'s can occur in any and all |
1060
|
|
|
|
|
|
|
# parts of an L<...> (i.e., in name, section, text, and url). |
1061
|
|
|
|
|
|
|
|
1062
|
|
|
|
|
|
|
sub _treat_Ls { # Process our dear dear friends, the L<...> sequences |
1063
|
|
|
|
|
|
|
|
1064
|
|
|
|
|
|
|
# L |
1065
|
|
|
|
|
|
|
# L or L |
1066
|
|
|
|
|
|
|
# L"sec"> or L or L<"sec"> |
1067
|
|
|
|
|
|
|
# L |
1068
|
|
|
|
|
|
|
# L or L |
1069
|
|
|
|
|
|
|
# L or L or L |
1070
|
|
|
|
|
|
|
# L |
1071
|
|
|
|
|
|
|
# L |
1072
|
|
|
|
|
|
|
|
1073
|
1080
|
|
|
1080
|
|
1686
|
my($self,@stack) = @_; |
1074
|
|
|
|
|
|
|
|
1075
|
1080
|
|
|
|
|
1386
|
my($i, $treelet); |
1076
|
1080
|
|
|
|
|
1649
|
my $start_line = $stack[0][1]{'start_line'}; |
1077
|
|
|
|
|
|
|
|
1078
|
|
|
|
|
|
|
# A recursive algorithm implemented iteratively! Whee! |
1079
|
|
|
|
|
|
|
|
1080
|
1080
|
|
|
|
|
1845
|
while($treelet = shift @stack) { |
1081
|
3236
|
|
|
|
|
5377
|
for(my $i = 2; $i < @$treelet; ++$i) { |
1082
|
|
|
|
|
|
|
# iterate over children of current tree node |
1083
|
7434
|
100
|
|
|
|
14803
|
next unless ref $treelet->[$i]; # text nodes are uninteresting |
1084
|
2334
|
100
|
|
|
|
3748
|
unless($treelet->[$i][0] eq 'L') { |
1085
|
1991
|
|
|
|
|
2364
|
unshift @stack, $treelet->[$i]; # recurse |
1086
|
1991
|
|
|
|
|
2993
|
next; |
1087
|
|
|
|
|
|
|
} |
1088
|
|
|
|
|
|
|
|
1089
|
|
|
|
|
|
|
|
1090
|
|
|
|
|
|
|
# By here, $treelet->[$i] is definitely an L node |
1091
|
343
|
|
|
|
|
542
|
my $ell = $treelet->[$i]; |
1092
|
343
|
|
|
|
|
396
|
DEBUG > 1 and print STDERR "Ogling L node " . pretty($ell) . "\n"; |
1093
|
|
|
|
|
|
|
|
1094
|
|
|
|
|
|
|
# bitch if it's empty or is just '/' |
1095
|
343
|
100
|
100
|
|
|
400
|
if (@{$ell} == 3 and $ell->[2] =~ m!\A\s*/\s*\z!) { |
|
343
|
|
|
|
|
1380
|
|
1096
|
1
|
|
|
|
|
5
|
$self->whine( $start_line, "L<> contains only '/'" ); |
1097
|
1
|
|
|
|
|
2
|
$treelet->[$i] = 'L>'; # just make it a text node |
1098
|
1
|
|
|
|
|
5
|
next; # and move on |
1099
|
|
|
|
|
|
|
} |
1100
|
342
|
50
|
66
|
|
|
467
|
if( @{$ell} == 2 |
|
342
|
|
33
|
|
|
760
|
|
1101
|
342
|
|
|
|
|
1094
|
or (@{$ell} == 3 and $ell->[2] eq '') |
1102
|
|
|
|
|
|
|
) { |
1103
|
0
|
|
|
|
|
0
|
$self->whine( $start_line, "An empty L<>" ); |
1104
|
0
|
|
|
|
|
0
|
$treelet->[$i] = 'L<>'; # just make it a text node |
1105
|
0
|
|
|
|
|
0
|
next; # and move on |
1106
|
|
|
|
|
|
|
} |
1107
|
|
|
|
|
|
|
|
1108
|
342
|
100
|
100
|
|
|
2399
|
if( (! ref $ell->[2] && $ell->[2] =~ /\A\s/) |
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
1109
|
|
|
|
|
|
|
||(! ref $ell->[-1] && $ell->[-1] =~ /\s\z/) |
1110
|
|
|
|
|
|
|
) { |
1111
|
2
|
|
|
|
|
13
|
$self->whine( $start_line, "L<> starts or ends with whitespace" ); |
1112
|
|
|
|
|
|
|
} |
1113
|
|
|
|
|
|
|
|
1114
|
|
|
|
|
|
|
# Catch URLs: |
1115
|
|
|
|
|
|
|
|
1116
|
|
|
|
|
|
|
# there are a number of possible cases: |
1117
|
|
|
|
|
|
|
# 1) text node containing url: http://foo.com |
1118
|
|
|
|
|
|
|
# -> [ 'http://foo.com' ] |
1119
|
|
|
|
|
|
|
# 2) text node containing url and text: foo|http://foo.com |
1120
|
|
|
|
|
|
|
# -> [ 'foo|http://foo.com' ] |
1121
|
|
|
|
|
|
|
# 3) text node containing url start: mailto:xEfoo.com |
1122
|
|
|
|
|
|
|
# -> [ 'mailto:x', [ E ... ], 'foo.com' ] |
1123
|
|
|
|
|
|
|
# 4) text node containing url start and text: foo|mailto:xEfoo.com |
1124
|
|
|
|
|
|
|
# -> [ 'foo|mailto:x', [ E ... ], 'foo.com' ] |
1125
|
|
|
|
|
|
|
# 5) other nodes containing text and url start: OE<39>Malley|http://foo.com |
1126
|
|
|
|
|
|
|
# -> [ 'O', [ E ... ], 'Malley', '|http://foo.com' ] |
1127
|
|
|
|
|
|
|
# ... etc. |
1128
|
|
|
|
|
|
|
|
1129
|
|
|
|
|
|
|
# anything before the url is part of the text. |
1130
|
|
|
|
|
|
|
# anything after it is part of the url. |
1131
|
|
|
|
|
|
|
# the url text node itself may contain parts of both. |
1132
|
|
|
|
|
|
|
|
1133
|
342
|
100
|
|
|
|
2068
|
if (my ($url_index, $text_part, $url_part) = |
1134
|
|
|
|
|
|
|
# grep is no good here; we want to bail out immediately so that we can |
1135
|
|
|
|
|
|
|
# use $1, $2, etc. without having to do the match twice. |
1136
|
|
|
|
|
|
|
sub { |
1137
|
342
|
|
|
342
|
|
1040
|
for (2..$#$ell) { |
1138
|
584
|
100
|
|
|
|
1116
|
next if ref $ell->[$_]; |
1139
|
448
|
100
|
|
|
|
1386
|
next unless $ell->[$_] =~ m/^(?:([^|]*)\|)?(\w+:[^:\s]\S*)$/s; |
1140
|
44
|
|
|
|
|
296
|
return ($_, $1, $2); |
1141
|
|
|
|
|
|
|
} |
1142
|
298
|
|
|
|
|
810
|
return; |
1143
|
|
|
|
|
|
|
}->() |
1144
|
|
|
|
|
|
|
) { |
1145
|
44
|
|
|
|
|
108
|
$ell->[1]{'type'} = 'url'; |
1146
|
|
|
|
|
|
|
|
1147
|
44
|
|
|
|
|
102
|
my @text = @{$ell}[2..$url_index-1]; |
|
44
|
|
|
|
|
115
|
|
1148
|
44
|
100
|
|
|
|
120
|
push @text, $text_part if defined $text_part; |
1149
|
|
|
|
|
|
|
|
1150
|
44
|
|
|
|
|
96
|
my @url = @{$ell}[$url_index+1..$#$ell]; |
|
44
|
|
|
|
|
83
|
|
1151
|
44
|
|
|
|
|
113
|
unshift @url, $url_part; |
1152
|
|
|
|
|
|
|
|
1153
|
44
|
100
|
|
|
|
120
|
unless (@text) { |
1154
|
30
|
|
|
|
|
58
|
$ell->[1]{'content-implicit'} = 'yes'; |
1155
|
30
|
|
|
|
|
59
|
@text = @url; |
1156
|
|
|
|
|
|
|
} |
1157
|
|
|
|
|
|
|
|
1158
|
44
|
100
|
|
|
|
382
|
$ell->[1]{to} = Pod::Simple::LinkSection->new( |
1159
|
|
|
|
|
|
|
@url == 1 |
1160
|
|
|
|
|
|
|
? $url[0] |
1161
|
|
|
|
|
|
|
: [ '', {}, @url ], |
1162
|
|
|
|
|
|
|
); |
1163
|
|
|
|
|
|
|
|
1164
|
44
|
|
|
|
|
181
|
splice @$ell, 2, $#$ell, @text; |
1165
|
|
|
|
|
|
|
|
1166
|
44
|
|
|
|
|
323
|
next; |
1167
|
|
|
|
|
|
|
} |
1168
|
|
|
|
|
|
|
|
1169
|
|
|
|
|
|
|
# Catch some very simple and/or common cases |
1170
|
298
|
100
|
66
|
|
|
1183
|
if(@{$ell} == 3 and ! ref $ell->[2]) { |
|
298
|
|
|
|
|
992
|
|
1171
|
223
|
|
|
|
|
334
|
my $it = $ell->[2]; |
1172
|
223
|
100
|
|
|
|
505
|
if($it =~ m{^[^/|]+[(][-a-zA-Z0-9]+[)]$}s) { # man sections |
1173
|
|
|
|
|
|
|
# Hopefully neither too broad nor too restrictive a RE |
1174
|
6
|
|
|
|
|
10
|
DEBUG > 1 and print STDERR "Catching \"$it\" as manpage link.\n"; |
1175
|
6
|
|
|
|
|
13
|
$ell->[1]{'type'} = 'man'; |
1176
|
|
|
|
|
|
|
# This's the only place where man links can get made. |
1177
|
6
|
|
|
|
|
12
|
$ell->[1]{'content-implicit'} = 'yes'; |
1178
|
6
|
|
|
|
|
48
|
$ell->[1]{'to' } = |
1179
|
|
|
|
|
|
|
Pod::Simple::LinkSection->new( $it ); # treelet! |
1180
|
|
|
|
|
|
|
|
1181
|
6
|
|
|
|
|
22
|
next; |
1182
|
|
|
|
|
|
|
} |
1183
|
217
|
100
|
|
|
|
890
|
if($it =~ m/^[^\/\|,\$\%\@\ \"\<\>\:\#\&\*\{\}\[\]\(\)]+(\:\:[^\/\|,\$\%\@\ \"\<\>\:\#\&\*\{\}\[\]\(\)]+)*$/s) { |
1184
|
|
|
|
|
|
|
# Extremely forgiving idea of what constitutes a bare |
1185
|
|
|
|
|
|
|
# modulename link like L or even L |
1186
|
127
|
|
|
|
|
151
|
DEBUG > 1 and print STDERR "Catching \"$it\" as ho-hum L link.\n"; |
1187
|
127
|
|
|
|
|
241
|
$ell->[1]{'type'} = 'pod'; |
1188
|
127
|
|
|
|
|
216
|
$ell->[1]{'content-implicit'} = 'yes'; |
1189
|
127
|
|
|
|
|
539
|
$ell->[1]{'to' } = |
1190
|
|
|
|
|
|
|
Pod::Simple::LinkSection->new( $it ); # treelet! |
1191
|
127
|
|
|
|
|
342
|
next; |
1192
|
|
|
|
|
|
|
} |
1193
|
|
|
|
|
|
|
# else fall thru... |
1194
|
|
|
|
|
|
|
} |
1195
|
|
|
|
|
|
|
|
1196
|
|
|
|
|
|
|
|
1197
|
|
|
|
|
|
|
|
1198
|
|
|
|
|
|
|
# ...Uhoh, here's the real L<...> parsing stuff... |
1199
|
|
|
|
|
|
|
# "With the ill behavior, with the ill behavior, with the ill behavior..." |
1200
|
|
|
|
|
|
|
|
1201
|
165
|
|
|
|
|
222
|
DEBUG > 1 and print STDERR "Running a real parse on this non-trivial L\n"; |
1202
|
|
|
|
|
|
|
|
1203
|
|
|
|
|
|
|
|
1204
|
165
|
|
|
|
|
207
|
my $link_text; # set to an arrayref if found |
1205
|
165
|
|
|
|
|
440
|
my @ell_content = @$ell; |
1206
|
165
|
|
|
|
|
321
|
splice @ell_content,0,2; # Knock off the 'L' and {} bits |
1207
|
|
|
|
|
|
|
|
1208
|
165
|
|
|
|
|
203
|
DEBUG > 3 and print STDERR " Ell content to start: ", |
1209
|
|
|
|
|
|
|
pretty(@ell_content), "\n"; |
1210
|
|
|
|
|
|
|
|
1211
|
|
|
|
|
|
|
|
1212
|
|
|
|
|
|
|
# Look for the "|" -- only in CHILDREN (not all underlings!) |
1213
|
|
|
|
|
|
|
# Like L |
1214
|
165
|
|
|
|
|
203
|
DEBUG > 3 and |
1215
|
|
|
|
|
|
|
print STDERR " Peering at L content for a '|' ...\n"; |
1216
|
165
|
|
|
|
|
416
|
for(my $j = 0; $j < @ell_content; ++$j) { |
1217
|
379
|
100
|
|
|
|
793
|
next if ref $ell_content[$j]; |
1218
|
260
|
|
|
|
|
297
|
DEBUG > 3 and |
1219
|
|
|
|
|
|
|
print STDERR " Peering at L-content text bit \"$ell_content[$j]\" for a '|'.\n"; |
1220
|
|
|
|
|
|
|
|
1221
|
260
|
100
|
|
|
|
826
|
if($ell_content[$j] =~ m/^([^\|]*)\|(.*)$/s) { |
1222
|
61
|
|
|
|
|
180
|
my @link_text = ($1); # might be 0-length |
1223
|
61
|
|
|
|
|
129
|
$ell_content[$j] = $2; # might be 0-length |
1224
|
|
|
|
|
|
|
|
1225
|
61
|
|
|
|
|
76
|
DEBUG > 3 and |
1226
|
|
|
|
|
|
|
print STDERR " FOUND a '|' in it. Splitting into [$1] + [$2]\n"; |
1227
|
|
|
|
|
|
|
|
1228
|
61
|
100
|
|
|
|
175
|
if ($link_text[0] =~ m{[|/]}) { |
1229
|
1
|
|
|
|
|
5
|
$self->whine( |
1230
|
|
|
|
|
|
|
$start_line, |
1231
|
|
|
|
|
|
|
"alternative text '$link_text[0]' contains non-escaped | or /" |
1232
|
|
|
|
|
|
|
); |
1233
|
|
|
|
|
|
|
} |
1234
|
|
|
|
|
|
|
|
1235
|
61
|
|
|
|
|
133
|
unshift @link_text, splice @ell_content, 0, $j; |
1236
|
|
|
|
|
|
|
# leaving only things at J and after |
1237
|
61
|
|
66
|
|
|
345
|
@ell_content = grep ref($_)||length($_), @ell_content ; |
1238
|
61
|
|
100
|
|
|
331
|
$link_text = [grep ref($_)||length($_), @link_text ]; |
1239
|
61
|
|
|
|
|
92
|
DEBUG > 3 and printf |
1240
|
|
|
|
|
|
|
" So link text is %s\n and remaining ell content is %s\n", |
1241
|
|
|
|
|
|
|
pretty($link_text), pretty(@ell_content); |
1242
|
61
|
|
|
|
|
173
|
last; |
1243
|
|
|
|
|
|
|
} |
1244
|
|
|
|
|
|
|
} |
1245
|
|
|
|
|
|
|
|
1246
|
|
|
|
|
|
|
|
1247
|
|
|
|
|
|
|
# Now look for the "/" -- only in CHILDREN (not all underlings!) |
1248
|
|
|
|
|
|
|
# And afterward, anything left in @ell_content will be the raw name |
1249
|
|
|
|
|
|
|
# Like L |
1250
|
165
|
|
|
|
|
236
|
my $section_name; # set to arrayref if found |
1251
|
165
|
|
|
|
|
203
|
DEBUG > 3 and print STDERR " Peering at L-content for a '/' ...\n"; |
1252
|
165
|
|
|
|
|
373
|
for(my $j = 0; $j < @ell_content; ++$j) { |
1253
|
218
|
100
|
|
|
|
494
|
next if ref $ell_content[$j]; |
1254
|
183
|
|
|
|
|
211
|
DEBUG > 3 and |
1255
|
|
|
|
|
|
|
print STDERR " Peering at L-content text bit \"$ell_content[$j]\" for a '/'.\n"; |
1256
|
|
|
|
|
|
|
|
1257
|
183
|
100
|
|
|
|
651
|
if($ell_content[$j] =~ m/^([^\/]*)\/(.*)$/s) { |
1258
|
100
|
|
|
|
|
302
|
my @section_name = ($2); # might be 0-length |
1259
|
100
|
|
|
|
|
200
|
$ell_content[$j] = $1; # might be 0-length |
1260
|
|
|
|
|
|
|
|
1261
|
100
|
|
|
|
|
138
|
DEBUG > 3 and |
1262
|
|
|
|
|
|
|
print STDERR " FOUND a '/' in it.", |
1263
|
|
|
|
|
|
|
" Splitting to page [...$1] + section [$2...]\n"; |
1264
|
|
|
|
|
|
|
|
1265
|
100
|
|
|
|
|
233
|
push @section_name, splice @ell_content, 1+$j; |
1266
|
|
|
|
|
|
|
# leaving only things before and including J |
1267
|
|
|
|
|
|
|
|
1268
|
100
|
|
100
|
|
|
488
|
@ell_content = grep ref($_)||length($_), @ell_content ; |
1269
|
100
|
|
100
|
|
|
508
|
@section_name = grep ref($_)||length($_), @section_name ; |
1270
|
|
|
|
|
|
|
|
1271
|
|
|
|
|
|
|
# Turn L<.../"foo"> into L<.../foo> |
1272
|
100
|
100
|
66
|
|
|
1024
|
if(@section_name |
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
1273
|
|
|
|
|
|
|
and !ref($section_name[0]) and !ref($section_name[-1]) |
1274
|
|
|
|
|
|
|
and $section_name[ 0] =~ m/^\"/s |
1275
|
|
|
|
|
|
|
and $section_name[-1] =~ m/\"$/s |
1276
|
|
|
|
|
|
|
and !( # catch weird degenerate case of L<"> ! |
1277
|
|
|
|
|
|
|
@section_name == 1 and $section_name[0] eq '"' |
1278
|
|
|
|
|
|
|
) |
1279
|
|
|
|
|
|
|
) { |
1280
|
40
|
|
|
|
|
157
|
$section_name[ 0] =~ s/^\"//s; |
1281
|
40
|
|
|
|
|
128
|
$section_name[-1] =~ s/\"$//s; |
1282
|
40
|
|
|
|
|
59
|
DEBUG > 3 and |
1283
|
|
|
|
|
|
|
print STDERR " Quotes removed: ", pretty(@section_name), "\n"; |
1284
|
|
|
|
|
|
|
} else { |
1285
|
60
|
|
|
|
|
94
|
DEBUG > 3 and |
1286
|
|
|
|
|
|
|
print STDERR " No need to remove quotes in ", pretty(@section_name), "\n"; |
1287
|
|
|
|
|
|
|
} |
1288
|
|
|
|
|
|
|
|
1289
|
100
|
|
|
|
|
170
|
$section_name = \@section_name; |
1290
|
100
|
|
|
|
|
200
|
last; |
1291
|
|
|
|
|
|
|
} |
1292
|
|
|
|
|
|
|
} |
1293
|
|
|
|
|
|
|
|
1294
|
|
|
|
|
|
|
# Turn L<"Foo Bar"> into L |
1295
|
165
|
50
|
66
|
|
|
1058
|
if(!$section_name and @ell_content |
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
1296
|
|
|
|
|
|
|
and !ref($ell_content[0]) and !ref($ell_content[-1]) |
1297
|
|
|
|
|
|
|
and $ell_content[ 0] =~ m/^\"/s |
1298
|
|
|
|
|
|
|
and $ell_content[-1] =~ m/\"$/s |
1299
|
|
|
|
|
|
|
and !( # catch weird degenerate case of L<"> ! |
1300
|
|
|
|
|
|
|
@ell_content == 1 and $ell_content[0] eq '"' |
1301
|
|
|
|
|
|
|
) |
1302
|
|
|
|
|
|
|
) { |
1303
|
19
|
|
|
|
|
61
|
$section_name = [splice @ell_content]; |
1304
|
19
|
|
|
|
|
80
|
$section_name->[ 0] =~ s/^\"//s; |
1305
|
19
|
|
|
|
|
72
|
$section_name->[-1] =~ s/\"$//s; |
1306
|
19
|
|
|
|
|
49
|
$ell->[1]{'~tolerated'} = 1; |
1307
|
|
|
|
|
|
|
} |
1308
|
|
|
|
|
|
|
|
1309
|
|
|
|
|
|
|
# Turn L into L. |
1310
|
165
|
100
|
100
|
|
|
802
|
if(!$section_name and !$link_text and @ell_content |
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
1311
|
|
|
|
|
|
|
and grep !ref($_) && m/ /s, @ell_content |
1312
|
|
|
|
|
|
|
) { |
1313
|
14
|
|
|
|
|
34
|
$section_name = [splice @ell_content]; |
1314
|
14
|
|
|
|
|
35
|
$ell->[1]{'~deprecated'} = 1; |
1315
|
|
|
|
|
|
|
# That's support for the now-deprecated syntax. |
1316
|
|
|
|
|
|
|
# Note that it deliberately won't work on L<...|Foo Bar> |
1317
|
|
|
|
|
|
|
} |
1318
|
|
|
|
|
|
|
|
1319
|
|
|
|
|
|
|
|
1320
|
|
|
|
|
|
|
# Now make up the link_text |
1321
|
|
|
|
|
|
|
# L -> L |
1322
|
|
|
|
|
|
|
# L -> L<"Bar"|Bar> |
1323
|
|
|
|
|
|
|
# L -> L<"Bar" in Foo/Foo> |
1324
|
165
|
100
|
|
|
|
345
|
unless($link_text) { |
1325
|
104
|
|
|
|
|
254
|
$ell->[1]{'content-implicit'} = 'yes'; |
1326
|
104
|
|
|
|
|
176
|
$link_text = []; |
1327
|
104
|
100
|
|
|
|
374
|
push @$link_text, '"', @$section_name, '"' if $section_name; |
1328
|
|
|
|
|
|
|
|
1329
|
104
|
100
|
|
|
|
222
|
if(@ell_content) { |
1330
|
51
|
100
|
|
|
|
140
|
$link_text->[-1] .= ' in ' if $section_name; |
1331
|
51
|
|
|
|
|
97
|
push @$link_text, @ell_content; |
1332
|
|
|
|
|
|
|
} |
1333
|
|
|
|
|
|
|
} |
1334
|
|
|
|
|
|
|
|
1335
|
|
|
|
|
|
|
|
1336
|
|
|
|
|
|
|
# And the E resolver will have to deal with all our treeletty things: |
1337
|
|
|
|
|
|
|
|
1338
|
165
|
100
|
66
|
|
|
687
|
if(@ell_content == 1 and !ref($ell_content[0]) |
|
|
|
100
|
|
|
|
|
1339
|
|
|
|
|
|
|
and $ell_content[0] =~ m{^[^/]+[(][-a-zA-Z0-9]+[)]$}s |
1340
|
|
|
|
|
|
|
) { |
1341
|
9
|
|
|
|
|
25
|
$ell->[1]{'type'} = 'man'; |
1342
|
9
|
|
|
|
|
14
|
DEBUG > 3 and print STDERR "Considering this ($ell_content[0]) a man link.\n"; |
1343
|
|
|
|
|
|
|
} else { |
1344
|
156
|
|
|
|
|
375
|
$ell->[1]{'type'} = 'pod'; |
1345
|
156
|
|
|
|
|
216
|
DEBUG > 3 and print STDERR "Considering this a pod link (not man or url).\n"; |
1346
|
|
|
|
|
|
|
} |
1347
|
|
|
|
|
|
|
|
1348
|
165
|
100
|
|
|
|
334
|
if( defined $section_name ) { |
1349
|
133
|
|
|
|
|
1041
|
$ell->[1]{'section'} = Pod::Simple::LinkSection->new( |
1350
|
|
|
|
|
|
|
['', {}, @$section_name] |
1351
|
|
|
|
|
|
|
); |
1352
|
133
|
|
|
|
|
354
|
DEBUG > 3 and print STDERR "L-section content: ", pretty($ell->[1]{'section'}), "\n"; |
1353
|
|
|
|
|
|
|
} |
1354
|
|
|
|
|
|
|
|
1355
|
165
|
100
|
|
|
|
346
|
if( @ell_content ) { |
1356
|
93
|
|
|
|
|
444
|
$ell->[1]{'to'} = Pod::Simple::LinkSection->new( |
1357
|
|
|
|
|
|
|
['', {}, @ell_content] |
1358
|
|
|
|
|
|
|
); |
1359
|
93
|
|
|
|
|
221
|
DEBUG > 3 and print STDERR "L-to content: ", pretty($ell->[1]{'to'}), "\n"; |
1360
|
|
|
|
|
|
|
} |
1361
|
|
|
|
|
|
|
|
1362
|
|
|
|
|
|
|
# And update children to be the link-text: |
1363
|
165
|
50
|
|
|
|
704
|
@$ell = (@$ell[0,1], defined($link_text) ? splice(@$link_text) : ''); |
1364
|
|
|
|
|
|
|
|
1365
|
165
|
|
|
|
|
224
|
DEBUG > 2 and print STDERR "End of L-parsing for this node " . pretty($treelet->[$i]) . "\n"; |
1366
|
|
|
|
|
|
|
|
1367
|
165
|
|
|
|
|
695
|
unshift @stack, $treelet->[$i]; # might as well recurse |
1368
|
|
|
|
|
|
|
} |
1369
|
|
|
|
|
|
|
} |
1370
|
|
|
|
|
|
|
|
1371
|
1080
|
|
|
|
|
1438
|
return; |
1372
|
|
|
|
|
|
|
} |
1373
|
|
|
|
|
|
|
|
1374
|
|
|
|
|
|
|
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
1375
|
|
|
|
|
|
|
|
1376
|
|
|
|
|
|
|
sub _treat_Es { |
1377
|
1080
|
|
|
1080
|
|
1750
|
my($self,@stack) = @_; |
1378
|
|
|
|
|
|
|
|
1379
|
1080
|
|
|
|
|
1410
|
my($i, $treelet, $content, $replacer, $charnum); |
1380
|
1080
|
|
|
|
|
1521
|
my $start_line = $stack[0][1]{'start_line'}; |
1381
|
|
|
|
|
|
|
|
1382
|
|
|
|
|
|
|
# A recursive algorithm implemented iteratively! Whee! |
1383
|
|
|
|
|
|
|
|
1384
|
|
|
|
|
|
|
|
1385
|
|
|
|
|
|
|
# Has frightening side effects on L nodes' attributes. |
1386
|
|
|
|
|
|
|
|
1387
|
|
|
|
|
|
|
#my @ells_to_tweak; |
1388
|
|
|
|
|
|
|
|
1389
|
1080
|
|
|
|
|
1934
|
while($treelet = shift @stack) { |
1390
|
3676
|
|
|
|
|
6027
|
for(my $i = 2; $i < @$treelet; ++$i) { # iterate over children |
1391
|
8105
|
100
|
|
|
|
16996
|
next unless ref $treelet->[$i]; # text nodes are uninteresting |
1392
|
2477
|
100
|
|
|
|
4764
|
if($treelet->[$i][0] eq 'L') { |
|
|
100
|
|
|
|
|
|
1393
|
|
|
|
|
|
|
# SPECIAL STUFF for semi-processed L<>'s |
1394
|
|
|
|
|
|
|
|
1395
|
342
|
|
|
|
|
504
|
my $thing; |
1396
|
342
|
|
|
|
|
561
|
foreach my $attrname ('section', 'to') { |
1397
|
684
|
100
|
66
|
|
|
2091
|
if(defined($thing = $treelet->[$i][1]{$attrname}) and ref $thing) { |
1398
|
403
|
|
|
|
|
574
|
unshift @stack, $thing; |
1399
|
|
|
|
|
|
|
DEBUG > 2 and print STDERR " Enqueuing ", |
1400
|
403
|
|
|
|
|
536
|
pretty( $treelet->[$i][1]{$attrname} ), |
1401
|
|
|
|
|
|
|
" as an attribute value to tweak.\n"; |
1402
|
|
|
|
|
|
|
} |
1403
|
|
|
|
|
|
|
} |
1404
|
|
|
|
|
|
|
|
1405
|
342
|
|
|
|
|
551
|
unshift @stack, $treelet->[$i]; # recurse |
1406
|
342
|
|
|
|
|
942
|
next; |
1407
|
|
|
|
|
|
|
} elsif($treelet->[$i][0] ne 'E') { |
1408
|
1851
|
|
|
|
|
2218
|
unshift @stack, $treelet->[$i]; # recurse |
1409
|
1851
|
|
|
|
|
2839
|
next; |
1410
|
|
|
|
|
|
|
} |
1411
|
|
|
|
|
|
|
|
1412
|
284
|
|
|
|
|
335
|
DEBUG > 1 and print STDERR "Ogling E node ", pretty($treelet->[$i]), "\n"; |
1413
|
|
|
|
|
|
|
|
1414
|
|
|
|
|
|
|
# bitch if it's empty |
1415
|
284
|
50
|
33
|
|
|
357
|
if( @{$treelet->[$i]} == 2 |
|
284
|
|
33
|
|
|
670
|
|
1416
|
284
|
|
|
|
|
1063
|
or (@{$treelet->[$i]} == 3 and $treelet->[$i][2] eq '') |
1417
|
|
|
|
|
|
|
) { |
1418
|
0
|
|
|
|
|
0
|
$self->whine( $start_line, "An empty E<>" ); |
1419
|
0
|
|
|
|
|
0
|
$treelet->[$i] = 'E<>'; # splice in a literal |
1420
|
0
|
|
|
|
|
0
|
next; |
1421
|
|
|
|
|
|
|
} |
1422
|
|
|
|
|
|
|
|
1423
|
|
|
|
|
|
|
# bitch if content is weird |
1424
|
284
|
50
|
33
|
|
|
399
|
unless(@{$treelet->[$i]} == 3 and !ref($content = $treelet->[$i][2])) { |
|
284
|
|
|
|
|
1058
|
|
1425
|
0
|
|
|
|
|
0
|
$self->whine( $start_line, "An E<...> surrounding strange content" ); |
1426
|
0
|
|
|
|
|
0
|
$replacer = $treelet->[$i]; # scratch |
1427
|
0
|
|
|
|
|
0
|
splice(@$treelet, $i, 1, # fake out a literal |
1428
|
|
|
|
|
|
|
'E<', |
1429
|
|
|
|
|
|
|
splice(@$replacer,2), # promote its content |
1430
|
|
|
|
|
|
|
'>' |
1431
|
|
|
|
|
|
|
); |
1432
|
|
|
|
|
|
|
# Don't need to do --$i, as the 'E<' we just added isn't interesting. |
1433
|
0
|
|
|
|
|
0
|
next; |
1434
|
|
|
|
|
|
|
} |
1435
|
|
|
|
|
|
|
|
1436
|
284
|
|
|
|
|
384
|
DEBUG > 1 and print STDERR "Ogling E<$content>\n"; |
1437
|
|
|
|
|
|
|
|
1438
|
|
|
|
|
|
|
# XXX E<>'s contents *should* be a valid char in the scope of the current |
1439
|
|
|
|
|
|
|
# =encoding directive. Defaults to iso-8859-1, I believe. Fix this in the |
1440
|
|
|
|
|
|
|
# future sometime. |
1441
|
|
|
|
|
|
|
|
1442
|
284
|
|
|
|
|
739
|
$charnum = Pod::Escapes::e2charnum($content); |
1443
|
284
|
|
|
|
|
3402
|
DEBUG > 1 and print STDERR " Considering E<$content> with char ", |
1444
|
|
|
|
|
|
|
defined($charnum) ? $charnum : "undef", ".\n"; |
1445
|
|
|
|
|
|
|
|
1446
|
284
|
100
|
100
|
|
|
883
|
if(!defined( $charnum )) { |
|
|
50
|
|
|
|
|
|
1447
|
6
|
|
|
|
|
8
|
DEBUG > 1 and print STDERR "I don't know how to deal with E<$content>.\n"; |
1448
|
6
|
|
|
|
|
21
|
$self->whine( $start_line, "Unknown E content in E<$content>" ); |
1449
|
6
|
|
|
|
|
14
|
$replacer = "E<$content>"; # better than nothing |
1450
|
|
|
|
|
|
|
} elsif($charnum >= 255 and !UNICODE) { |
1451
|
0
|
|
|
|
|
0
|
$replacer = ASCII ? "\xA4" : "?"; |
1452
|
0
|
|
|
|
|
0
|
DEBUG > 1 and print STDERR "This Perl version can't handle ", |
1453
|
|
|
|
|
|
|
"E<$content> (chr $charnum), so replacing with $replacer\n"; |
1454
|
|
|
|
|
|
|
} else { |
1455
|
278
|
|
|
|
|
610
|
$replacer = Pod::Escapes::e2char($content); |
1456
|
278
|
|
|
|
|
3698
|
DEBUG > 1 and print STDERR " Replacing E<$content> with $replacer\n"; |
1457
|
|
|
|
|
|
|
} |
1458
|
|
|
|
|
|
|
|
1459
|
284
|
|
|
|
|
1104
|
splice(@$treelet, $i, 1, $replacer); # no need to back up $i, tho |
1460
|
|
|
|
|
|
|
} |
1461
|
|
|
|
|
|
|
} |
1462
|
|
|
|
|
|
|
|
1463
|
1080
|
|
|
|
|
1488
|
return; |
1464
|
|
|
|
|
|
|
} |
1465
|
|
|
|
|
|
|
|
1466
|
|
|
|
|
|
|
|
1467
|
|
|
|
|
|
|
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
1468
|
|
|
|
|
|
|
|
1469
|
|
|
|
|
|
|
sub _treat_Ss { |
1470
|
1080
|
|
|
1080
|
|
1588
|
my($self,$treelet) = @_; |
1471
|
|
|
|
|
|
|
|
1472
|
1080
|
100
|
|
|
|
2521
|
_change_S_to_nbsp($treelet,0) if $self->{'nbsp_for_S'}; |
1473
|
|
|
|
|
|
|
|
1474
|
|
|
|
|
|
|
# TODO: or a change_nbsp_to_S |
1475
|
|
|
|
|
|
|
# Normalizing nbsp's to S is harder: for each text node, make S content |
1476
|
|
|
|
|
|
|
# out of anything matching m/([^ \xA0]*(?:\xA0+[^ \xA0]*)+)/ |
1477
|
|
|
|
|
|
|
|
1478
|
|
|
|
|
|
|
|
1479
|
1080
|
|
|
|
|
1400
|
return; |
1480
|
|
|
|
|
|
|
} |
1481
|
|
|
|
|
|
|
|
1482
|
|
|
|
|
|
|
sub _change_S_to_nbsp { # a recursive function |
1483
|
|
|
|
|
|
|
# Sanely assumes that the top node in the excursion won't be an S node. |
1484
|
1680
|
|
|
1680
|
|
2046
|
my($treelet, $in_s) = @_; |
1485
|
|
|
|
|
|
|
|
1486
|
1680
|
|
|
|
|
2034
|
my $is_s = ('S' eq $treelet->[0]); |
1487
|
1680
|
|
100
|
|
|
4173
|
$in_s ||= $is_s; # So in_s is on either by this being an S element, |
1488
|
|
|
|
|
|
|
# or by an ancestor being an S element. |
1489
|
|
|
|
|
|
|
|
1490
|
1680
|
|
|
|
|
2479
|
for(my $i = 2; $i < @$treelet; ++$i) { |
1491
|
3964
|
100
|
|
|
|
4896
|
if(ref $treelet->[$i]) { |
1492
|
1175
|
100
|
|
|
|
1534
|
if( _change_S_to_nbsp( $treelet->[$i], $in_s ) ) { |
1493
|
12
|
|
|
|
|
22
|
my $to_pull_up = $treelet->[$i]; |
1494
|
12
|
|
|
|
|
32
|
splice @$to_pull_up,0,2; # ...leaving just its content |
1495
|
12
|
|
|
|
|
31
|
splice @$treelet, $i, 1, @$to_pull_up; # Pull up content |
1496
|
12
|
|
|
|
|
39
|
$i += @$to_pull_up - 1; # Make $i skip the pulled-up stuff |
1497
|
|
|
|
|
|
|
} |
1498
|
|
|
|
|
|
|
} else { |
1499
|
2789
|
100
|
|
|
|
4681
|
$treelet->[$i] =~ s/\s/$Pod::Simple::nbsp/g if $in_s; |
1500
|
|
|
|
|
|
|
|
1501
|
|
|
|
|
|
|
# Note that if you apply nbsp_for_S to text, and so turn |
1502
|
|
|
|
|
|
|
# "foo S quux" into "foo bar faz quux", you |
1503
|
|
|
|
|
|
|
# end up with something that fails to say "and don't hyphenate |
1504
|
|
|
|
|
|
|
# any part of 'bar baz'". However, hyphenation is such a vexing |
1505
|
|
|
|
|
|
|
# problem anyway, that most Pod renderers just don't render it |
1506
|
|
|
|
|
|
|
# at all. But if you do want to implement hyphenation, I guess |
1507
|
|
|
|
|
|
|
# that you'd better have nbsp_for_S off. |
1508
|
|
|
|
|
|
|
} |
1509
|
|
|
|
|
|
|
} |
1510
|
|
|
|
|
|
|
|
1511
|
1680
|
|
|
|
|
3287
|
return $is_s; |
1512
|
|
|
|
|
|
|
} |
1513
|
|
|
|
|
|
|
|
1514
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
1515
|
|
|
|
|
|
|
|
1516
|
|
|
|
|
|
|
sub _accessorize { # A simple-minded method-maker |
1517
|
67
|
|
|
67
|
|
786
|
no strict 'refs'; |
|
67
|
|
|
|
|
141
|
|
|
67
|
|
|
|
|
5907
|
|
1518
|
102
|
|
|
102
|
|
293
|
foreach my $attrname (@_) { |
1519
|
2500
|
100
|
|
|
|
5179
|
next if $attrname =~ m/::/; # a hack |
1520
|
2398
|
|
|
|
|
8706
|
*{caller() . '::' . $attrname} = sub { |
1521
|
67
|
|
|
67
|
|
495
|
use strict; |
|
67
|
|
|
|
|
252
|
|
|
67
|
|
|
|
|
40004
|
|
1522
|
10508
|
50
|
66
|
10508
|
|
38704
|
$Carp::CarpLevel = 1, Carp::croak( |
|
|
|
33
|
|
|
|
|
1523
|
|
|
|
|
|
|
"Accessor usage: \$obj->$attrname() or \$obj->$attrname(\$new_value)" |
1524
|
|
|
|
|
|
|
) unless (@_ == 1 or @_ == 2) and ref $_[0]; |
1525
|
|
|
|
|
|
|
|
1526
|
|
|
|
|
|
|
(@_ == 1) ? $_[0]->{$attrname} |
1527
|
10508
|
100
|
|
|
|
30614
|
: ($_[0]->{$attrname} = $_[1]); |
1528
|
2398
|
|
|
|
|
6326
|
}; |
1529
|
|
|
|
|
|
|
} |
1530
|
|
|
|
|
|
|
# Ya know, they say accessories make the ensemble! |
1531
|
102
|
|
|
|
|
247
|
return; |
1532
|
|
|
|
|
|
|
} |
1533
|
|
|
|
|
|
|
|
1534
|
|
|
|
|
|
|
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
1535
|
|
|
|
|
|
|
# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . |
1536
|
|
|
|
|
|
|
#============================================================================= |
1537
|
|
|
|
|
|
|
|
1538
|
|
|
|
|
|
|
sub filter { |
1539
|
0
|
|
|
0
|
1
|
0
|
my($class, $source) = @_; |
1540
|
0
|
|
|
|
|
0
|
my $new = $class->new; |
1541
|
0
|
|
|
|
|
0
|
$new->output_fh(*STDOUT{IO}); |
1542
|
|
|
|
|
|
|
|
1543
|
0
|
0
|
0
|
|
|
0
|
if(ref($source || '') eq 'SCALAR') { |
|
|
0
|
|
|
|
|
|
1544
|
0
|
|
|
|
|
0
|
$new->parse_string_document( $$source ); |
1545
|
|
|
|
|
|
|
} elsif(ref($source)) { # it's a file handle |
1546
|
0
|
|
|
|
|
0
|
$new->parse_file($source); |
1547
|
|
|
|
|
|
|
} else { # it's a filename |
1548
|
0
|
|
|
|
|
0
|
$new->parse_file($source); |
1549
|
|
|
|
|
|
|
} |
1550
|
|
|
|
|
|
|
|
1551
|
0
|
|
|
|
|
0
|
return $new; |
1552
|
|
|
|
|
|
|
} |
1553
|
|
|
|
|
|
|
|
1554
|
|
|
|
|
|
|
|
1555
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
1556
|
|
|
|
|
|
|
|
1557
|
|
|
|
|
|
|
sub _out { |
1558
|
|
|
|
|
|
|
# For use in testing: Class->_out($source) |
1559
|
|
|
|
|
|
|
# returns the transformation of $source |
1560
|
|
|
|
|
|
|
|
1561
|
524
|
|
|
524
|
|
9656
|
my $class = shift(@_); |
1562
|
|
|
|
|
|
|
|
1563
|
524
|
100
|
100
|
|
|
3002
|
my $mutor = shift(@_) if @_ and ref($_[0] || '') eq 'CODE'; |
|
|
|
66
|
|
|
|
|
1564
|
|
|
|
|
|
|
|
1565
|
524
|
|
|
|
|
805
|
DEBUG and print STDERR "\n\n", '#' x 76, |
1566
|
|
|
|
|
|
|
"\nAbout to parse source: {{\n$_[0]\n}}\n\n"; |
1567
|
|
|
|
|
|
|
|
1568
|
|
|
|
|
|
|
|
1569
|
524
|
100
|
66
|
|
|
2208
|
my $parser = ref $class && $class->isa(__PACKAGE__) ? $class : $class->new; |
1570
|
524
|
|
|
|
|
1543
|
$parser->hide_line_numbers(1); |
1571
|
|
|
|
|
|
|
|
1572
|
524
|
|
|
|
|
798
|
my $out = ''; |
1573
|
524
|
|
|
|
|
1573
|
$parser->output_string( \$out ); |
1574
|
524
|
|
|
|
|
715
|
DEBUG and print STDERR " _out to ", \$out, "\n"; |
1575
|
|
|
|
|
|
|
|
1576
|
524
|
100
|
|
|
|
1363
|
$mutor->($parser) if $mutor; |
1577
|
|
|
|
|
|
|
|
1578
|
524
|
|
|
|
|
1584
|
$parser->parse_string_document( $_[0] ); |
1579
|
|
|
|
|
|
|
# use Data::Dumper; print STDERR Dumper($parser), "\n"; |
1580
|
524
|
|
|
|
|
6838
|
return $out; |
1581
|
|
|
|
|
|
|
} |
1582
|
|
|
|
|
|
|
|
1583
|
|
|
|
|
|
|
|
1584
|
|
|
|
|
|
|
sub _duo { |
1585
|
|
|
|
|
|
|
# For use in testing: Class->_duo($source1, $source2) |
1586
|
|
|
|
|
|
|
# returns the parse trees of $source1 and $source2. |
1587
|
|
|
|
|
|
|
# Good in things like: &ok( Class->duo(... , ...) ); |
1588
|
|
|
|
|
|
|
|
1589
|
56
|
|
|
56
|
|
2454
|
my $class = shift(@_); |
1590
|
|
|
|
|
|
|
|
1591
|
56
|
50
|
|
|
|
175
|
Carp::croak "But $class->_duo is useful only in list context!" |
1592
|
|
|
|
|
|
|
unless wantarray; |
1593
|
|
|
|
|
|
|
|
1594
|
56
|
100
|
100
|
|
|
346
|
my $mutor = shift(@_) if @_ and ref($_[0] || '') eq 'CODE'; |
|
|
|
66
|
|
|
|
|
1595
|
|
|
|
|
|
|
|
1596
|
56
|
50
|
|
|
|
155
|
Carp::croak "But $class->_duo takes two parameters, not: @_" |
1597
|
|
|
|
|
|
|
unless @_ == 2; |
1598
|
|
|
|
|
|
|
|
1599
|
56
|
|
|
|
|
90
|
my(@out); |
1600
|
|
|
|
|
|
|
|
1601
|
56
|
|
|
|
|
127
|
while( @_ ) { |
1602
|
112
|
|
|
|
|
481
|
my $parser = $class->new; |
1603
|
|
|
|
|
|
|
|
1604
|
112
|
|
|
|
|
226
|
push @out, ''; |
1605
|
112
|
|
|
|
|
347
|
$parser->output_string( \( $out[-1] ) ); |
1606
|
|
|
|
|
|
|
|
1607
|
112
|
|
|
|
|
143
|
DEBUG and print STDERR " _duo out to ", $parser->output_string(), |
1608
|
|
|
|
|
|
|
" = $parser->{'output_string'}\n"; |
1609
|
|
|
|
|
|
|
|
1610
|
112
|
|
|
|
|
307
|
$parser->hide_line_numbers(1); |
1611
|
112
|
100
|
|
|
|
292
|
$mutor->($parser) if $mutor; |
1612
|
112
|
|
|
|
|
305
|
$parser->parse_string_document( shift( @_ ) ); |
1613
|
|
|
|
|
|
|
# use Data::Dumper; print STDERR Dumper($parser), "\n"; |
1614
|
|
|
|
|
|
|
} |
1615
|
|
|
|
|
|
|
|
1616
|
56
|
|
|
|
|
342
|
return @out; |
1617
|
|
|
|
|
|
|
} |
1618
|
|
|
|
|
|
|
|
1619
|
|
|
|
|
|
|
|
1620
|
|
|
|
|
|
|
|
1621
|
|
|
|
|
|
|
#----------------------------------------------------------------------------- |
1622
|
|
|
|
|
|
|
1; |
1623
|
|
|
|
|
|
|
__END__ |