| 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 |