| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Pod::L10N::Html::Util; |
|
2
|
22
|
|
|
22
|
|
6501
|
use strict; |
|
|
22
|
|
|
|
|
43
|
|
|
|
22
|
|
|
|
|
994
|
|
|
3
|
22
|
|
|
22
|
|
127
|
use Exporter 'import'; |
|
|
22
|
|
|
|
|
40
|
|
|
|
22
|
|
|
|
|
2385
|
|
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
our $VERSION = 1.10; # Please keep in synch with lib/Pod/Html.pm |
|
6
|
|
|
|
|
|
|
$VERSION = eval $VERSION; |
|
7
|
|
|
|
|
|
|
our @EXPORT_OK = qw( |
|
8
|
|
|
|
|
|
|
anchorify |
|
9
|
|
|
|
|
|
|
html_escape |
|
10
|
|
|
|
|
|
|
htmlify |
|
11
|
|
|
|
|
|
|
process_command_line |
|
12
|
|
|
|
|
|
|
relativize_url |
|
13
|
|
|
|
|
|
|
trim_leading_whitespace |
|
14
|
|
|
|
|
|
|
unixify |
|
15
|
|
|
|
|
|
|
usage |
|
16
|
|
|
|
|
|
|
); |
|
17
|
|
|
|
|
|
|
|
|
18
|
22
|
|
|
22
|
|
139
|
use Config; |
|
|
22
|
|
|
|
|
40
|
|
|
|
22
|
|
|
|
|
1003
|
|
|
19
|
22
|
|
|
22
|
|
111
|
use File::Spec; |
|
|
22
|
|
|
|
|
40
|
|
|
|
22
|
|
|
|
|
651
|
|
|
20
|
22
|
|
|
22
|
|
114
|
use File::Spec::Unix; |
|
|
22
|
|
|
|
|
36
|
|
|
|
22
|
|
|
|
|
773
|
|
|
21
|
22
|
|
|
22
|
|
18186
|
use Getopt::Long; |
|
|
22
|
|
|
|
|
351039
|
|
|
|
22
|
|
|
|
|
265
|
|
|
22
|
22
|
|
|
22
|
|
20322
|
use Pod::Simple::XHTML; |
|
|
22
|
|
|
|
|
421264
|
|
|
|
22
|
|
|
|
|
3303
|
|
|
23
|
22
|
|
|
22
|
|
13103
|
use Text::Tabs; |
|
|
22
|
|
|
|
|
21368
|
|
|
|
22
|
|
|
|
|
3531
|
|
|
24
|
22
|
|
|
22
|
|
12095
|
use locale; # make \w work right in non-ASCII lands |
|
|
22
|
|
|
|
|
19953
|
|
|
|
22
|
|
|
|
|
136
|
|
|
25
|
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
=head1 NAME |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
Pod::Html::Util - helper functions for Pod-Html |
|
29
|
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
=head1 SUBROUTINES |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
B While these functions are importable on request from |
|
33
|
|
|
|
|
|
|
F, they are specifically intended for use within (a) the |
|
34
|
|
|
|
|
|
|
F distribution (modules and test programs) shipped as part of the |
|
35
|
|
|
|
|
|
|
Perl 5 core and (b) other parts of the core such as the F |
|
36
|
|
|
|
|
|
|
program. These functions may be modified or relocated within the core |
|
37
|
|
|
|
|
|
|
distribution -- or removed entirely therefrom -- as the core's needs evolve. |
|
38
|
|
|
|
|
|
|
Hence, you should not rely on these functions in situations other than those |
|
39
|
|
|
|
|
|
|
just described. |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
=cut |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=head2 C |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
Process command-line switches (options). Returns a reference to a hash. Will |
|
46
|
|
|
|
|
|
|
provide usage message if C<--help> switch is present or if parameters are |
|
47
|
|
|
|
|
|
|
invalid. |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
Calling this subroutine may modify C<@ARGV>. |
|
50
|
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
=cut |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
sub process_command_line { |
|
54
|
31
|
|
|
31
|
1
|
301
|
my %opts = map { $_ => undef } (qw| |
|
|
558
|
|
|
|
|
2961
|
|
|
55
|
|
|
|
|
|
|
backlink cachedir css flush |
|
56
|
|
|
|
|
|
|
header help htmldir htmlroot |
|
57
|
|
|
|
|
|
|
index infile outfile poderrors |
|
58
|
|
|
|
|
|
|
podpath podroot quiet recurse |
|
59
|
|
|
|
|
|
|
title verbose |
|
60
|
|
|
|
|
|
|
|); |
|
61
|
31
|
50
|
|
|
|
4830
|
unshift @ARGV, split ' ', $Config{pod2html} if $Config{pod2html}; |
|
62
|
31
|
|
|
|
|
665
|
my $result = GetOptions(\%opts, |
|
63
|
|
|
|
|
|
|
'backlink!', |
|
64
|
|
|
|
|
|
|
'cachedir=s', |
|
65
|
|
|
|
|
|
|
'css=s', |
|
66
|
|
|
|
|
|
|
'flush', |
|
67
|
|
|
|
|
|
|
'help', |
|
68
|
|
|
|
|
|
|
'header!', |
|
69
|
|
|
|
|
|
|
'htmldir=s', |
|
70
|
|
|
|
|
|
|
'htmlroot=s', |
|
71
|
|
|
|
|
|
|
'index!', |
|
72
|
|
|
|
|
|
|
'infile=s', |
|
73
|
|
|
|
|
|
|
'outfile=s', |
|
74
|
|
|
|
|
|
|
'poderrors!', |
|
75
|
|
|
|
|
|
|
'podpath=s', |
|
76
|
|
|
|
|
|
|
'podroot=s', |
|
77
|
|
|
|
|
|
|
'quiet!', |
|
78
|
|
|
|
|
|
|
'recurse!', |
|
79
|
|
|
|
|
|
|
'title=s', |
|
80
|
|
|
|
|
|
|
'verbose!', |
|
81
|
|
|
|
|
|
|
); |
|
82
|
31
|
100
|
|
|
|
111077
|
usage("-", "invalid parameters") if not $result; |
|
83
|
30
|
100
|
|
|
|
217
|
usage("-") if defined $opts{help}; # see if the user asked for help |
|
84
|
29
|
|
|
|
|
158
|
$opts{help} = ""; # just to make -w shut-up. |
|
85
|
29
|
|
|
|
|
247
|
return \%opts; |
|
86
|
|
|
|
|
|
|
} |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=head2 C |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
Display customary Pod::Html usage information on STDERR. |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=cut |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub usage { |
|
95
|
2
|
|
|
2
|
1
|
5
|
my $podfile = shift; |
|
96
|
2
|
100
|
|
|
|
20
|
warn "$0: $podfile: @_\n" if @_; |
|
97
|
2
|
|
|
|
|
57
|
die <
|
|
98
|
|
|
|
|
|
|
Usage: $0 --help --htmldir= --htmlroot= |
|
99
|
|
|
|
|
|
|
--infile= --outfile= |
|
100
|
|
|
|
|
|
|
--podpath=:...: --podroot= |
|
101
|
|
|
|
|
|
|
--cachedir= --flush --recurse --norecurse |
|
102
|
|
|
|
|
|
|
--quiet --noquiet --verbose --noverbose |
|
103
|
|
|
|
|
|
|
--index --noindex --backlink --nobacklink |
|
104
|
|
|
|
|
|
|
--header --noheader --poderrors --nopoderrors |
|
105
|
|
|
|
|
|
|
--css= --title= |
|
106
|
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
--[no]backlink - turn =head1 directives into links pointing to the top of |
|
108
|
|
|
|
|
|
|
the page (off by default). |
|
109
|
|
|
|
|
|
|
--cachedir - directory for the directory cache files. |
|
110
|
|
|
|
|
|
|
--css - stylesheet URL |
|
111
|
|
|
|
|
|
|
--flush - flushes the directory cache. |
|
112
|
|
|
|
|
|
|
--[no]header - produce block header/footer (default is no headers). |
|
113
|
|
|
|
|
|
|
--help - prints this message. |
|
114
|
|
|
|
|
|
|
--htmldir - directory for resulting HTML files. |
|
115
|
|
|
|
|
|
|
--htmlroot - http-server base directory from which all relative paths |
|
116
|
|
|
|
|
|
|
in podpath stem (default is /). |
|
117
|
|
|
|
|
|
|
--[no]index - generate an index at the top of the resulting html |
|
118
|
|
|
|
|
|
|
(default behaviour). |
|
119
|
|
|
|
|
|
|
--infile - filename for the pod to convert (input taken from stdin |
|
120
|
|
|
|
|
|
|
by default). |
|
121
|
|
|
|
|
|
|
--outfile - filename for the resulting html file (output sent to |
|
122
|
|
|
|
|
|
|
stdout by default). |
|
123
|
|
|
|
|
|
|
--[no]poderrors - include a POD ERRORS section in the output if there were |
|
124
|
|
|
|
|
|
|
any POD errors in the input (default behavior). |
|
125
|
|
|
|
|
|
|
--podpath - colon-separated list of directories containing library |
|
126
|
|
|
|
|
|
|
pods (empty by default). |
|
127
|
|
|
|
|
|
|
--podroot - filesystem base directory from which all relative paths |
|
128
|
|
|
|
|
|
|
in podpath stem (default is .). |
|
129
|
|
|
|
|
|
|
--[no]quiet - suppress some benign warning messages (default is off). |
|
130
|
|
|
|
|
|
|
--[no]recurse - recurse on those subdirectories listed in podpath |
|
131
|
|
|
|
|
|
|
(default behaviour). |
|
132
|
|
|
|
|
|
|
--title - title that will appear in resulting html file. |
|
133
|
|
|
|
|
|
|
--[no]verbose - self-explanatory (off by default). |
|
134
|
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
END_OF_USAGE |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
} |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
=head2 C |
|
140
|
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
Ensure that F's internals and tests handle paths consistently |
|
142
|
|
|
|
|
|
|
across Unix, Windows and VMS. |
|
143
|
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
=cut |
|
145
|
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
sub unixify { |
|
147
|
561
|
|
|
561
|
1
|
6089687
|
my $full_path = shift; |
|
148
|
561
|
100
|
|
|
|
2749
|
return '' unless $full_path; |
|
149
|
514
|
100
|
|
|
|
1805
|
return $full_path if $full_path eq '/'; |
|
150
|
|
|
|
|
|
|
|
|
151
|
506
|
|
|
|
|
13002
|
my ($vol, $dirs, $file) = File::Spec->splitpath($full_path); |
|
152
|
506
|
50
|
|
|
|
4759
|
my @dirs = $dirs eq File::Spec->curdir() |
|
153
|
|
|
|
|
|
|
? (File::Spec::Unix->curdir()) |
|
154
|
|
|
|
|
|
|
: File::Spec->splitdir($dirs); |
|
155
|
506
|
50
|
33
|
|
|
2946
|
if (defined($vol) && $vol) { |
|
156
|
0
|
0
|
|
|
|
0
|
$vol =~ s/:$// if $^O eq 'VMS'; |
|
157
|
0
|
0
|
|
|
|
0
|
$vol = uc $vol if $^O eq 'MSWin32'; |
|
158
|
|
|
|
|
|
|
|
|
159
|
0
|
0
|
|
|
|
0
|
if( $dirs[0] ) { |
|
160
|
0
|
|
|
|
|
0
|
unshift @dirs, $vol; |
|
161
|
|
|
|
|
|
|
} |
|
162
|
|
|
|
|
|
|
else { |
|
163
|
0
|
|
|
|
|
0
|
$dirs[0] = $vol; |
|
164
|
|
|
|
|
|
|
} |
|
165
|
|
|
|
|
|
|
} |
|
166
|
506
|
100
|
|
|
|
3168
|
unshift @dirs, '' if File::Spec->file_name_is_absolute($full_path); |
|
167
|
506
|
100
|
|
|
|
1455
|
return $file unless scalar(@dirs); |
|
168
|
483
|
|
|
|
|
3992
|
$full_path = File::Spec::Unix->catfile(File::Spec::Unix->catdir(@dirs), |
|
169
|
|
|
|
|
|
|
$file); |
|
170
|
483
|
50
|
|
|
|
1965
|
$full_path =~ s|^\/|| if $^O eq 'MSWin32'; # C:/foo works, /C:/foo doesn't |
|
171
|
483
|
50
|
|
|
|
1306
|
$full_path =~ s/\^\././g if $^O eq 'VMS'; # unescape dots |
|
172
|
483
|
|
|
|
|
1872
|
return $full_path; |
|
173
|
|
|
|
|
|
|
} |
|
174
|
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
=head2 C |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
Convert an absolute URL to one relative to a base URL. |
|
178
|
|
|
|
|
|
|
Assumes both end in a filename. |
|
179
|
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=cut |
|
181
|
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
sub relativize_url { |
|
183
|
26
|
|
|
26
|
1
|
1824
|
my ($dest, $source) = @_; |
|
184
|
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
# Remove each file from its path |
|
186
|
26
|
|
|
|
|
320
|
my ($dest_volume, $dest_directory, $dest_file) = |
|
187
|
|
|
|
|
|
|
File::Spec::Unix->splitpath( $dest ); |
|
188
|
26
|
|
|
|
|
239
|
$dest = File::Spec::Unix->catpath( $dest_volume, $dest_directory, '' ); |
|
189
|
|
|
|
|
|
|
|
|
190
|
26
|
|
|
|
|
385
|
my ($source_volume, $source_directory, $source_file) = |
|
191
|
|
|
|
|
|
|
File::Spec::Unix->splitpath( $source ); |
|
192
|
26
|
|
|
|
|
165
|
$source = File::Spec::Unix->catpath( $source_volume, $source_directory, '' ); |
|
193
|
|
|
|
|
|
|
|
|
194
|
26
|
|
|
|
|
74
|
my $rel_path = ''; |
|
195
|
26
|
50
|
|
|
|
101
|
if ($dest ne '') { |
|
196
|
26
|
|
|
|
|
2490
|
$rel_path = File::Spec::Unix->abs2rel( $dest, $source ); |
|
197
|
|
|
|
|
|
|
} |
|
198
|
|
|
|
|
|
|
|
|
199
|
26
|
50
|
33
|
|
|
216
|
if ($rel_path ne '' && substr( $rel_path, -1 ) ne '/') { |
|
200
|
26
|
|
|
|
|
65
|
$rel_path .= "/$dest_file"; |
|
201
|
|
|
|
|
|
|
} else { |
|
202
|
0
|
|
|
|
|
0
|
$rel_path .= "$dest_file"; |
|
203
|
|
|
|
|
|
|
} |
|
204
|
|
|
|
|
|
|
|
|
205
|
26
|
|
|
|
|
109
|
return $rel_path; |
|
206
|
|
|
|
|
|
|
} |
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
=head2 C |
|
209
|
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
Make text safe for HTML. |
|
211
|
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
=cut |
|
213
|
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
sub html_escape { |
|
215
|
29
|
|
|
29
|
1
|
91
|
my $rest = $_[0]; |
|
216
|
29
|
|
|
|
|
148
|
$rest =~ s/&/&/g; |
|
217
|
29
|
|
|
|
|
174
|
$rest =~ s/</g; |
|
218
|
29
|
|
|
|
|
107
|
$rest =~ s/>/>/g; |
|
219
|
29
|
|
|
|
|
72
|
$rest =~ s/"/"/g; |
|
220
|
29
|
|
|
|
|
121
|
return $rest; |
|
221
|
|
|
|
|
|
|
} |
|
222
|
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
=head2 C |
|
224
|
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
htmlify($heading); |
|
226
|
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
Converts a pod section specification to a suitable section specification |
|
228
|
|
|
|
|
|
|
for HTML. Note that we keep spaces and special characters except |
|
229
|
|
|
|
|
|
|
C<", ?> (Netscape problem) and the hyphen (writer's problem...). |
|
230
|
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
=cut |
|
232
|
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
sub htmlify { |
|
234
|
0
|
|
|
0
|
1
|
0
|
my( $heading) = @_; |
|
235
|
0
|
|
|
|
|
0
|
$heading =~ s/(\s+)/ /g; |
|
236
|
0
|
|
|
|
|
0
|
$heading =~ s/\s+\Z//; |
|
237
|
0
|
|
|
|
|
0
|
$heading =~ s/\A\s+//; |
|
238
|
|
|
|
|
|
|
# The hyphen is a disgrace to the English language. |
|
239
|
|
|
|
|
|
|
# $heading =~ s/[-"?]//g; |
|
240
|
0
|
|
|
|
|
0
|
$heading =~ s/["?]//g; |
|
241
|
0
|
|
|
|
|
0
|
$heading = lc( $heading ); |
|
242
|
0
|
|
|
|
|
0
|
return $heading; |
|
243
|
|
|
|
|
|
|
} |
|
244
|
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=head2 C |
|
246
|
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
anchorify(@heading); |
|
248
|
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
Similar to C, but turns non-alphanumerics into underscores. Note |
|
250
|
|
|
|
|
|
|
that C is not exported by default. |
|
251
|
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
=cut |
|
253
|
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
sub anchorify { |
|
255
|
13
|
|
|
13
|
1
|
405536
|
my ($anchor) = @_; |
|
256
|
13
|
|
|
|
|
31
|
$anchor =~ s/"/_/g; # Replace double quotes with underscores |
|
257
|
13
|
|
|
|
|
24
|
$anchor =~ s/_$//; # ... but strip any final underscore |
|
258
|
13
|
|
|
|
|
26
|
$anchor =~ s/[<>&']//g; # Strip the remaining HTML special characters |
|
259
|
13
|
|
|
|
|
31
|
$anchor =~ s/^\s+//; s/\s+$//; # Strip white space. |
|
|
13
|
|
|
|
|
23
|
|
|
260
|
13
|
|
|
|
|
29
|
$anchor =~ s/^([^a-zA-Z]+)$/pod$1/; # Prepend "pod" if no valid chars. |
|
261
|
13
|
|
|
|
|
27
|
$anchor =~ s/^[^a-zA-Z]+//; # First char must be a letter. |
|
262
|
13
|
|
|
|
|
41
|
$anchor =~ s/[^-a-zA-Z0-9_:.]+/-/g; # All other chars must be valid. |
|
263
|
13
|
|
|
|
|
47
|
$anchor =~ s/[-:.]+$//; # Strip trailing punctuation. |
|
264
|
13
|
|
|
|
|
50
|
$anchor =~ s/\W/_/g; |
|
265
|
13
|
|
|
|
|
83
|
return $anchor; |
|
266
|
|
|
|
|
|
|
} |
|
267
|
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
=head2 C |
|
269
|
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
Remove any level of indentation (spaces or tabs) from each code block |
|
271
|
|
|
|
|
|
|
consistently. Adapted from: |
|
272
|
|
|
|
|
|
|
https://metacpan.org/source/HAARG/MetaCPAN-Pod-XHTML-0.002001/lib/Pod/Simple/Role/StripVerbatimIndent.pm |
|
273
|
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=cut |
|
275
|
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
sub trim_leading_whitespace { |
|
277
|
8
|
|
|
8
|
1
|
49612
|
my ($para) = @_; |
|
278
|
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
# Start by converting tabs to spaces |
|
280
|
8
|
|
|
|
|
95
|
@$para = Text::Tabs::expand(@$para); |
|
281
|
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
# Find the line with the least amount of indent, as that's our "base" |
|
283
|
8
|
|
|
|
|
820
|
my @indent_levels = (sort(map { $_ =~ /^( *)./mg } @$para)); |
|
|
24
|
|
|
|
|
163
|
|
|
284
|
8
|
|
50
|
|
|
36
|
my $indent = $indent_levels[0] || ""; |
|
285
|
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
# Remove the "base" amount of indent from each line |
|
287
|
8
|
|
|
|
|
24
|
foreach (@$para) { |
|
288
|
24
|
|
|
|
|
226
|
$_ =~ s/^\Q$indent//mg; |
|
289
|
|
|
|
|
|
|
} |
|
290
|
|
|
|
|
|
|
|
|
291
|
8
|
|
|
|
|
32
|
return; |
|
292
|
|
|
|
|
|
|
} |
|
293
|
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
1; |
|
295
|
|
|
|
|
|
|
|