line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
=head1 NAME |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
String::Escape - Backslash escapes, quoted phrase, word elision, etc. |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=cut |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
package String::Escape; |
8
|
|
|
|
|
|
|
|
9
|
6
|
|
|
6
|
|
54105
|
use strict; |
|
6
|
|
|
|
|
9
|
|
|
6
|
|
|
|
|
149
|
|
10
|
6
|
|
|
6
|
|
18
|
use warnings; |
|
6
|
|
|
|
|
7
|
|
|
6
|
|
|
|
|
121
|
|
11
|
6
|
|
|
6
|
|
18
|
use Carp; |
|
6
|
|
|
|
|
7
|
|
|
6
|
|
|
|
|
406
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
######################################################################## |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 SYNOPSIS |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
This module provides a flexible calling interface to some frequently-performed string conversion functions, including applying and removing backslash escapes like \n and \t, wrapping and removing double-quotes, and truncating to fit within a desired length. |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
use String::Escape qw( printable unprintable ); |
21
|
|
|
|
|
|
|
# Convert control, high-bit chars to \n or \xxx escapes |
22
|
|
|
|
|
|
|
$output = printable($value); |
23
|
|
|
|
|
|
|
# Convert escape sequences back to original chars |
24
|
|
|
|
|
|
|
$value = unprintable($input); |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
use String::Escape qw( elide ); |
27
|
|
|
|
|
|
|
# Shorten strings to fit, if necessary |
28
|
|
|
|
|
|
|
foreach (@_) { print elide( $_, 79 ) . "\n"; } |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
use String::Escape qw( string2list list2string ); |
31
|
|
|
|
|
|
|
# Pack and unpack simple lists by quoting each item |
32
|
|
|
|
|
|
|
$list = list2string( @list ); |
33
|
|
|
|
|
|
|
@list = string2list( $list ); |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
use String::Escape qw( escape ); |
36
|
|
|
|
|
|
|
# Defer selection of escaping routines until runtime |
37
|
|
|
|
|
|
|
$escape_name = $use_quotes ? 'qprintable' : 'printable'; |
38
|
|
|
|
|
|
|
@escaped = escape($escape_name, @values); |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
=cut |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
######################################################################## |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
=head1 VERSION |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
This is version 2010.001. |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=cut |
50
|
|
|
|
|
|
|
|
51
|
6
|
|
|
6
|
|
27
|
use vars qw( $VERSION ); |
|
6
|
|
|
|
|
9
|
|
|
6
|
|
|
|
|
295
|
|
52
|
|
|
|
|
|
|
$VERSION = 2010.001; |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
######################################################################## |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=head1 SUBROUTINES |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
You can either import the specific functions you want, or import only the C function and pass it the names of the functions to invoke. |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=cut |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
######################################################################## |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
=head2 import / EXPORT |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
All of the public functions described below are available as optional exports. |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=cut |
71
|
|
|
|
|
|
|
|
72
|
6
|
|
|
6
|
|
24
|
use Exporter; |
|
6
|
|
|
|
|
9
|
|
|
6
|
|
|
|
|
192
|
|
73
|
|
|
|
|
|
|
|
74
|
6
|
|
|
6
|
|
19
|
use vars qw( @ISA @EXPORT_OK ); |
|
6
|
|
|
|
|
4
|
|
|
6
|
|
|
|
|
1472
|
|
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
push @ISA, qw( Exporter ); |
77
|
|
|
|
|
|
|
push @EXPORT_OK, qw( |
78
|
|
|
|
|
|
|
quote unquote quote_non_words singlequote unsinglequote |
79
|
|
|
|
|
|
|
evalable unevalable qevalable unqevalable |
80
|
|
|
|
|
|
|
printable unprintable qprintable unqprintable |
81
|
|
|
|
|
|
|
unquotemeta |
82
|
|
|
|
|
|
|
elide |
83
|
|
|
|
|
|
|
escape |
84
|
|
|
|
|
|
|
string2list string2hash list2string list2hash hash2string hash2list |
85
|
|
|
|
|
|
|
); |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
######################################################################## |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
=head2 Quoting |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
Each of these functions takes a single simple scalar argument and |
92
|
|
|
|
|
|
|
returns its escaped (or unescaped) equivalent. |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=over 4 |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
=item quote($value) : $escaped |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
Add double quote characters to each end of the string. |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=item unquote($value) : $escaped |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
If the string both begins and ends with double quote characters, they are removed, otherwise the string is returned unchanged. |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
=item quote_non_words($value) : $escaped |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
As above, but only quotes empty, punctuated, and multiword values; simple values consisting of alphanumerics without special characters are not quoted. |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=item singlequote($value) : $escaped |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
Add single quote characters to each end of the string. |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=item unsinglequote($value) : $escaped |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
If the string both begins and ends with single quote characters, they are removed, otherwise the string is returned unchanged. |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=back |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
=cut |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
# $with_surrounding_quotes = quote( $string_value ); |
121
|
|
|
|
|
|
|
sub quote ($) { |
122
|
5
|
|
|
5
|
1
|
44
|
'"' . $_[0] . '"' |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
# $remove_surrounding_quotes = quote( $string_value ); |
126
|
|
|
|
|
|
|
sub unquote ($) { |
127
|
5
|
50
|
|
5
|
1
|
31
|
( $_[0] =~ m/ \A ["] (.*) ["] \Z /sx ) ? $1 : $_[0]; |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# $word_or_phrase_with_surrounding_quotes = quote( $string_value ); |
131
|
|
|
|
|
|
|
sub quote_non_words ($) { |
132
|
8
|
100
|
66
|
8
|
1
|
70
|
( ! length $_[0] or $_[0] =~ /[^\w\_\-\/\.\:\#]/ ) ? '"'.$_[0].'"' : $_[0] |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
# $with_surrounding_quotes = singlequote( $string_value ); |
136
|
|
|
|
|
|
|
sub singlequote ($) { |
137
|
0
|
|
|
0
|
1
|
0
|
'\'' . $_[0] . '\'' |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
# $remove_surrounding_quotes = singlequote( $string_value ); |
141
|
|
|
|
|
|
|
sub unsinglequote ($) { |
142
|
0
|
0
|
|
0
|
1
|
0
|
( $_[0] =~ m/ \A ['] (.*) ['] \Z /sx ) ? $1 : $_[0]; |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
######################################################################## |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
=head2 Backslash Escaping Functions |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
Each of these functions takes a single simple scalar argument and |
151
|
|
|
|
|
|
|
returns its escaped (or unescaped) equivalent. |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
=over 4 |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
=item evalable($value) : $escaped |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
Converts return, newline, tab, backslash, dollar, at sign and unprintable |
158
|
|
|
|
|
|
|
characters to their backslash-escaped equivalents. |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
=item unevalable($value) : $escaped |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
Converts backslash escape sequences in a string back to their original value. |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
=item qevalable($value) : $escaped |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
Converts special characters to their backslash-escaped equivalents and then wraps the results with double quotes. |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
=item unqevalable($value) : $escaped |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
Strips surrounding double quotes then converts backslash escape sequences back to their original value. |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=back |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
In addition to the four functions listed above, there is a corresponding set which use a slightly different set of escape sequences. |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
=over 4 |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
=item printable($value) : $escaped |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
Converts return, newline, tab, backslash and unprintable |
181
|
|
|
|
|
|
|
characters to their backslash-escaped equivalents. |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
=item unprintable($value) : $escaped |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
Converts backslash escape sequences in a string back to their original value. |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=item qprintable($value) : $escaped |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
Converts special characters to their backslash-escaped equivalents and then wraps the results with double quotes. |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
(Note that this is I MIME quoted-printable encoding.) |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
=item unqprintable($value) : $escaped |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
Strips surrounding double quotes then converts backslash escape sequences back to their original value. |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=back |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
In addition to the functions listed above, there is also one function that mirrors the behavior of Perl's built-in C function. |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
=over 4 |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=item unquotemeta($value) : $escaped |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
Strips out backslashes before any character. |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=back |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
Here are a few examples: |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
=over 4 |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
=item * |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
print printable( "\tNow is the time\nfor all good folks\n" ); |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
\tNow is the time\nfor all good folks\n |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
=item * |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
print unprintable( '\\tNow is the time\\nfor all good folks\\n' ); |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
Now is the time |
224
|
|
|
|
|
|
|
for all good folks |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
=back |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
=cut |
229
|
|
|
|
|
|
|
|
230
|
6
|
|
|
6
|
|
22
|
use vars qw( @EvalEscapes %Evalable %Unevalable ); |
|
6
|
|
|
|
|
6
|
|
|
6
|
|
|
|
|
2138
|
|
231
|
|
|
|
|
|
|
@EvalEscapes = ( |
232
|
|
|
|
|
|
|
( map { $_ => $_ } ( '\\', '"', '$', '@' ) ), |
233
|
|
|
|
|
|
|
( 'r' => "\r", 'n' => "\n", 't' => "\t" ), |
234
|
|
|
|
|
|
|
( map { 'x' . unpack('H2', chr($_)) => chr($_) } (0..255) ), |
235
|
|
|
|
|
|
|
( map { sprintf('%03o', $_) => chr($_) } (0..255) ), |
236
|
|
|
|
|
|
|
); |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
%Evalable = ( reverse @EvalEscapes ); |
239
|
|
|
|
|
|
|
%Unevalable = ( @EvalEscapes ); |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
# $special_characters_escaped = evalable( $source_string ); |
242
|
|
|
|
|
|
|
sub evalable ($) { |
243
|
9
|
100
|
|
9
|
1
|
517
|
local $_ = ( defined $_[0] ? $_[0] : '' ); |
244
|
|
|
|
|
|
|
# Preserve only printable ASCII characters other than \, ", $, and @ |
245
|
9
|
|
|
|
|
66
|
s/([^\x20\x21\x24\x25-\x39\x41-\x5b\x5d-\x7e])/\\$Evalable{$1}/gs; |
246
|
9
|
|
|
|
|
28
|
return $_; |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
# $original_string = unevalable( $special_characters_escaped ); |
250
|
|
|
|
|
|
|
sub unevalable ($) { |
251
|
8
|
100
|
|
8
|
1
|
16
|
local $_ = ( defined $_[0] ? $_[0] : '' ); |
252
|
8
|
|
|
|
|
24
|
s/ (\A|\G|[^\\]) [\\] ( [0]\d\d | [x][\da-fA-F]{2} | . ) / $1 . ( $Unevalable{lc($2) }) /gsxe; |
|
27
|
|
|
|
|
76
|
|
253
|
8
|
|
|
|
|
39
|
return $_; |
254
|
|
|
|
|
|
|
} |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
# quoted_and_escaped = qevalable( $source_string ); |
257
|
5
|
|
|
5
|
1
|
1480
|
sub qevalable ($) { quote evalable $_[0] } |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
# $original_string = unqevalable( quoted_and_escaped ); |
260
|
4
|
|
|
4
|
1
|
11
|
sub unqevalable ($) { unevalable unquote $_[0] } |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
######################################################################## |
263
|
|
|
|
|
|
|
|
264
|
6
|
|
|
6
|
|
27
|
use vars qw( %Printable %Unprintable ); |
|
6
|
|
|
|
|
6
|
|
|
6
|
|
|
|
|
2372
|
|
265
|
|
|
|
|
|
|
%Printable = ( |
266
|
|
|
|
|
|
|
( map { chr($_), unpack('H2', chr($_)) } (0..255) ), |
267
|
|
|
|
|
|
|
( "\\"=>'\\', "\r"=>'r', "\n"=>'n', "\t"=>'t', ), |
268
|
|
|
|
|
|
|
( map { $_ => $_ } ( '"' ) ) |
269
|
|
|
|
|
|
|
); |
270
|
|
|
|
|
|
|
%Unprintable = ( reverse %Printable ); |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
# $special_characters_escaped = printable( $source_string ); |
273
|
|
|
|
|
|
|
sub printable ($) { |
274
|
12
|
100
|
|
12
|
1
|
980
|
local $_ = ( defined $_[0] ? $_[0] : '' ); |
275
|
12
|
|
|
|
|
31
|
s/([\r\n\t\"\\\x00-\x1f\x7F-\xFF])/ '\\' . $Printable{$1} /gsxe; |
|
18
|
|
|
|
|
39
|
|
276
|
12
|
|
|
|
|
32
|
return $_; |
277
|
|
|
|
|
|
|
} |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
# $original_string = unprintable( $special_characters_escaped ); |
280
|
|
|
|
|
|
|
sub unprintable ($) { |
281
|
12
|
100
|
|
12
|
1
|
26
|
local $_ = ( defined $_[0] ? $_[0] : '' ); |
282
|
12
|
|
|
|
|
29
|
s/((?:\A|\G|[^\\]))\\([rRnNtT\"\\]|[x]?[\da-fA-F]{2})/ $1 . $Unprintable{lc($2)} /gsxe; |
|
17
|
|
|
|
|
69
|
|
283
|
12
|
|
|
|
|
27
|
return $_; |
284
|
|
|
|
|
|
|
} |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
# quoted_and_escaped = qprintable( $source_string ); |
287
|
8
|
|
|
8
|
1
|
374
|
sub qprintable ($) { quote_non_words printable $_[0] } |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
# $original_string = unqprintable( quoted_and_escaped ); |
290
|
1
|
|
|
1
|
1
|
6
|
sub unqprintable ($) { unprintable unquote $_[0] } |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
######################################################################## |
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
sub unquotemeta ($) { |
295
|
0
|
0
|
|
0
|
1
|
0
|
local $_ = ( defined $_[0] ? $_[0] : '' ); |
296
|
0
|
|
|
|
|
0
|
s/ (\A|\G|[^\\]) [\\] (.) / $1 . $2 /gsex; |
|
0
|
|
|
|
|
0
|
|
297
|
0
|
|
|
|
|
0
|
return $_; |
298
|
|
|
|
|
|
|
} |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
######################################################################## |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
=head2 Elision Function |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
This function extracts the leading portion of a provided string and appends ellipsis if it's longer than the desired maximum excerpt length. |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
=over 4 |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
=item elide($string) : $elided_string |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
=item elide($string, $length) : $elided_string |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
=item elide($string, $length, $word_boundary_strictness) : $elided_string |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
Return a single-quoted, shortened version of the string, with ellipsis. |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
If the original string is shorter than $length, it is returned unchanged. At most $length characters are returned; if called with a single argument, $length defaults to $DefaultLength. |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
Up to $word_boundary_strictness additional characters may be ommited in order to make the elided portion end on a word boundary; you can pass 0 to ignore word boundaries. If not provided, $word_boundary_strictness defaults to $DefaultStrictness. |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
=item $Elipses |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
The string of characters used to indicate the end of the excerpt. Initialized to '...'. |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
=item $DefaultLength |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
The default target excerpt length, used when the elide function is called with a single argument. Initialized to 60. |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=item $DefaultStrictness |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
The default word-boundary flexibility, used when the elide function is called without the third argument. Initialized to 10. |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=back |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
Here are a few examples: |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
=over 4 |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
=item * |
340
|
|
|
|
|
|
|
|
341
|
|
|
|
|
|
|
C<$string = 'foo bar baz this that the other';> |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
C |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
foo bar baz this that the other |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
=item * |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
C |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
foo bar... |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
=item * |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
C |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
foo bar b... |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
=back |
360
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
=cut |
362
|
|
|
|
|
|
|
|
363
|
6
|
|
|
6
|
|
27
|
use vars qw( $Elipses $DefaultLength $DefaultStrictness ); |
|
6
|
|
|
|
|
6
|
|
|
6
|
|
|
|
|
1198
|
|
364
|
|
|
|
|
|
|
$Elipses = '...'; |
365
|
|
|
|
|
|
|
$DefaultLength = 60; |
366
|
|
|
|
|
|
|
$DefaultStrictness = 10; |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
# $elided_string = elide($string); |
369
|
|
|
|
|
|
|
# $elided_string = elide($string, $length); |
370
|
|
|
|
|
|
|
# $elided_string = elide($string, $length, $word_boundary_strictness); |
371
|
|
|
|
|
|
|
sub elide ($;$$) { |
372
|
4
|
|
|
4
|
1
|
14
|
my $source = shift; |
373
|
4
|
50
|
|
|
|
11
|
my $length = scalar(@_) ? shift() : $DefaultLength; |
374
|
4
|
100
|
|
|
|
8
|
my $word_limit = scalar(@_) ? shift() : $DefaultStrictness; |
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
# If the source is already short, we don't need to do anything |
377
|
4
|
50
|
|
|
|
11
|
return $source if (length($source) < $length); |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
# Leave room for the elipses and make sure we include at least one character. |
380
|
4
|
|
|
|
|
6
|
$length -= length( $Elipses ); |
381
|
4
|
50
|
|
|
|
9
|
$length = 1 if ( $length < 1 ); |
382
|
|
|
|
|
|
|
|
383
|
4
|
|
|
|
|
5
|
my $excerpt; |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
# Try matching $length characters or less at a word boundary. |
386
|
4
|
100
|
|
|
|
88
|
$excerpt = ( $source =~ /^(.{0,$length})(?:\s|\Z)/ )[0] if ( $word_limit ); |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
# Ignore boundaries if that fails or returns much less than we wanted. |
389
|
4
|
100
|
33
|
|
|
32
|
$excerpt = substr($source, 0, $length) if ( ! defined $excerpt or |
|
|
|
33
|
|
|
|
|
|
|
|
66
|
|
|
|
|
390
|
|
|
|
|
|
|
length($excerpt) < length($source) and |
391
|
|
|
|
|
|
|
! length($excerpt) || abs($length - length($excerpt)) > $word_limit); |
392
|
|
|
|
|
|
|
|
393
|
4
|
|
|
|
|
24
|
return $excerpt . $Elipses; |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
|
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
######################################################################## |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
=head2 escape() |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
These functions provide for the registration of string-escape specification |
402
|
|
|
|
|
|
|
names and corresponding functions, and then allow the invocation of one or |
403
|
|
|
|
|
|
|
several of these functions on one or several source string values. |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
=over 4 |
406
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
=item escape($escapes, $value) : $escaped_value |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
=item escape($escapes, @values) : @escaped_values |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
Returns an altered copy of the provided values by looking up the escapes string in a registry of string-modification functions. |
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
If called in a scalar context, operates on the single value passed in; if |
414
|
|
|
|
|
|
|
called in a list contact, operates identically on each of the provided values. |
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
Space-separated compound specifications like 'quoted uppercase' are expanded to a list of functions to be applied in order. |
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
Valid escape specifications are: |
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
=over 4 |
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
=item one of the keys defined in %Escapes |
423
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
The coresponding specification will be looked up and used. |
425
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
=item a sequence of names separated by whitespace, |
427
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
Each name will be looked up, and each of the associated functions will be applied successively, from left to right. |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
=item a reference to a function |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
The provided function will be called on with each value in turn. |
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
=item a reference to an array |
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
Each item in the array will be expanded as provided above. |
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
=back |
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
A fatal error will be generated if you pass an unsupported escape specification, or if the function is called with multiple values in a scalar context. |
441
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
=item String::Escape::names() : @defined_escapes |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
Returns a list of defined escape specification strings. |
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
=item String::Escape::add( $escape_name, \&escape_function ); |
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
Add a new escape specification and corresponding function. |
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
=back |
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
By default, all of the public functions described below are available as named escape commands, as well as the following built-in functions: |
453
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
=over 4 |
455
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
=item * |
457
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
none: Return the string unchanged. |
459
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
=item * |
461
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
uppercase: Calls the built-in uc function. |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
=item * |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
lowercase: Calls the built-in lc function. |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
=item * |
469
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
initialcase: Calls the built-in lc and ucfirst functions. |
471
|
|
|
|
|
|
|
|
472
|
|
|
|
|
|
|
=back |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
Here are a few examples: |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
=over 4 |
477
|
|
|
|
|
|
|
|
478
|
|
|
|
|
|
|
=item * |
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
C |
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
"\tNow is the time\nfor all good folks\n" |
483
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
=item * |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
C |
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
"\tNOW IS THE TIME\nFOR ALL GOOD FOLKS\n" |
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
=item * |
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
C |
493
|
|
|
|
|
|
|
|
494
|
|
|
|
|
|
|
\tNow is the time\n--for all good folks\n |
495
|
|
|
|
|
|
|
|
496
|
|
|
|
|
|
|
=item * |
497
|
|
|
|
|
|
|
|
498
|
|
|
|
|
|
|
You can add more escaping functions to the supported set by calling add(). |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
C |
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
C |
503
|
|
|
|
|
|
|
|
504
|
|
|
|
|
|
|
AT&T |
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
=back |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
=cut |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
# %Escapes - escaper function references by name |
511
|
6
|
|
|
6
|
|
53
|
use vars qw( %Escapes ); |
|
6
|
|
|
|
|
6
|
|
|
6
|
|
|
|
|
5316
|
|
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
# String::Escape::add( $name, $subroutine ); |
514
|
|
|
|
|
|
|
sub add { |
515
|
6
|
|
|
6
|
1
|
18
|
while ( @_ ) { |
516
|
120
|
|
|
|
|
77
|
my ( $name, $func ) = ( shift, shift ); |
517
|
120
|
|
|
|
|
187
|
$Escapes{ $name } = $func |
518
|
|
|
|
|
|
|
} |
519
|
|
|
|
|
|
|
} |
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
# @defined_names = String::Escape::names(); |
522
|
|
|
|
|
|
|
sub names { |
523
|
1
|
|
|
1
|
1
|
170
|
keys(%Escapes) |
524
|
|
|
|
|
|
|
} |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
# $escaped = escape($escape_spec, $value); |
527
|
|
|
|
|
|
|
# @escaped = escape($escape_spec, @values); |
528
|
|
|
|
|
|
|
sub escape { |
529
|
3
|
|
|
3
|
1
|
482
|
my ($escape_spec, @values) = @_; |
530
|
|
|
|
|
|
|
|
531
|
3
|
|
|
|
|
7
|
my @escapes = _expand_escape_spec($escape_spec); |
532
|
|
|
|
|
|
|
|
533
|
2
|
|
|
|
|
4
|
foreach my $value ( @values ) { |
534
|
5
|
|
|
|
|
7
|
foreach my $escaper ( @escapes ) { |
535
|
5
|
|
|
|
|
6
|
$value = &$escaper( $value ); |
536
|
|
|
|
|
|
|
} |
537
|
|
|
|
|
|
|
} |
538
|
|
|
|
|
|
|
|
539
|
2
|
100
|
|
|
|
6
|
if ( wantarray ) { |
|
|
50
|
|
|
|
|
|
540
|
|
|
|
|
|
|
@values |
541
|
1
|
|
|
|
|
3
|
} elsif ( @values > 1 ) { |
542
|
0
|
|
|
|
|
0
|
croak "escape called with multiple values but in scalar context" |
543
|
|
|
|
|
|
|
} else { |
544
|
1
|
|
|
|
|
5
|
$values[0] |
545
|
|
|
|
|
|
|
} |
546
|
|
|
|
|
|
|
} |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
# @escape_functions = _expand_escape_spec($escape_spec); |
549
|
|
|
|
|
|
|
sub _expand_escape_spec { |
550
|
4
|
|
|
4
|
|
4
|
my $escape_spec = shift; |
551
|
|
|
|
|
|
|
|
552
|
4
|
100
|
|
|
|
12
|
if ( ref($escape_spec) eq 'CODE' ) { |
|
|
50
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
553
|
2
|
|
|
|
|
14
|
return $escape_spec; |
554
|
|
|
|
|
|
|
} elsif ( ref($escape_spec) eq 'ARRAY' ) { |
555
|
0
|
|
|
|
|
0
|
return map { _expand_escape_spec($_) } @$escape_spec; |
|
0
|
|
|
|
|
0
|
|
556
|
|
|
|
|
|
|
} elsif ( ! ref($escape_spec) ) { |
557
|
|
|
|
|
|
|
return map { |
558
|
1
|
|
|
|
|
3
|
_expand_escape_spec($_) |
559
|
|
|
|
|
|
|
} map { |
560
|
2
|
100
|
|
|
|
7
|
$Escapes{$_} or _unsupported_escape_spec( $_ ) |
|
2
|
|
|
|
|
11
|
|
561
|
|
|
|
|
|
|
} split(/\s+/, $escape_spec); |
562
|
|
|
|
|
|
|
} else { |
563
|
0
|
|
|
|
|
0
|
_unsupported_escape_spec( $escape_spec ); |
564
|
|
|
|
|
|
|
} |
565
|
|
|
|
|
|
|
} |
566
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
# _unsupported_escape_spec($escape_spec); |
568
|
|
|
|
|
|
|
sub _unsupported_escape_spec { |
569
|
1
|
|
|
1
|
|
2
|
my $escape_spec = shift; |
570
|
|
|
|
|
|
|
|
571
|
1
|
50
|
|
|
|
9
|
croak( |
572
|
|
|
|
|
|
|
"unsupported escape specification " . |
573
|
|
|
|
|
|
|
( defined($escape_spec) ? "'$_'" : 'undef' ) . "; " . |
574
|
|
|
|
|
|
|
"should be one of " . join(', ', names()) |
575
|
|
|
|
|
|
|
) |
576
|
|
|
|
|
|
|
} |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
add( |
579
|
|
|
|
|
|
|
'none' => sub ($) { $_[0]; }, |
580
|
|
|
|
|
|
|
|
581
|
|
|
|
|
|
|
'uppercase' => sub ($) { uc $_[0] }, |
582
|
|
|
|
|
|
|
'lowercase' => sub ($) { lc $_[0] }, |
583
|
|
|
|
|
|
|
'initialcase' => sub ($) { ucfirst lc $_[0] }, |
584
|
|
|
|
|
|
|
|
585
|
|
|
|
|
|
|
'quote' => \"e, |
586
|
|
|
|
|
|
|
'unquote' => \&unquote, |
587
|
|
|
|
|
|
|
'quote_non_words' => \"e_non_words, |
588
|
|
|
|
|
|
|
'singlequote' => \&singlequote, |
589
|
|
|
|
|
|
|
'singleunquote' => \&unsinglequote, |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
'evalable' => \&evalable, |
592
|
|
|
|
|
|
|
'unevalable' => \&unevalable, |
593
|
|
|
|
|
|
|
'qevalable' => \&qevalable, |
594
|
|
|
|
|
|
|
'unqevalable' => \&unqevalable, |
595
|
|
|
|
|
|
|
|
596
|
|
|
|
|
|
|
'printable' => \&printable, |
597
|
|
|
|
|
|
|
'unprintable' => \&unprintable, |
598
|
|
|
|
|
|
|
'qprintable' => \&qprintable, |
599
|
|
|
|
|
|
|
'unqprintable' => \&unqprintable, |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
'quotemeta' => sub ($) { quotemeta $_[0] }, |
602
|
|
|
|
|
|
|
'unquotemeta' => \&unquotemeta, |
603
|
|
|
|
|
|
|
|
604
|
|
|
|
|
|
|
'elide' => \&elide, |
605
|
|
|
|
|
|
|
); |
606
|
|
|
|
|
|
|
|
607
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
######################################################################## |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
=head2 Space-separated Lists and Hashes |
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
=over 4 |
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
=item @words = string2list( $space_separated_phrases ); |
615
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
Converts a space separated string of words and quoted phrases to an array; |
617
|
|
|
|
|
|
|
|
618
|
|
|
|
|
|
|
=item $space_sparated_string = list2string( @words ); |
619
|
|
|
|
|
|
|
|
620
|
|
|
|
|
|
|
Joins an array of strings into a space separated string of words and quoted phrases; |
621
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
=item %hash = string2hash( $string ); |
623
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
Converts a space separated string of equal-sign-associated key=value pairs into a simple hash. |
625
|
|
|
|
|
|
|
|
626
|
|
|
|
|
|
|
=item $string = hash2string( %hash ); |
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
Converts a simple hash into a space separated string of equal-sign-associated key=value pairs. |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
=item %hash = list2hash( @words ); |
631
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
Converts an array of equal-sign-associated key=value strings into a simple hash. |
633
|
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
=item @words = hash2list( %hash ); |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
Converts a hash to an array of equal-sign-associated key=value strings. |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
=back |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
Here are a few examples: |
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
=over 4 |
643
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
=item * |
645
|
|
|
|
|
|
|
|
646
|
|
|
|
|
|
|
C |
647
|
|
|
|
|
|
|
|
648
|
|
|
|
|
|
|
hello "I move next march" |
649
|
|
|
|
|
|
|
|
650
|
|
|
|
|
|
|
=item * |
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
C<@list = string2list('one "second item" 3 "four\nlines\nof\ntext"');> |
653
|
|
|
|
|
|
|
|
654
|
|
|
|
|
|
|
C |
655
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
second item |
657
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
=item * |
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
C 'Animal Cities', 'bar' =E 'Cheap' );> |
661
|
|
|
|
|
|
|
|
662
|
|
|
|
|
|
|
foo="Animal Cities" bar=Cheap |
663
|
|
|
|
|
|
|
|
664
|
|
|
|
|
|
|
=item * |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
C<%hash = string2hash('key=value "undefined key" words="the cat in the hat"');> |
667
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
C |
669
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
the cat in the hat |
671
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
C |
673
|
|
|
|
|
|
|
|
674
|
|
|
|
|
|
|
1 |
675
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
=back |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
=cut |
679
|
|
|
|
|
|
|
|
680
|
|
|
|
|
|
|
# @words = string2list( $space_separated_phrases ); |
681
|
|
|
|
|
|
|
sub string2list { |
682
|
2
|
|
|
2
|
1
|
24
|
my $text = shift; |
683
|
|
|
|
|
|
|
|
684
|
2
|
50
|
|
|
|
8
|
carp "string2list called with a non-text argument, '$text'" if (ref $text); |
685
|
|
|
|
|
|
|
|
686
|
2
|
|
|
|
|
3
|
my @words; |
687
|
2
|
|
|
|
|
3
|
my $word = ''; |
688
|
|
|
|
|
|
|
|
689
|
2
|
|
|
|
|
12
|
while ( length $text ) { |
690
|
13
|
100
|
|
|
|
150
|
if ($text =~ s/\A(?: ([^\"\s\\]+) | \\(.) )//mx) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
691
|
4
|
|
|
|
|
14
|
$word .= $1; |
692
|
|
|
|
|
|
|
} elsif ($text =~ s/\A"((?:[^\"\\]|\\.)*)"//mx) { |
693
|
4
|
|
|
|
|
15
|
$word .= $1; |
694
|
|
|
|
|
|
|
} elsif ($text =~ s/\A\s+//m){ |
695
|
5
|
|
|
|
|
8
|
push(@words, unprintable($word)); |
696
|
5
|
|
|
|
|
10
|
$word = ''; |
697
|
|
|
|
|
|
|
} elsif ($text =~ s/\A"//) { |
698
|
0
|
|
|
|
|
0
|
carp "string2list found an unmatched quote at '$text'"; |
699
|
0
|
|
|
|
|
0
|
return; |
700
|
|
|
|
|
|
|
} else { |
701
|
0
|
|
|
|
|
0
|
carp "string2list parse exception at '$text'"; |
702
|
0
|
|
|
|
|
0
|
return; |
703
|
|
|
|
|
|
|
} |
704
|
|
|
|
|
|
|
} |
705
|
2
|
|
|
|
|
6
|
push(@words, unprintable($word)); |
706
|
|
|
|
|
|
|
|
707
|
2
|
|
|
|
|
15
|
return @words; |
708
|
|
|
|
|
|
|
} |
709
|
|
|
|
|
|
|
|
710
|
|
|
|
|
|
|
# $space_sparated_string = list2string( @words ); |
711
|
|
|
|
|
|
|
sub list2string { |
712
|
1
|
|
|
1
|
1
|
8
|
join ( ' ', map qprintable($_), @_ ); |
713
|
|
|
|
|
|
|
} |
714
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
# %hash = list2hash( @words ); |
716
|
|
|
|
|
|
|
sub list2hash { |
717
|
1
|
|
|
1
|
1
|
2
|
my @pairs; |
718
|
1
|
|
|
|
|
5
|
foreach (@_) { |
719
|
3
|
|
|
|
|
19
|
my ($key, $val) = m/\A(.*?)(?:\=(.*))?\Z/s; |
720
|
3
|
|
|
|
|
11
|
push @pairs, $key, $val; |
721
|
|
|
|
|
|
|
} |
722
|
1
|
|
|
|
|
9
|
return @pairs; |
723
|
|
|
|
|
|
|
} |
724
|
|
|
|
|
|
|
|
725
|
|
|
|
|
|
|
# @words = hash2list( %hash ); |
726
|
|
|
|
|
|
|
sub hash2list { |
727
|
1
|
|
|
1
|
1
|
1
|
my @words; |
728
|
1
|
|
|
|
|
6
|
while ( scalar @_ ) { |
729
|
2
|
|
|
|
|
5
|
my ($key, $value) = ( shift, shift ); |
730
|
2
|
|
|
|
|
4
|
push @words, qprintable($key) . '=' . qprintable($value) |
731
|
|
|
|
|
|
|
} |
732
|
1
|
|
|
|
|
7
|
return @words; |
733
|
|
|
|
|
|
|
} |
734
|
|
|
|
|
|
|
|
735
|
|
|
|
|
|
|
# %hash = string2hash( $string ); |
736
|
|
|
|
|
|
|
sub string2hash { |
737
|
1
|
|
|
1
|
1
|
4
|
return list2hash( string2list( shift ) ); |
738
|
|
|
|
|
|
|
} |
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
# $string = hash2string( %hash ); |
741
|
|
|
|
|
|
|
sub hash2string { |
742
|
1
|
|
|
1
|
1
|
4
|
join ( ' ', hash2list( @_ ) ); |
743
|
|
|
|
|
|
|
} |
744
|
|
|
|
|
|
|
|
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
######################################################################## |
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
=head1 PREREQUISITES AND INSTALLATION |
749
|
|
|
|
|
|
|
|
750
|
|
|
|
|
|
|
This package should run on any standard Perl 5 installation. |
751
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
To install this package, download the distribution from a CPAN mirror, |
753
|
|
|
|
|
|
|
unpack the archive file, and execute the standard "perl Makefile.PL", |
754
|
|
|
|
|
|
|
"make test", "make install" sequence or your local equivalent. |
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
=head1 SEE ALSO |
758
|
|
|
|
|
|
|
|
759
|
|
|
|
|
|
|
Numerous modules provide collections of string escaping functions for specific contexts. |
760
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
The string2list function is similar to to the quotewords function in the standard distribution; see L. |
762
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
Use other packages to stringify more complex data structures; see L, L, or other similar package. |
764
|
|
|
|
|
|
|
|
765
|
|
|
|
|
|
|
=cut |
766
|
|
|
|
|
|
|
|
767
|
|
|
|
|
|
|
|
768
|
|
|
|
|
|
|
######################################################################## |
769
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
=head1 AUTHOR |
771
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
Matthew Simon Cavalletto, C<< >> |
773
|
|
|
|
|
|
|
|
774
|
|
|
|
|
|
|
|
775
|
|
|
|
|
|
|
=head1 BUGS |
776
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
Please report any bugs or feature requests to |
778
|
|
|
|
|
|
|
C, or through the web interface |
779
|
|
|
|
|
|
|
at L. |
780
|
|
|
|
|
|
|
I will be notified, and then you'll automatically be notified of |
781
|
|
|
|
|
|
|
progress on your bug as I make changes. |
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
The following changes are in progress or under consideration: |
784
|
|
|
|
|
|
|
|
785
|
|
|
|
|
|
|
=over 4 |
786
|
|
|
|
|
|
|
|
787
|
|
|
|
|
|
|
=item * |
788
|
|
|
|
|
|
|
|
789
|
|
|
|
|
|
|
Clarify documentation regarding printable / evalable functions. |
790
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
Rename evalable functions. |
792
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
Clarify the language being used in the documentation. |
794
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
http://perldoc.perl.org/perlop.html#Quote-and-Quote-like-Operators |
796
|
|
|
|
|
|
|
|
797
|
|
|
|
|
|
|
http://rt.cpan.org/Public/Bug/Display.html?id=19765 |
798
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
=item * |
800
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
Does this problem with the \r character only show up on Windows? |
802
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
http://rt.cpan.org/Public/Bug/Display.html?id=19766 |
804
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
=item * |
806
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
I would like to suggest another the inclusion of the '|' character into the escapable list. I know that the '|' has no special function while printing but it could be useful when using regexp matching. In fact, an extra function for escaping regexp reserved characters could be quite handy. |
808
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
-- Filipe Garrett |
810
|
|
|
|
|
|
|
|
811
|
|
|
|
|
|
|
=item * |
812
|
|
|
|
|
|
|
|
813
|
|
|
|
|
|
|
Use \b word-boundary test in elide's regular expression rather than \s|\Z. |
814
|
|
|
|
|
|
|
|
815
|
|
|
|
|
|
|
=item * |
816
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
Check for possible problems in the use of printable escaping functions and list2hash. For example, are the encoded strings for hashes with high-bit characters in their keys properly unquoted and unescaped? |
818
|
|
|
|
|
|
|
|
819
|
|
|
|
|
|
|
=item * |
820
|
|
|
|
|
|
|
|
821
|
|
|
|
|
|
|
In string2list, quotes embedded in a word (eg: a@"!a) shouldn't cause phrase breaks. |
822
|
|
|
|
|
|
|
|
823
|
|
|
|
|
|
|
=item * |
824
|
|
|
|
|
|
|
|
825
|
|
|
|
|
|
|
Allow escape specifications to contain = signs and optional arguments, so that users can request certain string lengths with C. |
826
|
|
|
|
|
|
|
|
827
|
|
|
|
|
|
|
=back |
828
|
|
|
|
|
|
|
|
829
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
=head1 SUPPORT |
831
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
833
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
perldoc String::Escape |
835
|
|
|
|
|
|
|
|
836
|
|
|
|
|
|
|
You can also look for information at: |
837
|
|
|
|
|
|
|
|
838
|
|
|
|
|
|
|
=over 4 |
839
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker |
841
|
|
|
|
|
|
|
|
842
|
|
|
|
|
|
|
L |
843
|
|
|
|
|
|
|
|
844
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
845
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
L |
847
|
|
|
|
|
|
|
|
848
|
|
|
|
|
|
|
=item * CPAN Ratings |
849
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
L |
851
|
|
|
|
|
|
|
|
852
|
|
|
|
|
|
|
=item * Search CPAN |
853
|
|
|
|
|
|
|
|
854
|
|
|
|
|
|
|
L |
855
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
=back |
857
|
|
|
|
|
|
|
|
858
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
860
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
Initial versions developed at Evolution Online Systems with Eleanor J. Evans and Jeremy G. Bishop. |
862
|
|
|
|
|
|
|
|
863
|
|
|
|
|
|
|
|
864
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
865
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
Copyright 2010, 2002 Matthew Simon Cavalletto. |
867
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
Portions copyright 1996, 1997, 1998, 2001 Evolution Online Systems, Inc. |
869
|
|
|
|
|
|
|
|
870
|
|
|
|
|
|
|
You may use, modify, and distribute this software under the same terms as Perl. |
871
|
|
|
|
|
|
|
|
872
|
|
|
|
|
|
|
See http://dev.perl.org/licenses/ for more information. |
873
|
|
|
|
|
|
|
|
874
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
=cut |
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
######################################################################## |
878
|
|
|
|
|
|
|
|
879
|
|
|
|
|
|
|
1; # End of String::Escape |