1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
|
package Text::Capitalize;
=encoding utf8
=head1 NAME
Text::Capitalize - capitalize strings ("to WORK AS titles" becomes "To Work as Titles")
=head1 SYNOPSIS
use Text::Capitalize;
print capitalize( "...and justice for all" ), "\n";
...And Justice For All
print capitalize_title( "...and justice for all" ), "\n";
...And Justice for All
print capitalize_title( "agent of SFPUG", PRESERVE_ALLCAPS=>1 ), "\n";
Agent of SFPUG
print capitalize_title( "the ring: symbol or cliche?",
PRESERVE_WHITESPACE=>1 ), "\n";
The Ring: Symbol or Cliche?
(Note, double-space after colon is still there.)
# To work on international characters, may need to set locale
use Env qw( LANG );
$LANG = "en_US";
print capitalize_title( "über maus" ), "\n";
Über Maus
use Text::Capitalize qw( scramble_case );
print scramble_case( 'It depends on what you mean by "mean"' );
It dEpenDS On wHAT YOu mEan by "meAn".
=head1 ABSTRACT
Text::Capitalize is for capitalizing strings in a manner
suitable for use in titles.
=head1 DESCRIPTION
Text::Capitalize provides some routines for B<title-like>
formatting of strings.
The simple B<capitalize> function just makes the initial character
of each word uppercase, and forces the rest to lowercase.
The B<capitalize_title> function applies English title case rules
(discussed below) where only the "important" words are supposed
to be capitalized. There are also some customization features
provided to allow the user to choose variant rules.
Comparing B<capitalize> and B<captialize_title>:
Input: "lost watches of splitsville"
capitalize: "Lost Watches Of Splitsville"
capitalize_title: "Lost Watches of Splitsville"
Some examples of formatting with B<capitalize_title>:
Input: "KiLLiNG TiMe"
capitalize_title: "Killing Time"
Input: "we have come to wound the autumnal city"
capitalize_title: "We Have Come to Wound the Autumnal City"
Input: "ask for whom they ask for"
captialize_title: "Ask for Whom They Ask For"
Text::Capitalize also provides some functions for special effects
such as B<scramble_case>, which typically would be used for this sort
of transformation:
Input: "get whacky"
scramble_case: "gET wHaCkY" (or something similar)
=head1 EXPORTS
=head2 default exports
=over
=cut
use 5.006;
use strict;
use warnings;
use utf8;
# use locale;
use Carp;
use Exporter;
use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION);
use vars qw($DEBUG);
$DEBUG = 0;
@ISA = qw(Exporter);
@EXPORT = qw(capitalize capitalize_title);
@EXPORT_OK = qw(@exceptions
%defaults_capitalize_title
scramble_case
random_case
zippify_case
capitalize_title_original
);
$VERSION = '1.5';
# Define the pattern to match "exceptions": the minor words
# that don't usually get capitalized in titles (used by capitalize_title)
use vars qw(@exceptions);
@exceptions = qw(
a an the
and or nor for but so yet
to of by at for but in with has
de von
);
# Define the default arguments for the capitalize_title function
use vars qw(%defaults_capitalize_title);
%defaults_capitalize_title = (
PRESERVE_WHITESPACE => 0,
PRESERVE_ALLCAPS => 0,
PRESERVE_ANYCAPS => 0,
NOT_CAPITALIZED => \@exceptions,
);
# Defining patterns to match "words" and "sentences" (used by capitalize_title)
use vars qw($word_rule $sentence_rule);
use vars qw($anything $ellipsis $dot $qmark $emdash $terminator $ws);
$word_rule = qr{ ([^\w\s]*) # $1 - leading punctuation
# (e.g. ellipsis, leading apostrophe)
([\w']*) # $2 - the word itself (includes non-leading apostrophes)
([^\w\s]*) # $3 - trailing punctuation
# (e.g. comma, ellipsis, period)
(\s*) # $4 - trailing whitespace
# (usually " ", though at EOL prob "")
}x ;
# Pieces for the $sentence_rule
$anything = qr{.*?};
$ellipsis = qr{\Q...};
$dot = qr{\Q.};
$qmark = qr{\Q?};
$emdash = qr{\Q--};
$terminator = qr{$ellipsis|$dot|$qmark|!|:|$emdash|$};
$ws = qr{\s*};
$sentence_rule =
qr{ ( $anything # anything up to...
$terminator # any sentence terminator (*or* the EOS)
$ws # trailing whitespace, if any
) # all captured to $1
}ox;
=item capitalize
Makes the initial character of each word uppercase, and forces the
rest to lowercase.
The original routine by Stanislaw Y. Pusep.
=cut
sub capitalize {
local $_ = shift;
s/\b(.*?)\b/$1 eq uc $1 ? $1 : "\u\L$1"/ge;
return $_;
}
=item capitalize_title
Applies English title case rules (See L<BACKGROUND>) where only the
"important" words are supposed to be capitalized.
The one required argument is the string to be capitalized.
Some customization options may be passed in as pairs of names and
values following the required argument.
The following customizations are allowed:
Boolean:
PRESERVE_WHITESPACE
PRESERVE_ALLCAPS
PRESERVE_ANYCAPS
Array reference:
NOT_CAPITALIZED
See L<Customizing the Exceptions to Capitalization>.
=cut
sub capitalize_title {
my $string = shift;
my %args = (%defaults_capitalize_title,
@_ # imports the argument pair list, if any
);
# Checking for spelling errors in options
foreach (keys %args) {
unless (exists $defaults_capitalize_title{$_}) {
carp "Bad option $_\n";
}
}
my $keep_ws = $args{ PRESERVE_WHITESPACE };
my $keep_acronyms = $args{ PRESERVE_ALLCAPS };
my $keep_mixups = $args{ PRESERVE_ANYCAPS };
my $exceptions_or = join '|', @{ $args{ NOT_CAPITALIZED } };
my $exception_rule = qr{^(?:$exceptions_or)$}i;
my $new_string = "";
### Processing each sentence (titles can have multiple sentences)
while ( $string =~ /$sentence_rule/g ) {
my $sentence = $1;
my $new_sentence = "";
my @words = ();
# The array @words will contain records about each word, including its
# surroundings: trailing whitespace and leading or trailing punctuation
# (for cases such as "...and", "'em", "and...", "F.B.I.")
# Each row is an aref of: $punct_leading, $word, $punct_trailing, $spc
my $i = 0;
while ($sentence =~ /$word_rule/g) {
# If we've matched something, load it (pattern yields an empty match at eos)
if ( ($2 ne '') or $1 or $3 or ($4 ne '') ) {
$words[ $i ] = [ $1, $2, $3, $4 ];
$i++;
}
}
### Processing each word
my ($punct_leading, $word, $punct_trailing, $spc);
my $first = 0;
my $last = $#words;
for ( $i = $first; $i <= $last; $i++ ) {
{
# (easier to know when you're doing the first and last using explicit counter)
($punct_leading, $word, $punct_trailing, $spc) = ( @{ $words[$i] } );
unless ($keep_ws) { # collapse whitespace
$spc = " " if (length($spc) > 0);
}
# Keep words with any capitals (e.g. "iMac") if they're being passed through.
next if ( ($keep_mixups) && ( $word =~ m{[[:upper:]]} ) );
# Keep all uppercase words if they're being passed through.
next if ( ($keep_acronyms) && ( $word =~ m{^[[:upper:]]+$}) );
# Fugliness to get some French names to work, e.g. "d'Alembert", "l'Hospital"
if ( $word =~ m{^[dl]'}) {
$word =~ s{ ^(d') (\w) }{ lc($1) . ucfirst($2) }iex;
$word =~ s{ ^(l') (\w) }{ lc($1) . ucfirst($2) }iex;
# But upcase first char if first or last word
if ( ($i == $first) or ($i == $last) ) {
$word = ucfirst( $word );
}
next;
}
# The first word and the last are always capitalized
if ( ($i == $first) or ($i == $last) ) {
$word = ucfirst( lc( $word ) );
next;
}
# upcase all words, except for the exceptions
if ( $word =~ m{$exception_rule} ) {
$word = lc( $word );
} else {
$word = ucfirst( lc( $word ) );
}
} continue { # Append word to the new sentence
$new_sentence .= $punct_leading . $word . $punct_trailing . $spc;
}
} # end of per word for loop
$new_string .= $new_sentence;
} # end of per sentence loop.
# Delete leading/trailing spaces, unless preserving whitespace,
# (Doing as final step to avoid dropping spaces *between* sentences.)
unless ($keep_ws) {
$new_string =~ s|^\s+||;
$new_string =~ s|\s+$||;
}
return $new_string;
} # end sub capitalize_title
=back
=head2 optional exports
=over
=item @exceptions
The list of minor words that don't usually get capitalized in
titles (used by L<capitalize_title>). Defaults to:
a an the
and or nor for but so yet
to of by at for but in with has
de von
=item %defaults_capitalize_title
Defines the default arguments for the capitalize_title function
Initially, this is set-up to shut off the features
PRESERVE_WHITESPACE, PRESERVE_ALLCAPS and PRESERVE_ANYCAPS;
it also has L<@exceptions> as the NOT_CAPITALIZED list.
=item scramble_case
This routine provides a special effect: sCraMBliNg tHe CaSe
The algorithm here uses a modified probability distribution to get
a weirder looking effect than simple randomization such as with L<random_case>.
For a discussion of the algorithm, see L<SPECIAL EFFECTS>.
=cut
# Instead of initializing $uppers, $downers to zero, using fudged
# initial counts to
# (1) provide an initial bias against leading with uppercase,
# (2) eliminate need to watch for division by zero on $tweak below.
# Rather than "int(rand(2))" which generates a 50/50 distribution of 0s and 1s,
# we're using "int(rand(1+$tweak))" where $tweak will
# provide a restoring force back to the average
# So here we want $tweak:
# to go to 1 when you approach $uppers = $downers
# to be larger than 1 if $downers > $uppers
# to be less than 1 if $uppers > $downers
# A simple formula that does this:
# $uppity = int( rand( 1 + $downers/$uppers) );
# The alternative (proposed by Randal Schwartz) is no real speed improvement:
# $uppity = rand( $uppers + $downers ) > $uppers;
# (though there are no worries about divide by zero there).
# Note that this benchmarks faster:
# @chars = split //, $string;
# Than:
# @chars = split /(?<=[[:alpha:]])/, $string;
sub scramble_case {
my $string = shift;
my (@chars, $uppity, $newstring, $total, $uppers, $downers, $tweak);
@chars = split //, $string;
$uppers = 2;
$downers = 1;
foreach my $c (@chars) {
$uppity = int( rand( 1 + $downers/$uppers) );
if ($uppity) {
$c = ucfirst($c);
$uppers++;
} else {
$c = lc($c);
$downers++;
}
}
$newstring = join '', @chars;
return $newstring;
}
=item random_case
Randomizes the case of each character with a 50-50 chance
of each one becoming upper or lower case.
=cut
sub random_case {
local $_;
my $string = shift;
my (@chars, $uppity, $newstring);
@chars = split //, $string;
foreach (@chars) {
$uppity = int ( rand(2) ); # simple, 50-50 random pick
if ($uppity) {
$_ = uc;
} else {
$_ = lc;
}
}
$newstring = join '', @chars;
return $newstring;
}
=item zippify_case
Function to provide a special effect: "RANDOMLY upcasing WHOLE WORDS at a TIME".
This uses a similar algorithm to L<scramble_case>, though it also
ignores words on the L<@exceptions> list, just as L<capitalize_title> does.
=cut
sub zippify_case {
my $string = shift;
my (@words, $uppity, $newstring, $total, $uppers, $downers, $tweak);
@words = split /\b/, $string;
$uppers = 1;
$downers = 5;
WORD: foreach my $word (@words) {
foreach (@exceptions) {
next WORD if m/\Q$word\E/i;
}
# a modified "random" distribution with fewer "streaks" than normal.
$uppity = int( rand( 1 + $downers/$uppers ) );
if ($uppity) {
$word = ucfirst($word);
$uppers++;
} else {
$word = lc($word);
$downers++;
}
}
$newstring = join '', @words;
return $newstring;
}
1;
=back
=head1 BACKGROUND
The capitalize_title function tries to do the right thing by
default: adjust an arbitrary chunk of text so that it can be used
as a title. But as with many aspects of the human languages, it
is extremely difficult to come up with a set of programmatic
rules that will cover all cases.
=head2 Words that don't get capitalized
This web page:
http://www.continentallocating.com/World.Literature/General2/LiteraryTitles2.htm
presents some admirably clear rules for capitalizing titles:
ALL words in EVERY title are capitalized except
(1) a, an, and the,
(2) two and three letter conjunctions (and, or, nor, for, but, so, yet),
(3) prepositions.
Exceptions: The first and last words are always capitalized even
if they are among the above three groups.
But consider the case:
"It Waits Underneath the Sea"
Should the word "underneath" be downcased because it's a preposition?
Most English speakers would be surprised to see it that way.
Consequently, the default list of exceptions to capitalization in this module
only includes the shortest of the common prepositions (to of by at for but in).
The default entries on the exception list are:
a an the
and or nor for but so yet
to of by at for but in with has
de von
The observant may note that the last row is not composed of English
words. The honorary "de" has been included in honor of "Honoré de
Balzac". And "von" was added for the sake of equal time.
=head2 Customizing the Exceptions to Capitalization
If you have different ideas about the "rules" of English
(or perhaps if you're trying to use this code with another
language with different rules) you might like to substitute
a new exception list of your own:
capitalize_title( "Dude, we, like, went to Old Slavy, and uh, they didn't have it",
NOT_CAPITALIZED => [ qw( uh duh huh wha like man you know ) ] );
This should return:
Dude, We, like, Went To Old Slavy, And uh, They Didn't Have It
Less radically, you might like to simply add a word to the list,
for example "from":
use Text::Capitalize 0.2 qw( capitalize_title @exceptions );
push @exceptions, "from";
print capitalize_title( "fungi from yuggoth",
NOT_CAPITALIZED => \@exceptions);
This should output:
Fungi from Yuggoth
=head2 All Uppercase Words
In order to work with a wide range of input strings, by default
capitalize_title presumes that upper-case input needs to be adjusted
(e.g. "DOOM APPROACHES!" would become "Doom Approaches!"). But, this
doesn't allow for the possibilities such as an acronym in a title
(e.g. "RAM Prices Plummet" ideally should not become "Ram Prices
Plummet"). If the PRESERVE_ALLCAPS option is set, then it will be
presumed that an all-uppercase word is that way for a reason, and
will be left alone:
print capitalize_title( "ram more RAM down your throat",
PRESERVE_ALLCAPS => 1 );
This should output:
Ram More RAM Down Your Throat
=head2 Preserving Any Usage of Uppercase for Mixed-case Words
There are some other odd cases that are difficult to handle well,
notably mixed-case words such as "iMac", "CHiPs", and so on. For
these purposes, a PRESERVE_ANYCAPS option has been provided which
presumes that any usage of uppercase is there for a reason, in which
case the entire word should be passed through untouched. With
PRESERVE_ANYCAPS on, only the case of all lowercase words will ever
be adjusted:
print capitalize_title( "TLAs i have known and loved",
PRESERVE_ANYCAPS => 1 );
This should output:
TLAs I Have Known and Loved
print capitalize_title( "the next iMac: just another NeXt?",
PRESERVE_ANYCAPS => 1);
This should output:
The Next iMac: Just Another NeXt?
=head2 Handling Whitespace
By default, the capitalize_title function presumes that you're trying
to clean up potential title strings. As an extra feature it collapses
multiple spaces and tabs into single spaces. If this feature doesn't
seem desirable and you want it to literally restrict itself to
adjusting capitalization, you can force that behavior with the
PRESERVE_WHITESPACE option:
print capitalize_title( "it came from texas: the new new world order?",
PRESERVE_WHITESPACE => 1);
This should output:
It Came From Texas: The New New World Order?
(Note: the double-space after the colon is still there.)
=head2 Comparison to Text::Autoformat
As you might expect, there's more than one way to do this,
and these two pieces of code perform very similar functions:
use Text::Capitalize 0.2;
print capitalize_title( $t ), "\n";
use Text::Autoformat;
print autoformat { case => "highlight", right => length( $t ) }, $t;
Note: with autoformat, supplying the length of the string as the
"right margin" is much faster than plugging in an arbitrarily large
number. There doesn't seem to be any other way of turning off
line-breaking (e.g. by using the "fill" parameter) though possibly
there will be in the future.
As of this writing, "capitalize_title" has some advantages:
=over
=item 1.
It works on characters outside the English 7-bit ASCII
range, for example with my locale setting (en_US) the
ISO-8859-1 International characters are handled correctly,
so that "über maus" becomes "Über Maus".
=item 2.
Minor words following leading punctuation become upper case:
"...And Justice for All"
=item 3.
It works with multiple sentence input (e.g. "And sooner. And later."
should probably not be "And sooner. and later.")
=item 4.
The list of minor words is more extensive (i.e. includes: so, yet, nor),
and is also customizable.
=item 5.
There's a way of preserving acronyms via the PRESERVE_ALLCAPS option
and similarly, mixed-case words ("iMac", "NeXt", etc") with the
PRESERVE_ANYCAPS option.
=item 6.
capitalize_title is roughly ten times faster.
=back
Another difference is that Text::Autoformat's "highlight"
always preserves whitespace something like capitalize_title
does with the PRESERVE_WHITESPACE option set.
However, it should be pointed out that Text::Autoformat is under
active maintenance by Damian Conway. It also does far more than
this module, and you may want to use it for other reasons.
=head2 Still more ways to do it
Late breaking news: The second edition of the Perl Cookbook
has just come out. It now includes: "Properly Capitalizing
a Title or Headline" as recipe 1.14. You should
familiarize yourself with this if you want to become a true
master of all title capitalization routines.
(And I see that recipe 1.13 includes a "randcap" program as
an example, which as it happens does something like the
random_case function described below...)
=head1 SPECIAL EFFECTS
Some functions have been provided to make strings look weird
by scrambling their capitalization ("lIKe tHiS"):
random_case and scramble_case. The function "random_case"
does a straight-forward randomization of capitalization so
that each letter has a 50-50 chance of being upper or lower
case. The function "scramble_case" performs a very similar
function, but does a slightly better job of producing something
"weird-looking".
The difficulty is that there are differences between human
perception of randomness and actual randomness. Consider
the fact that of the sixteen ways that the four letter word
"word" can be capitalized, three of them are rather boring:
"word", "Word" and "WORD". To make it less likely that
scramble_case will produce dull output when you want "weird"
output, a modified probability distribution has been used
that records the history of previous outcomes, and tweaks
the likelihood of the next decision in the opposite
direction, back toward the expected average. In effect,
this simulates a world in which the Gambler's Fallacy is
correct ("Hm... red has come up a lot, I bet that black is
going to come up now."). "Streaks" are much less likely
with scramble_case than with random_case.
Additionally, with scramble_case the probability that the
first character of the input string will become upper-case
has been tweaked to less than 50%. (Future versions may
apply this tweak on a per-word basis rather than just on a
per-string basis).
There is also a function that scrambles capitalization on
a word-by-word basis called "zippify_case", which should produce output
like: "In my PREVIOUS life i was a LATEX-novelty REPAIRMAN!"
=head1 EXPORT
By default, this version of the module provides the two
functions capitalize and capitalize_title. Future versions
will have no further additions to the default export list.
Optionally, the following functions may also be exported:
=over
=item scramble_case
A function to scramble capitalization in a wEiRD loOOkInG wAy.
Supposed to look a little stranger than the simpler random_case
output
=item random_case
Function to randomize capitalization of each letter in the
string. Compare to "scramble_case"
=item zippify_case
A function like "scramble_case" that acts on a word-by-word basis
(Somewhat LIKE this, YOU know?).
=back
It is also possible to export the following variables:
=over
=item @exceptions
The list of minor words that capitalize_title uses by default to
determine the exceptions to capitalization.
=item %defaults-capitalize_title
The hash of allowed arguments (with defaults) that the
capitalize_title function uses.
=back
=head1 BUGS
1. In capitalize_title, quoted sentence terminators are
treated as actual sentence breaks, e.g. in this case:
'say "yes but!" and "know what?"'
The program sees the ! and effectively treats this as two
separate sentences: the word "but" becomes "But" (under the
rule that last words must always be uppercase, even if they're
on the exception list) and the word "and" becomes "And" (under
the first word rule).
2. There's no good way to automatically handle names like
"McCoy". Consider the difficulty of disambiguating "Macadam
Roads" from "MacAdam Rode". If you need to solve problems like
this, consider using the case_surname function of Lingua::En::NameParse.
3. In general, Text::Capitalize is a very parochial
English oriented module that looks like it belongs in the
"Lingua::En::*" tree.
4. There's currently no way of doing a PRESERVE_ANYCAPS
that *also* adjusts capitalization of words on the exception
list, so that "iMac Or iPod" would become "iMac or iPod".
=head1 SEE ALSO
L<Text::Autoformat>
"The Perl Cookbook", second edition, recipes 1.13 and 1.14
L<Lingua::En::NameParse>
About "scramble_case":
L<http://obsidianrook.com/devnotes/talks/esthetic_randomness/>
=head1 VERSION
Version 0.9
=head1 AUTHORS
Joseph M. Brenner
E-Mail: doom@kzsu.stanford.edu
Homepage: http://obsidianrook.com/map
Stanislaw Y. Pusep (who wrote "capitalize")
E-Mail: stanis@linuxmail.org
ICQ UIN: 11979567
Homepage: http://sysdlabs.hypermart.net/
And many thanks (for feature suggestions and code examples) to:
Belden Lyman, Yary Hcluhan, Randal Schwartz
=head1 COPYRIGHT AND LICENSE
Copyright 2003 by Joseph Brenner. All rights reserved.
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
|