This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Integrate non-ithreads fix to mainline
authorNick Ing-Simmons <nik@tiuk.ti.com>
Mon, 22 Oct 2001 06:51:22 +0000 (06:51 +0000)
committerNick Ing-Simmons <nik@tiuk.ti.com>
Mon, 22 Oct 2001 06:51:22 +0000 (06:51 +0000)
p4raw-id: //depot/perl@12556

32 files changed:
MANIFEST
embed.h
embed.pl
ext/threads/shared/Makefile.PL [new file with mode: 0755]
ext/threads/shared/README [new file with mode: 0644]
ext/threads/shared/shared.pm [new file with mode: 0644]
ext/threads/shared/shared.xs [new file with mode: 0644]
ext/threads/shared/t/sv_refs.t [new file with mode: 0644]
ext/threads/shared/t/sv_simple.t [new file with mode: 0644]
global.sym
installhtml
lib/unicore/To/Lower.pl
lib/unicore/To/SpecLower.pl [deleted file]
lib/unicore/To/SpecTitle.pl [deleted file]
lib/unicore/To/SpecUpper.pl [deleted file]
lib/unicore/To/Title.pl
lib/unicore/To/Upper.pl
lib/unicore/mktables
perl.h
pod/buildtoc.PL
pod/perl.pod
pod/perlapi.pod
pod/perlfunc.pod
pod/perlpod.pod
pod/perlpodspec.pod [new file with mode: 0644]
pod/perltoc.pod
pod/perlunicode.pod
proto.h
sharedsv.c
t/op/lc.t
t/op/utf8decode.t [changed mode: 0755->0644]
utf8.c

index 9236c3c..d21175d 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -580,6 +580,12 @@ ext/threads/t/stress_string.t      Test with multiple threads, string cv argument.
 ext/threads/threads.h          ithreads
 ext/threads/threads.pm          ithreads
 ext/threads/threads.xs         ithreads
+ext/threads/shared/Makefile.PL  thread shared variables
+ext/threads/shared/README       thread shared variables
+ext/threads/shared/shared.pm    thread shared variables
+ext/threads/shared/shared.xs    thread shared variables
+ext/threads/shared/t/sv_simple.t       thread shared variables
+ext/threads/shared/t/sv_refs.t thread shared variables
 ext/Time/HiRes/Changes         Time::HiRes extension
 ext/Time/HiRes/hints/dynixptx.pl       Hint for Time::HiRes for named architecture
 ext/Time/HiRes/hints/sco.pl    Hints for Time::HiRes for named architecture
@@ -1598,9 +1604,6 @@ lib/unicore/Scripts.txt           Unicode character database
 lib/unicore/SpecCase.txt       Unicode character database
 lib/unicore/To/Digit.pl                Unicode character database
 lib/unicore/To/Lower.pl                Unicode character database
-lib/unicore/To/SpecLower.pl    Unicode character database
-lib/unicore/To/SpecTitle.pl    Unicode character database
-lib/unicore/To/SpecUpper.pl    Unicode character database
 lib/unicore/To/Title.pl                Unicode character database
 lib/unicore/To/Upper.pl                Unicode character database
 lib/unicore/UCD.html           Unicode character database
@@ -1854,6 +1857,7 @@ pod/perlop.pod                    Operator info
 pod/perlopentut.pod            open() tutorial
 pod/perlothrtut.pod            Threads old tutorial
 pod/perlpod.pod                        Pod info
+pod/perlpodspec.pod            Pod specification
 pod/perlport.pod               Portability guide
 pod/perlre.pod                 Regular expression info
 pod/perlref.pod                        References info
diff --git a/embed.h b/embed.h
index b591206..8c584a5 100644 (file)
--- a/embed.h
+++ b/embed.h
 #define swash_fetch            Perl_swash_fetch
 #define taint_env              Perl_taint_env
 #define taint_proper           Perl_taint_proper
+#define to_utf8_case           Perl_to_utf8_case
 #define to_utf8_lower          Perl_to_utf8_lower
 #define to_utf8_upper          Perl_to_utf8_upper
 #define to_utf8_title          Perl_to_utf8_title
 #define swash_fetch(a,b,c)     Perl_swash_fetch(aTHX_ a,b,c)
 #define taint_env()            Perl_taint_env(aTHX)
 #define taint_proper(a,b)      Perl_taint_proper(aTHX_ a,b)
+#define to_utf8_case(a,b,c,d,e,f)      Perl_to_utf8_case(aTHX_ a,b,c,d,e,f)
 #define to_utf8_lower(a,b,c)   Perl_to_utf8_lower(aTHX_ a,b,c)
 #define to_utf8_upper(a,b,c)   Perl_to_utf8_upper(aTHX_ a,b,c)
 #define to_utf8_title(a,b,c)   Perl_to_utf8_title(aTHX_ a,b,c)
index 8c3ba3c..6c20660 100755 (executable)
--- a/embed.pl
+++ b/embed.pl
@@ -1818,6 +1818,8 @@ Ap        |SV*    |swash_init     |char* pkg|char* name|SV* listsv \
 Ap     |UV     |swash_fetch    |SV *sv|U8 *ptr|bool do_utf8
 Ap     |void   |taint_env
 Ap     |void   |taint_proper   |const char* f|const char* s
+Ap     |UV     |to_utf8_case   |U8 *p|U8* ustrp|STRLEN *lenp \
+                               |SV **swash|char *normal|char *special
 Ap     |UV     |to_utf8_lower  |U8 *p|U8* ustrp|STRLEN *lenp
 Ap     |UV     |to_utf8_upper  |U8 *p|U8* ustrp|STRLEN *lenp
 Ap     |UV     |to_utf8_title  |U8 *p|U8* ustrp|STRLEN *lenp
diff --git a/ext/threads/shared/Makefile.PL b/ext/threads/shared/Makefile.PL
new file mode 100755 (executable)
index 0000000..8587906
--- /dev/null
@@ -0,0 +1,26 @@
+use ExtUtils::MakeMaker;
+# See lib/ExtUtils/MakeMaker.pm for details of how to influence
+# the contents of the Makefile that is written.
+
+use Config;
+
+
+unless($Config{'useithreads'} eq 'define') {
+    die "We need a perl that is built with USEITHREAD!\n";
+}
+
+WriteMakefile(
+    'NAME'             => 'threads::shared',
+    'VERSION_FROM'     => 'shared.pm', # finds $VERSION
+    'PREREQ_PM'                => {}, # e.g., Module::Name => 1.1
+    ($] >= 5.005 ?    ## Add these new keywords supported since 5.005
+      (ABSTRACT_FROM => 'shared.pm', # retrieve abstract from module
+       AUTHOR     => 'Arthur Bergman <arthur@contiller.se>') : ()),
+    'LIBS'             => [''], # e.g., '-lm'
+    'DEFINE'           => '', # e.g., '-DHAVE_SOMETHING'
+       # Insert -I. if you add *.h files later:
+    'INC'              => '', # e.g., '-I/usr/include/other'
+       # Un-comment this if you add C files to link with later:
+    # 'OBJECT'         => '$(O_FILES)', # link all the C files too
+
+);
diff --git a/ext/threads/shared/README b/ext/threads/shared/README
new file mode 100644 (file)
index 0000000..0690835
--- /dev/null
@@ -0,0 +1,26 @@
+threads/shared version 0.02
+===========================
+
+This module needs perl 5.7.2 or later compiled with USEITHREADS, 
+It lets you share simple data structures between threads.
+
+INSTALLATION
+
+To install this module type the following:
+
+   perl Makefile.PL
+   make
+   make test
+   make install
+
+DEPENDENCIES
+
+This module requires these other modules and libraries:
+
+threads 0.03;
+
+COPYRIGHT AND LICENCE
+
+Copyright (C) 2001 Arthur Bergman artur at contiller.se
+Same licence as perl.
+
diff --git a/ext/threads/shared/shared.pm b/ext/threads/shared/shared.pm
new file mode 100644 (file)
index 0000000..2aae9f1
--- /dev/null
@@ -0,0 +1,125 @@
+
+package threads::shared;
+
+use strict;
+use warnings;
+use Config;
+use Scalar::Util qw(weaken);
+use attributes qw(reftype);
+
+BEGIN {
+    if($Config{'useithreads'} && $Config::threads) {
+       *share = \&share_enabled;
+       *cond_wait = \&cond_wait_disabled;
+       *cond_signal = \&cond_signal_disabled;
+       *cond_broadcast = \&cond_broadcast_disabled;
+       *unlock = \&unlock_disabled;
+       *lock = \&lock_disabled;
+    } else {
+       *share = \&share_enabled;
+    }
+}
+
+require Exporter;
+require DynaLoader;
+our @ISA = qw(Exporter DynaLoader);
+
+our @EXPORT = qw(share cond_wait cond_broadcast cond_signal unlock lock);
+our $VERSION = '0.01';
+
+our %shared;
+
+
+sub cond_wait_disabled { return @_ };
+sub cond_signal_disabled { return @_};
+sub cond_broadcast_disabled { return @_};
+sub unlock_disabled { 1 };
+sub lock_disabled { 1 }
+sub share_disabled { return @_}
+
+sub share_enabled (\[$@%]) { # \]     
+    my $value = $_[0];
+    my $ref = reftype($value);
+    if($ref eq 'SCALAR') {
+      my $obj = \threads::shared::sv->new($$value);
+      bless $obj, 'threads::shared::sv';
+      $shared{$$obj} = $value;
+      weaken($shared{$$obj});
+    } else {
+       die "You cannot share ref of type $_[0]\n";
+    }
+}
+
+sub CLONE {
+    return unless($_[0] eq "threads::shared");
+       foreach my $ptr (keys %shared) {
+           if($ptr) {
+               thrcnt_inc($shared{$ptr});
+           }
+       }
+}
+
+
+package threads::shared::sv;
+use base 'threads::shared';
+
+package threads::shared::av;
+use base 'threads::shared';
+
+package threads::shared::hv;
+use base 'threads::shared';
+
+
+bootstrap threads::shared $VERSION;
+
+__END__
+
+=head1 NAME
+
+threads::shared - Perl extension for sharing data structures between threads
+
+=head1 SYNOPSIS
+
+  use threads::shared;
+
+  my($foo, @foo, %foo);
+  share(\$foo);
+  share(\@foo);
+  share(\%hash);
+  my $bar = share([]);
+  $hash{bar} = share({});
+
+  lock(\%hash);
+  unlock(\%hash);
+  cond_wait($scalar);
+  cond_broadcast(\@array);
+  cond_signal($scalar);
+
+=head1 DESCRIPTION
+
+ This modules allows you to share() variables. These variables will then be shared across different threads (and pseudoforks on win32). They are used together with the threads module.
+
+=head2 EXPORT
+
+share(), lock(), unlock(), cond_wait, cond_signal, cond_broadcast
+
+=head1 BUGS
+
+Not stress tested!
+Does not support references
+Does not support splice on arrays!
+The exported functions need a reference due to unsufficent prototyping!
+
+=head1 AUTHOR
+
+Artur Bergman <lt>artur at contiller.se<gt>
+
+threads is released under the same license as Perl
+
+=head1 SEE ALSO
+
+L<perl> L<threads>
+
+=cut
+
+
diff --git a/ext/threads/shared/shared.xs b/ext/threads/shared/shared.xs
new file mode 100644 (file)
index 0000000..90049e2
--- /dev/null
@@ -0,0 +1,144 @@
+
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+
+void shared_sv_attach_sv (SV* sv, shared_sv* shared) {
+    HV* shared_hv = get_hv("threads::shared::shared", FALSE);
+    SV* id = newSViv((IV)shared);
+    STRLEN length = sv_len(id);
+    SV* tiedobject;
+    SV** tiedobject_ = hv_fetch(shared_hv, SvPV(id,length), length, 0);
+    if(tiedobject_) {
+       tiedobject = (*tiedobject_);
+        SvROK_on(sv);
+        SvRV(sv) = SvRV(tiedobject);
+
+    } else {
+        croak("die\n");
+    }
+}
+
+
+int shared_sv_fetch_mg (pTHX_ SV* sv, MAGIC *mg) {
+    shared_sv* shared = (shared_sv*) SvIV(mg->mg_obj);
+    SHAREDSvLOCK(shared);
+    if(SvROK(SHAREDSvGET(shared))) {
+        shared_sv* target = (shared_sv*) SvIV(SvRV(SHAREDSvGET(shared)));
+       shared_sv_attach_sv(sv, target);
+    } else {
+        sv_setsv(sv, SHAREDSvGET(shared));
+    }
+    SHAREDSvUNLOCK(shared);
+
+    return 0;
+}
+
+int shared_sv_store_mg (pTHX_ SV* sv, MAGIC *mg) {
+    shared_sv* shared = (shared_sv*) SvIV(mg->mg_obj);
+    SHAREDSvLOCK(shared);
+    if(SvROK(SHAREDSvGET(shared)))
+        Perl_sharedsv_thrcnt_dec(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(shared))));
+    SHAREDSvEDIT(shared);
+    if(SvROK(sv)) {
+        shared_sv* target = Perl_sharedsv_find(aTHX_ SvRV(sv));
+        if(!target) {
+            SHAREDSvRELEASE(shared);
+            sv_setsv(sv,SHAREDSvGET(shared));
+            SHAREDSvUNLOCK(shared);            
+            Perl_croak(aTHX_ "You cannot assign a non shared reference to a shared scalar");
+        }
+        Perl_sv_free(PL_sharedsv_space,SHAREDSvGET(shared));
+        SHAREDSvGET(shared) = newRV_noinc(newSViv((IV)target));
+        SvROK_off(sv);
+    } else {
+        sv_setsv(SHAREDSvGET(shared), sv);
+    }
+    SHAREDSvRELEASE(shared);
+    if(SvROK(SHAREDSvGET(shared)))
+       Perl_sharedsv_thrcnt_inc(aTHX_ (shared_sv*) SvIV(SvRV(SHAREDSvGET(shared))));       
+    SHAREDSvUNLOCK(shared);
+    return 0;
+}
+
+int shared_sv_destroy_mg (pTHX_ SV* sv, MAGIC *mg) {
+    shared_sv* shared = (shared_sv*) SvIV(mg->mg_obj);
+    if(!shared) 
+        return 0;
+    Perl_sharedsv_thrcnt_dec(aTHX_ shared);
+}
+
+MGVTBL svtable = {MEMBER_TO_FPTR(shared_sv_fetch_mg),
+                 MEMBER_TO_FPTR(shared_sv_store_mg),
+                 0,
+                 0,
+                 MEMBER_TO_FPTR(shared_sv_destroy_mg)
+};
+
+MODULE = threads::shared               PACKAGE = threads::shared               
+
+
+PROTOTYPES: DISABLE
+
+
+SV*
+ptr(ref)
+       SV* ref
+       CODE:
+       RETVAL = newSViv(SvIV(SvRV(ref)));
+       OUTPUT:
+       RETVAL
+
+
+SV*
+_thrcnt(ref)
+        SV* ref
+       CODE:
+        shared_sv* shared = Perl_sharedsv_find(aTHX, ref);
+        if(!shared)
+           croak("thrcnt can only be used on shared values");
+       SHAREDSvLOCK(shared);
+        RETVAL = newSViv(SvREFCNT(SHAREDSvGET(shared)));
+        SHAREDSvUNLOCK(shared);
+       OUTPUT:
+        RETVAL   
+
+
+void
+thrcnt_inc(ref)
+        SV* ref
+        CODE:
+       shared_sv* shared;
+        if(SvROK(ref)) 
+            ref = SvRV(ref);
+        shared = Perl_sharedsv_find(aTHX, ref);
+        if(!shared)
+           croak("thrcnt can only be used on shared values");
+       Perl_sharedsv_thrcnt_inc(aTHX_ shared);
+
+
+MODULE = threads::shared               PACKAGE = threads::shared::sv           
+
+SV*
+new(class, value)
+       SV* class
+       SV* value
+       CODE:
+       shared_sv* shared = Perl_sharedsv_new(aTHX);
+        MAGIC* shared_magic;
+       SV* obj = newSViv((IV)shared);
+       SHAREDSvEDIT(shared);
+       SHAREDSvGET(shared) = newSVsv(value);
+        SHAREDSvRELEASE(shared);
+       sv_magic(value, 0, PERL_MAGIC_ext, "threads::shared", 16);
+        shared_magic = mg_find(value, PERL_MAGIC_ext);
+        shared_magic->mg_virtual = &svtable;
+        shared_magic->mg_obj = newSViv((IV)shared);
+        shared_magic->mg_flags |= MGf_REFCOUNTED;
+        SvMAGICAL_on(value);
+        RETVAL = obj;
+        OUTPUT:                
+        RETVAL
+
+
diff --git a/ext/threads/shared/t/sv_refs.t b/ext/threads/shared/t/sv_refs.t
new file mode 100644 (file)
index 0000000..36977e7
--- /dev/null
@@ -0,0 +1,56 @@
+BEGIN {
+#    chdir 't' if -d 't';
+#    push @INC ,'../lib';
+    require Config; import Config;
+    unless ($Config{'useithreads'}) {
+        print "1..0 # Skip: no useithreads\n";
+        exit 0;
+    }
+}
+
+
+sub ok {
+    my ($id, $ok, $name) = @_;
+
+    # You have to do it this way or VMS will get confused.
+    print $ok ? "ok $id - $name\n" : "not ok $id - $name\n";
+
+    printf "# Failed test at line %d\n", (caller)[2] unless $ok;
+
+    return $ok;
+}
+
+use Devel::Peek;
+use ExtUtils::testlib;
+use strict;
+BEGIN { print "1..9\n" };
+use threads;
+use threads::shared;
+ok(1,1,"loaded");
+
+my $foo;
+my $bar = "foo";
+share($foo);
+eval {
+$foo = \$bar;
+};
+ok(2,my $temp1 = $@ =~/You cannot assign a non shared reference to a shared scalar/, "Check that the warning message is correct");
+share($bar);
+$foo = \$bar;
+ok(3, $temp1 = $foo =~/SCALAR/, "Check that is a ref");
+ok(4, $$foo eq "foo", "Check that it points to the correct value");
+$bar = "yeah";
+ok(5, $$foo eq "yeah", "Check that assignment works");
+$$foo = "yeah2";
+ok(6, $$foo eq "yeah2", "Check that deref assignment works");
+threads->create(sub {$bar = "yeah3"})->join();
+ok(7, $$foo eq "yeah3", "Check that other thread assignemtn works");
+threads->create(sub {$foo = "artur"})->join();
+ok(8, $foo eq "artur", "Check that uncopupling the ref works");
+my $baz;
+share($baz);
+$baz = "original";
+$bar = \$baz;
+$foo = \$bar;
+ok(9,$$$foo eq 'original', "Check reference chain");
+
diff --git a/ext/threads/shared/t/sv_simple.t b/ext/threads/shared/t/sv_simple.t
new file mode 100644 (file)
index 0000000..2a0d297
--- /dev/null
@@ -0,0 +1,59 @@
+
+
+
+
+BEGIN {
+#    chdir 't' if -d 't';
+#    push @INC ,'../lib';
+    require Config; import Config;
+    unless ($Config{'useithreads'}) {
+        print "1..0 # Skip: no useithreads\n";
+        exit 0;
+    }
+}
+
+
+sub ok {
+    my ($id, $ok, $name) = @_;
+
+    # You have to do it this way or VMS will get confused.
+    print $ok ? "ok $id - $name\n" : "not ok $id - $name\n";
+
+    printf "# Failed test at line %d\n", (caller)[2] unless $ok;
+
+    return $ok;
+}
+
+
+use ExtUtils::testlib;
+use strict;
+BEGIN { print "1..10\n" };
+use threads;
+use threads::shared;
+ok(1,1,"loaded");
+my $test = "bar";
+share($test);
+ok(2,$test eq "bar","Test magic share fetch");
+$test = "foo";
+ok(3,$test eq "foo","Test magic share assign");
+threads->create(
+               sub {
+                   ok(4, $test eq "foo","Test mage share fetch after thread");
+                   $test = "baz";
+                    ok(5,threads::shared::_thrcnt($test) == 2, "Check that threadcount is correct");
+                   })->join();
+ok(6,$test eq "baz","Test that value has changed in another thread");
+ok(7,threads::shared::_thrcnt($test) == 1,"Check thrcnt is down properly");
+$test = "barbar";
+ok(8, length($test) == 6, "Check length code");
+threads->create(sub { $test = "barbarbar" })->join;
+ok(9, length($test) == 9, "Check length code after different thread modified it");
+threads->create(sub { undef($test)})->join();
+ok(10, !defined($test), "Check undef value");
+
+
+
+
+
+
+
index c5a9246..ede1f3d 100644 (file)
@@ -470,6 +470,7 @@ Perl_swash_init
 Perl_swash_fetch
 Perl_taint_env
 Perl_taint_proper
+Perl_to_utf8_case
 Perl_to_utf8_lower
 Perl_to_utf8_upper
 Perl_to_utf8_title
index 4bbaba9..fe6628d 100755 (executable)
@@ -167,12 +167,10 @@ usage("") unless @ARGV;
 # See vms/descrip_mms.template -> descrip.mms for invokation.
 if ( $^O eq 'VMS' ) { @ARGV = split(/\s+/,$ARGV[0]); }
 
-use vars qw($opt_htmldir $opt_htmlroot $opt_podroot $opt_splitpod
-            $opt_verbose $opt_help $opt_podpath $opt_splithead $opt_splititem
-            $opt_libpods $opt_recurse);
+use vars qw( %Options );
 
 # parse the command-line
-my $result = GetOptions( qw(
+my $result = GetOptions( \%Options, qw(
        help
        podpath=s
        podroot=s
@@ -249,7 +247,7 @@ foreach my $dir (@splithead) {
        $_ =~ s{HREF="#(.*)">}{
            my $url = "$file/$1.html" ;
             $url = Pod::Html::relativize_url( $url, "$file.html" )
-                if ( ! defined $opt_htmlroot || $opt_htmlroot eq '' ) ;
+                if ( ! defined $Options{htmlroot} || $Options{htmlroot} eq '' );
             "HREF=\"$url\">" ;
         }eg;
        push @data, $_;
@@ -273,24 +271,24 @@ sub usage {
 
 
 sub parse_command_line {
-    usage() if defined $opt_help;
-    $opt_help = "";                # make -w shut up
+    usage() if defined $Options{help};
+    $Options{help} = "";                   # make -w shut up
 
     # list of directories
-    @podpath   = split(":", $opt_podpath) if defined $opt_podpath;
+    @podpath   = split(":", $Options{podpath}) if defined $Options{podpath};
 
     # lists of files
-    @splithead = split(",", $opt_splithead) if defined $opt_splithead;
-    @splititem = split(",", $opt_splititem) if defined $opt_splititem;
-    @libpods   = split(",", $opt_libpods) if defined $opt_libpods;
+    @splithead = split(",", $Options{splithead}) if defined $Options{splithead};
+    @splititem = split(",", $Options{splititem}) if defined $Options{splititem};
+    @libpods   = split(",", $Options{libpods}) if defined $Options{libpods};
 
-    $htmldir  = $opt_htmldir       if defined $opt_htmldir;
-    $htmlroot = $opt_htmlroot      if defined $opt_htmlroot;
-    $podroot  = $opt_podroot       if defined $opt_podroot;
-    $splitpod = $opt_splitpod      if defined $opt_splitpod;
+    $htmldir  = $Options{htmldir}          if defined $Options{htmldir};
+    $htmlroot = $Options{htmlroot}         if defined $Options{htmlroot};
+    $podroot  = $Options{podroot}          if defined $Options{podroot};
+    $splitpod = $Options{splitpod}         if defined $Options{splitpod};
 
-    $recurse  = $opt_recurse       if defined $opt_recurse;
-    $verbose  = $opt_verbose       if defined $opt_verbose;
+    $recurse  = $Options{recurse}          if defined $Options{recurse};
+    $verbose  = $Options{verbose}          if defined $Options{verbose};
 }
 
 
@@ -337,7 +335,7 @@ sub create_index {
           ($lcp1,$lcp2) = ($name =~ m,/H1>\s<P>\s(\S+)\s[\s-]*(.*?)\s*$,sm);
        }
        my $url= "$dir/$file" ;
-       if ( ! defined $opt_htmlroot || $opt_htmlroot eq '' ) {
+       if ( ! defined $Options{htmlroot} || $Options{htmlroot} eq '' ) {
            $url = Pod::Html::relativize_url( "$dir/$file", $html ) ;
        }
 
index 0fd4f8d..ce89c8e 100644 (file)
@@ -1,6 +1,112 @@
 # !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!! 
 # This file is built by mktables from e.g. Unicode.txt.
 # Any changes made here will be lost!
+
+%utf8::ToSpecLower = (
+'223' => "\x{00DF}",
+'329' => "\x{0149}",
+'496' => "\x{01F0}",
+'912' => "\x{0390}",
+'944' => "\x{03B0}",
+'1415' => "\x{0587}",
+'7830' => "\x{1E96}",
+'7831' => "\x{1E97}",
+'7832' => "\x{1E98}",
+'7833' => "\x{1E99}",
+'7834' => "\x{1E9A}",
+'8016' => "\x{1F50}",
+'8018' => "\x{1F52}",
+'8020' => "\x{1F54}",
+'8022' => "\x{1F56}",
+'8064' => "\x{1F80}",
+'8065' => "\x{1F81}",
+'8066' => "\x{1F82}",
+'8067' => "\x{1F83}",
+'8068' => "\x{1F84}",
+'8069' => "\x{1F85}",
+'8070' => "\x{1F86}",
+'8071' => "\x{1F87}",
+'8072' => "\x{1F80}",
+'8073' => "\x{1F81}",
+'8074' => "\x{1F82}",
+'8075' => "\x{1F83}",
+'8076' => "\x{1F84}",
+'8077' => "\x{1F85}",
+'8078' => "\x{1F86}",
+'8079' => "\x{1F87}",
+'8080' => "\x{1F90}",
+'8081' => "\x{1F91}",
+'8082' => "\x{1F92}",
+'8083' => "\x{1F93}",
+'8084' => "\x{1F94}",
+'8085' => "\x{1F95}",
+'8086' => "\x{1F96}",
+'8087' => "\x{1F97}",
+'8088' => "\x{1F90}",
+'8089' => "\x{1F91}",
+'8090' => "\x{1F92}",
+'8091' => "\x{1F93}",
+'8092' => "\x{1F94}",
+'8093' => "\x{1F95}",
+'8094' => "\x{1F96}",
+'8095' => "\x{1F97}",
+'8096' => "\x{1FA0}",
+'8097' => "\x{1FA1}",
+'8098' => "\x{1FA2}",
+'8099' => "\x{1FA3}",
+'8100' => "\x{1FA4}",
+'8101' => "\x{1FA5}",
+'8102' => "\x{1FA6}",
+'8103' => "\x{1FA7}",
+'8104' => "\x{1FA0}",
+'8105' => "\x{1FA1}",
+'8106' => "\x{1FA2}",
+'8107' => "\x{1FA3}",
+'8108' => "\x{1FA4}",
+'8109' => "\x{1FA5}",
+'8110' => "\x{1FA6}",
+'8111' => "\x{1FA7}",
+'8114' => "\x{1FB2}",
+'8115' => "\x{1FB3}",
+'8116' => "\x{1FB4}",
+'8118' => "\x{1FB6}",
+'8119' => "\x{1FB7}",
+'8124' => "\x{1FB3}",
+'8130' => "\x{1FC2}",
+'8131' => "\x{1FC3}",
+'8132' => "\x{1FC4}",
+'8134' => "\x{1FC6}",
+'8135' => "\x{1FC7}",
+'8140' => "\x{1FC3}",
+'8146' => "\x{1FD2}",
+'8147' => "\x{1FD3}",
+'8150' => "\x{1FD6}",
+'8151' => "\x{1FD7}",
+'8162' => "\x{1FE2}",
+'8163' => "\x{1FE3}",
+'8164' => "\x{1FE4}",
+'8166' => "\x{1FE6}",
+'8167' => "\x{1FE7}",
+'8178' => "\x{1FF2}",
+'8179' => "\x{1FF3}",
+'8180' => "\x{1FF4}",
+'8182' => "\x{1FF6}",
+'8183' => "\x{1FF7}",
+'8188' => "\x{1FF3}",
+'64256' => "\x{FB00}",
+'64257' => "\x{FB01}",
+'64258' => "\x{FB02}",
+'64259' => "\x{FB03}",
+'64260' => "\x{FB04}",
+'64261' => "\x{FB05}",
+'64262' => "\x{FB06}",
+'64275' => "\x{FB13}",
+'64276' => "\x{FB14}",
+'64277' => "\x{FB15}",
+'64278' => "\x{FB16}",
+'64279' => "\x{FB17}",
+);
+
 return <<'END';
 0041           0061
 0042           0062
diff --git a/lib/unicore/To/SpecLower.pl b/lib/unicore/To/SpecLower.pl
deleted file mode 100644 (file)
index 18c073b..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-# !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!! 
-# This file is built by mktables from e.g. Unicode.txt.
-# Any changes made here will be lost!
-return <<'END';
-00DF           00DF
-0149           0149
-01F0           01F0
-0390           0390
-03B0           03B0
-0587           0587
-1E96           1E96
-1E97           1E97
-1E98           1E98
-1E99           1E99
-1E9A           1E9A
-1F50           1F50
-1F52           1F52
-1F54           1F54
-1F56           1F56
-1F80           1F80
-1F81           1F81
-1F82           1F82
-1F83           1F83
-1F84           1F84
-1F85           1F85
-1F86           1F86
-1F87           1F87
-1F88           1F80
-1F89           1F81
-1F8A           1F82
-1F8B           1F83
-1F8C           1F84
-1F8D           1F85
-1F8E           1F86
-1F8F           1F87
-1F90           1F90
-1F91           1F91
-1F92           1F92
-1F93           1F93
-1F94           1F94
-1F95           1F95
-1F96           1F96
-1F97           1F97
-1F98           1F90
-1F99           1F91
-1F9A           1F92
-1F9B           1F93
-1F9C           1F94
-1F9D           1F95
-1F9E           1F96
-1F9F           1F97
-1FA0           1FA0
-1FA1           1FA1
-1FA2           1FA2
-1FA3           1FA3
-1FA4           1FA4
-1FA5           1FA5
-1FA6           1FA6
-1FA7           1FA7
-1FA8           1FA0
-1FA9           1FA1
-1FAA           1FA2
-1FAB           1FA3
-1FAC           1FA4
-1FAD           1FA5
-1FAE           1FA6
-1FAF           1FA7
-1FB2           1FB2
-1FB3           1FB3
-1FB4           1FB4
-1FB6           1FB6
-1FB7           1FB7
-1FBC           1FB3
-1FC2           1FC2
-1FC3           1FC3
-1FC4           1FC4
-1FC6           1FC6
-1FC7           1FC7
-1FCC           1FC3
-1FD2           1FD2
-1FD3           1FD3
-1FD6           1FD6
-1FD7           1FD7
-1FE2           1FE2
-1FE3           1FE3
-1FE4           1FE4
-1FE6           1FE6
-1FE7           1FE7
-1FF2           1FF2
-1FF3           1FF3
-1FF4           1FF4
-1FF6           1FF6
-1FF7           1FF7
-1FFC           1FF3
-FB00           FB00
-FB01           FB01
-FB02           FB02
-FB03           FB03
-FB04           FB04
-FB05           FB05
-FB06           FB06
-FB13           FB13
-FB14           FB14
-FB15           FB15
-FB16           FB16
-FB17           FB17
-END
diff --git a/lib/unicore/To/SpecTitle.pl b/lib/unicore/To/SpecTitle.pl
deleted file mode 100644 (file)
index c3e1911..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-# !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!! 
-# This file is built by mktables from e.g. Unicode.txt.
-# Any changes made here will be lost!
-return <<'END';
-00DF           0053 0073
-0149           02BC 004E
-01F0           004A 030C
-0390           0399 0308 0301
-03B0           03A5 0308 0301
-0587           0535 0582
-1E96           0048 0331
-1E97           0054 0308
-1E98           0057 030A
-1E99           0059 030A
-1E9A           0041 02BE
-1F50           03A5 0313
-1F52           03A5 0313 0300
-1F54           03A5 0313 0301
-1F56           03A5 0313 0342
-1F80           1F88
-1F81           1F89
-1F82           1F8A
-1F83           1F8B
-1F84           1F8C
-1F85           1F8D
-1F86           1F8E
-1F87           1F8F
-1F88           1F88
-1F89           1F89
-1F8A           1F8A
-1F8B           1F8B
-1F8C           1F8C
-1F8D           1F8D
-1F8E           1F8E
-1F8F           1F8F
-1F90           1F98
-1F91           1F99
-1F92           1F9A
-1F93           1F9B
-1F94           1F9C
-1F95           1F9D
-1F96           1F9E
-1F97           1F9F
-1F98           1F98
-1F99           1F99
-1F9A           1F9A
-1F9B           1F9B
-1F9C           1F9C
-1F9D           1F9D
-1F9E           1F9E
-1F9F           1F9F
-1FA0           1FA8
-1FA1           1FA9
-1FA2           1FAA
-1FA3           1FAB
-1FA4           1FAC
-1FA5           1FAD
-1FA6           1FAE
-1FA7           1FAF
-1FA8           1FA8
-1FA9           1FA9
-1FAA           1FAA
-1FAB           1FAB
-1FAC           1FAC
-1FAD           1FAD
-1FAE           1FAE
-1FAF           1FAF
-1FB2           1FBA 0345
-1FB3           1FBC
-1FB4           0386 0345
-1FB6           0391 0342
-1FB7           0391 0342 0345
-1FBC           1FBC
-1FC2           1FCA 0345
-1FC3           1FCC
-1FC4           0389 0345
-1FC6           0397 0342
-1FC7           0397 0342 0345
-1FCC           1FCC
-1FD2           0399 0308 0300
-1FD3           0399 0308 0301
-1FD6           0399 0342
-1FD7           0399 0308 0342
-1FE2           03A5 0308 0300
-1FE3           03A5 0308 0301
-1FE4           03A1 0313
-1FE6           03A5 0342
-1FE7           03A5 0308 0342
-1FF2           1FFA 0345
-1FF3           1FFC
-1FF4           038F 0345
-1FF6           03A9 0342
-1FF7           03A9 0342 0345
-1FFC           1FFC
-FB00           0046 0066
-FB01           0046 0069
-FB02           0046 006C
-FB03           0046 0066 0069
-FB04           0046 0066 006C
-FB05   FB06    0053 0074
-FB13           0544 0576
-FB14           0544 0565
-FB15           0544 056B
-FB16           054E 0576
-FB17           0544 056D
-END
diff --git a/lib/unicore/To/SpecUpper.pl b/lib/unicore/To/SpecUpper.pl
deleted file mode 100644 (file)
index e5af4b1..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-# !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!! 
-# This file is built by mktables from e.g. Unicode.txt.
-# Any changes made here will be lost!
-return <<'END';
-00DF           0053 0053
-0149           02BC 004E
-01F0           004A 030C
-0390           0399 0308 0301
-03B0           03A5 0308 0301
-0587           0535 0552
-1E96           0048 0331
-1E97           0054 0308
-1E98           0057 030A
-1E99           0059 030A
-1E9A           0041 02BE
-1F50           03A5 0313
-1F52           03A5 0313 0300
-1F54           03A5 0313 0301
-1F56           03A5 0313 0342
-1F80           1F08 0399
-1F81           1F09 0399
-1F82           1F0A 0399
-1F83           1F0B 0399
-1F84           1F0C 0399
-1F85           1F0D 0399
-1F86           1F0E 0399
-1F87           1F0F 0399
-1F88           1F08 0399
-1F89           1F09 0399
-1F8A           1F0A 0399
-1F8B           1F0B 0399
-1F8C           1F0C 0399
-1F8D           1F0D 0399
-1F8E           1F0E 0399
-1F8F           1F0F 0399
-1F90           1F28 0399
-1F91           1F29 0399
-1F92           1F2A 0399
-1F93           1F2B 0399
-1F94           1F2C 0399
-1F95           1F2D 0399
-1F96           1F2E 0399
-1F97           1F2F 0399
-1F98           1F28 0399
-1F99           1F29 0399
-1F9A           1F2A 0399
-1F9B           1F2B 0399
-1F9C           1F2C 0399
-1F9D           1F2D 0399
-1F9E           1F2E 0399
-1F9F           1F2F 0399
-1FA0           1F68 0399
-1FA1           1F69 0399
-1FA2           1F6A 0399
-1FA3           1F6B 0399
-1FA4           1F6C 0399
-1FA5           1F6D 0399
-1FA6           1F6E 0399
-1FA7           1F6F 0399
-1FA8           1F68 0399
-1FA9           1F69 0399
-1FAA           1F6A 0399
-1FAB           1F6B 0399
-1FAC           1F6C 0399
-1FAD           1F6D 0399
-1FAE           1F6E 0399
-1FAF           1F6F 0399
-1FB2           1FBA 0399
-1FB3           0391 0399
-1FB4           0386 0399
-1FB6           0391 0342
-1FB7           0391 0342 0399
-1FBC           0391 0399
-1FC2           1FCA 0399
-1FC3           0397 0399
-1FC4           0389 0399
-1FC6           0397 0342
-1FC7           0397 0342 0399
-1FCC           0397 0399
-1FD2           0399 0308 0300
-1FD3           0399 0308 0301
-1FD6           0399 0342
-1FD7           0399 0308 0342
-1FE2           03A5 0308 0300
-1FE3           03A5 0308 0301
-1FE4           03A1 0313
-1FE6           03A5 0342
-1FE7           03A5 0308 0342
-1FF2           1FFA 0399
-1FF3           03A9 0399
-1FF4           038F 0399
-1FF6           03A9 0342
-1FF7           03A9 0342 0399
-1FFC           03A9 0399
-FB00           0046 0046
-FB01           0046 0049
-FB02           0046 004C
-FB03           0046 0046 0049
-FB04           0046 0046 004C
-FB05   FB06    0053 0054
-FB13           0544 0546
-FB14           0544 0535
-FB15           0544 053B
-FB16           054E 0546
-FB17           0544 053D
-END
index 2fca353..3da9ca9 100644 (file)
@@ -1,6 +1,112 @@
 # !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!! 
 # This file is built by mktables from e.g. Unicode.txt.
 # Any changes made here will be lost!
+
+%utf8::ToSpecTitle = (
+'223' => "\x{0053}\x{0073}",
+'329' => "\x{02BC}\x{004E}",
+'496' => "\x{004A}\x{030C}",
+'912' => "\x{0399}\x{0308}\x{0301}",
+'944' => "\x{03A5}\x{0308}\x{0301}",
+'1415' => "\x{0535}\x{0582}",
+'7830' => "\x{0048}\x{0331}",
+'7831' => "\x{0054}\x{0308}",
+'7832' => "\x{0057}\x{030A}",
+'7833' => "\x{0059}\x{030A}",
+'7834' => "\x{0041}\x{02BE}",
+'8016' => "\x{03A5}\x{0313}",
+'8018' => "\x{03A5}\x{0313}\x{0300}",
+'8020' => "\x{03A5}\x{0313}\x{0301}",
+'8022' => "\x{03A5}\x{0313}\x{0342}",
+'8064' => "\x{1F88}",
+'8065' => "\x{1F89}",
+'8066' => "\x{1F8A}",
+'8067' => "\x{1F8B}",
+'8068' => "\x{1F8C}",
+'8069' => "\x{1F8D}",
+'8070' => "\x{1F8E}",
+'8071' => "\x{1F8F}",
+'8072' => "\x{1F88}",
+'8073' => "\x{1F89}",
+'8074' => "\x{1F8A}",
+'8075' => "\x{1F8B}",
+'8076' => "\x{1F8C}",
+'8077' => "\x{1F8D}",
+'8078' => "\x{1F8E}",
+'8079' => "\x{1F8F}",
+'8080' => "\x{1F98}",
+'8081' => "\x{1F99}",
+'8082' => "\x{1F9A}",
+'8083' => "\x{1F9B}",
+'8084' => "\x{1F9C}",
+'8085' => "\x{1F9D}",
+'8086' => "\x{1F9E}",
+'8087' => "\x{1F9F}",
+'8088' => "\x{1F98}",
+'8089' => "\x{1F99}",
+'8090' => "\x{1F9A}",
+'8091' => "\x{1F9B}",
+'8092' => "\x{1F9C}",
+'8093' => "\x{1F9D}",
+'8094' => "\x{1F9E}",
+'8095' => "\x{1F9F}",
+'8096' => "\x{1FA8}",
+'8097' => "\x{1FA9}",
+'8098' => "\x{1FAA}",
+'8099' => "\x{1FAB}",
+'8100' => "\x{1FAC}",
+'8101' => "\x{1FAD}",
+'8102' => "\x{1FAE}",
+'8103' => "\x{1FAF}",
+'8104' => "\x{1FA8}",
+'8105' => "\x{1FA9}",
+'8106' => "\x{1FAA}",
+'8107' => "\x{1FAB}",
+'8108' => "\x{1FAC}",
+'8109' => "\x{1FAD}",
+'8110' => "\x{1FAE}",
+'8111' => "\x{1FAF}",
+'8114' => "\x{1FBA}\x{0345}",
+'8115' => "\x{1FBC}",
+'8116' => "\x{0386}\x{0345}",
+'8118' => "\x{0391}\x{0342}",
+'8119' => "\x{0391}\x{0342}\x{0345}",
+'8124' => "\x{1FBC}",
+'8130' => "\x{1FCA}\x{0345}",
+'8131' => "\x{1FCC}",
+'8132' => "\x{0389}\x{0345}",
+'8134' => "\x{0397}\x{0342}",
+'8135' => "\x{0397}\x{0342}\x{0345}",
+'8140' => "\x{1FCC}",
+'8146' => "\x{0399}\x{0308}\x{0300}",
+'8147' => "\x{0399}\x{0308}\x{0301}",
+'8150' => "\x{0399}\x{0342}",
+'8151' => "\x{0399}\x{0308}\x{0342}",
+'8162' => "\x{03A5}\x{0308}\x{0300}",
+'8163' => "\x{03A5}\x{0308}\x{0301}",
+'8164' => "\x{03A1}\x{0313}",
+'8166' => "\x{03A5}\x{0342}",
+'8167' => "\x{03A5}\x{0308}\x{0342}",
+'8178' => "\x{1FFA}\x{0345}",
+'8179' => "\x{1FFC}",
+'8180' => "\x{038F}\x{0345}",
+'8182' => "\x{03A9}\x{0342}",
+'8183' => "\x{03A9}\x{0342}\x{0345}",
+'8188' => "\x{1FFC}",
+'64256' => "\x{0046}\x{0066}",
+'64257' => "\x{0046}\x{0069}",
+'64258' => "\x{0046}\x{006C}",
+'64259' => "\x{0046}\x{0066}\x{0069}",
+'64260' => "\x{0046}\x{0066}\x{006C}",
+'64261' => "\x{0053}\x{0074}",
+'64262' => "\x{0053}\x{0074}",
+'64275' => "\x{0544}\x{0576}",
+'64276' => "\x{0544}\x{0565}",
+'64277' => "\x{0544}\x{056B}",
+'64278' => "\x{054E}\x{0576}",
+'64279' => "\x{0544}\x{056D}",
+);
+
 return <<'END';
 0061           0041
 0062           0042
index bfdd4ea..a9c7a9f 100644 (file)
@@ -1,6 +1,112 @@
 # !!!!!!!   DO NOT EDIT THIS FILE   !!!!!!! 
 # This file is built by mktables from e.g. Unicode.txt.
 # Any changes made here will be lost!
+
+%utf8::ToSpecUpper = (
+'223' => "\x{0053}\x{0053}",
+'329' => "\x{02BC}\x{004E}",
+'496' => "\x{004A}\x{030C}",
+'912' => "\x{0399}\x{0308}\x{0301}",
+'944' => "\x{03A5}\x{0308}\x{0301}",
+'1415' => "\x{0535}\x{0552}",
+'7830' => "\x{0048}\x{0331}",
+'7831' => "\x{0054}\x{0308}",
+'7832' => "\x{0057}\x{030A}",
+'7833' => "\x{0059}\x{030A}",
+'7834' => "\x{0041}\x{02BE}",
+'8016' => "\x{03A5}\x{0313}",
+'8018' => "\x{03A5}\x{0313}\x{0300}",
+'8020' => "\x{03A5}\x{0313}\x{0301}",
+'8022' => "\x{03A5}\x{0313}\x{0342}",
+'8064' => "\x{1F08}\x{0399}",
+'8065' => "\x{1F09}\x{0399}",
+'8066' => "\x{1F0A}\x{0399}",
+'8067' => "\x{1F0B}\x{0399}",
+'8068' => "\x{1F0C}\x{0399}",
+'8069' => "\x{1F0D}\x{0399}",
+'8070' => "\x{1F0E}\x{0399}",
+'8071' => "\x{1F0F}\x{0399}",
+'8072' => "\x{1F08}\x{0399}",
+'8073' => "\x{1F09}\x{0399}",
+'8074' => "\x{1F0A}\x{0399}",
+'8075' => "\x{1F0B}\x{0399}",
+'8076' => "\x{1F0C}\x{0399}",
+'8077' => "\x{1F0D}\x{0399}",
+'8078' => "\x{1F0E}\x{0399}",
+'8079' => "\x{1F0F}\x{0399}",
+'8080' => "\x{1F28}\x{0399}",
+'8081' => "\x{1F29}\x{0399}",
+'8082' => "\x{1F2A}\x{0399}",
+'8083' => "\x{1F2B}\x{0399}",
+'8084' => "\x{1F2C}\x{0399}",
+'8085' => "\x{1F2D}\x{0399}",
+'8086' => "\x{1F2E}\x{0399}",
+'8087' => "\x{1F2F}\x{0399}",
+'8088' => "\x{1F28}\x{0399}",
+'8089' => "\x{1F29}\x{0399}",
+'8090' => "\x{1F2A}\x{0399}",
+'8091' => "\x{1F2B}\x{0399}",
+'8092' => "\x{1F2C}\x{0399}",
+'8093' => "\x{1F2D}\x{0399}",
+'8094' => "\x{1F2E}\x{0399}",
+'8095' => "\x{1F2F}\x{0399}",
+'8096' => "\x{1F68}\x{0399}",
+'8097' => "\x{1F69}\x{0399}",
+'8098' => "\x{1F6A}\x{0399}",
+'8099' => "\x{1F6B}\x{0399}",
+'8100' => "\x{1F6C}\x{0399}",
+'8101' => "\x{1F6D}\x{0399}",
+'8102' => "\x{1F6E}\x{0399}",
+'8103' => "\x{1F6F}\x{0399}",
+'8104' => "\x{1F68}\x{0399}",
+'8105' => "\x{1F69}\x{0399}",
+'8106' => "\x{1F6A}\x{0399}",
+'8107' => "\x{1F6B}\x{0399}",
+'8108' => "\x{1F6C}\x{0399}",
+'8109' => "\x{1F6D}\x{0399}",
+'8110' => "\x{1F6E}\x{0399}",
+'8111' => "\x{1F6F}\x{0399}",
+'8114' => "\x{1FBA}\x{0399}",
+'8115' => "\x{0391}\x{0399}",
+'8116' => "\x{0386}\x{0399}",
+'8118' => "\x{0391}\x{0342}",
+'8119' => "\x{0391}\x{0342}\x{0399}",
+'8124' => "\x{0391}\x{0399}",
+'8130' => "\x{1FCA}\x{0399}",
+'8131' => "\x{0397}\x{0399}",
+'8132' => "\x{0389}\x{0399}",
+'8134' => "\x{0397}\x{0342}",
+'8135' => "\x{0397}\x{0342}\x{0399}",
+'8140' => "\x{0397}\x{0399}",
+'8146' => "\x{0399}\x{0308}\x{0300}",
+'8147' => "\x{0399}\x{0308}\x{0301}",
+'8150' => "\x{0399}\x{0342}",
+'8151' => "\x{0399}\x{0308}\x{0342}",
+'8162' => "\x{03A5}\x{0308}\x{0300}",
+'8163' => "\x{03A5}\x{0308}\x{0301}",
+'8164' => "\x{03A1}\x{0313}",
+'8166' => "\x{03A5}\x{0342}",
+'8167' => "\x{03A5}\x{0308}\x{0342}",
+'8178' => "\x{1FFA}\x{0399}",
+'8179' => "\x{03A9}\x{0399}",
+'8180' => "\x{038F}\x{0399}",
+'8182' => "\x{03A9}\x{0342}",
+'8183' => "\x{03A9}\x{0342}\x{0399}",
+'8188' => "\x{03A9}\x{0399}",
+'64256' => "\x{0046}\x{0046}",
+'64257' => "\x{0046}\x{0049}",
+'64258' => "\x{0046}\x{004C}",
+'64259' => "\x{0046}\x{0046}\x{0049}",
+'64260' => "\x{0046}\x{0046}\x{004C}",
+'64261' => "\x{0053}\x{0054}",
+'64262' => "\x{0053}\x{0054}",
+'64275' => "\x{0544}\x{0546}",
+'64276' => "\x{0544}\x{0535}",
+'64277' => "\x{0544}\x{053B}",
+'64278' => "\x{054E}\x{0546}",
+'64279' => "\x{0544}\x{053D}",
+);
+
 return <<'END';
 0061           0041
 0062           0042
index 3328f69..7d8912d 100644 (file)
@@ -745,16 +745,32 @@ if (open(my $SpecCase, "SpecCase.txt")) {
 }
 
 # Now write out the special cases properties in their code point order.
-# The To/Spec{Lower,Title,Upper}.pl are unused for now since the swash
-# routines do not do returning multiple characters.
+# Prepend them to the To/{Upper,Lower,Title}.pl.
 
 for my $case (qw(Lower Title Upper)) {
-    my @case;
-    for my $prop (sort { $a->[0] <=> $b->[0] } @{$Case{$case}}) {
-        my ($ix, $code, $to) = @$prop;
-        append(\@case, $code, $to);
+    my $NormalCase = do "To/$case.pl";
+    if (open(my $Case, ">To/$case.pl")) {
+       header($Case);
+       print $Case <<EOT;
+
+%utf8::ToSpec$case = (
+EOT
+        for my $prop (sort { $a->[0] <=> $b->[0] } @{$Case{$case}}) {
+           my ($ix, $code, $to) = @$prop;
+           my $tostr =
+               join "", map { sprintf "\\x{%s}", $_ } split ' ', $to;
+           print $Case qq['$ix' => "$tostr",\n];
+       }
+       print $Case <<EOT;
+);
+
+EOT
+       begin($Case);
+       print $Case $NormalCase;
+       end($Case);
+    } else {
+       die "$0: To/$case.txt: $!\n";
     }
-    flush(\@case, "To/Spec$case.pl");
 }
 
 # That's all, folks!
diff --git a/perl.h b/perl.h
index 1e40d9b..2959df4 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -425,7 +425,7 @@ int usleep(unsigned int);
 #  define MYSWAP
 #endif
 
-/* Cannot include embed.h here on Win32 as win32.h has not
+/* Cannot include embed.h here on Win32 as win32.h has not 
    yet been included and defines some config variables e.g. HAVE_INTERP_INTERN
  */
 #if !defined(PERL_FOR_X2P) && !(defined(WIN32)||defined(VMS))
index 5d78962..bb6d0d3 100644 (file)
@@ -109,6 +109,7 @@ if (-d "pod") {
     perldsc
     perlrequick
     perlpod
+    perlpodspec
     perlstyle
     perltrap
 
index 9d585b5..8495648 100644 (file)
@@ -63,6 +63,7 @@ For ease of access, the Perl manual has been split up into several sections.
     perlfunc           Perl built-in functions
       perlopentut      Perl open() tutorial
     perlpod            Perl plain old documentation
+    perlpodspec         Perl plain old documentation format specification
     perlrun            Perl execution and options
     perldiag           Perl diagnostic messages
     perllexwarn                Perl warnings and their control
index 75defb8..6a23c14 100644 (file)
@@ -2606,21 +2606,21 @@ Like C<SvPV_nolen>, but converts sv to uft8 first if necessary.
 =for hackers
 Found in file sv.h
 
-=item SvPVX
+=item SvPVx
 
-Returns a pointer to the physical string in the SV.  The SV must contain a
-string.
+A version of C<SvPV> which guarantees to evaluate sv only once.
 
-       char*   SvPVX(SV* sv)
+       char*   SvPVx(SV* sv, STRLEN len)
 
 =for hackers
 Found in file sv.h
 
-=item SvPVx
+=item SvPVX
 
-A version of C<SvPV> which guarantees to evaluate sv only once.
+Returns a pointer to the physical string in the SV.  The SV must contain a
+string.
 
-       char*   SvPVx(SV* sv, STRLEN len)
+       char*   SvPVX(SV* sv)
 
 =for hackers
 Found in file sv.h
@@ -2827,19 +2827,19 @@ false, defined or undefined.  Does not handle 'get' magic.
 =for hackers
 Found in file sv.h
 
-=item svtype
+=item SvTYPE
 
-An enum of flags for Perl types.  These are found in the file B<sv.h>
-in the C<svtype> enum.  Test these flags with the C<SvTYPE> macro.
+Returns the type of the SV.  See C<svtype>.
+
+       svtype  SvTYPE(SV* sv)
 
 =for hackers
 Found in file sv.h
 
-=item SvTYPE
-
-Returns the type of the SV.  See C<svtype>.
+=item svtype
 
-       svtype  SvTYPE(SV* sv)
+An enum of flags for Perl types.  These are found in the file B<sv.h>
+in the C<svtype> enum.  Test these flags with the C<SvTYPE> macro.
 
 =for hackers
 Found in file sv.h
index 6d94459..ca48470 100644 (file)
@@ -2330,7 +2330,7 @@ C<redo> work.
 Returns an lowercased version of EXPR.  This is the internal function
 implementing the C<\L> escape in double-quoted strings.  Respects
 current LC_CTYPE locale if C<use locale> in force.  See L<perllocale>
-and L<perlunicode>.
+and L<perlunicode> for more details about locale and Unicode support.
 
 If EXPR is omitted, uses C<$_>.
 
@@ -2341,7 +2341,8 @@ If EXPR is omitted, uses C<$_>.
 Returns the value of EXPR with the first character lowercased.  This
 is the internal function implementing the C<\l> escape in
 double-quoted strings.  Respects current LC_CTYPE locale if C<use
-locale> in force.  See L<perllocale> and L<perlunicode>.
+locale> in force.  See L<perllocale> and L<perlunicode> for more
+details about locale and Unicode support.
 
 If EXPR is omitted, uses C<$_>.
 
@@ -5464,8 +5465,9 @@ otherwise.
 Returns an uppercased version of EXPR.  This is the internal function
 implementing the C<\U> escape in double-quoted strings.  Respects
 current LC_CTYPE locale if C<use locale> in force.  See L<perllocale>
-and L<perlunicode>.  It does not attempt to do titlecase mapping on
-initial letters.  See C<ucfirst> for that.
+and L<perlunicode> for more details about locale and Unicode support.
+It does not attempt to do titlecase mapping on initial letters.  See
+C<ucfirst> for that.
 
 If EXPR is omitted, uses C<$_>.
 
@@ -5476,7 +5478,8 @@ If EXPR is omitted, uses C<$_>.
 Returns the value of EXPR with the first character in uppercase
 (titlecase in Unicode).  This is the internal function implementing
 the C<\u> escape in double-quoted strings.  Respects current LC_CTYPE
-locale if C<use locale> in force.  See L<perllocale> and L<perlunicode>.
+locale if C<use locale> in force.  See L<perllocale> and L<perlunicode>
+for more details about locale and Unicode support.
 
 If EXPR is omitted, uses C<$_>.
 
index 765266b..91cc81a 100644 (file)
+
+=for comment
+This document is in Pod format.  To read this, use a Pod formatter,
+like "perldoc perlpod".
+
 =head1 NAME
 
-perlpod - plain old documentation
+perlpod - the Plain Old Documentation format
 
 =head1 DESCRIPTION
 
-A pod-to-whatever translator reads a pod file paragraph by paragraph,
-and translates it to the appropriate output format.  There are
-three kinds of paragraphs:
-L<verbatim|/"Verbatim Paragraph">,
-L<command|/"Command Paragraph">, and
-L<ordinary text|/"Ordinary Block of Text">.
+Pod is a simple-to-use markup language used for writing documentation
+for Perl, Perl programs, and Perl modules.
+
+Translators are available for converting Pod to various formats
+like plain text, HTML, man pages, and more.
+
+Pod markup consists of three basic kinds of paragraphs:
+L<ordinary|/"Ordinary Paragraph">,
+L<verbatim|/"Verbatim Paragraph">, and 
+L<command|/"Command Paragraph">.
+
+
+=head2 Ordinary Paragraph
+
+Most paragraphs in your documentation will be ordinary blocks
+of text, like this one.  You can simply type in your text without
+any markup whatsoever, and with just a blank line before and
+after.  When it gets formatted, it will undergo minimal formatting, 
+like being rewrapped, probably put into a proportionally spaced
+font, and maybe even justified.
+
+You can use formatting codes in ordinary paragraphs, for B<bold>,
+I<italic>, C<code-style>, L<hyperlinks|perlfaq>, and more.  Such
+codes are explained in the "L<Formatting Codes|/"Formatting Codes">"
+section, below.
+
 
 =head2 Verbatim Paragraph
 
-A verbatim paragraph, distinguished by being indented (that is,
-it starts with space or tab).  It should be reproduced exactly,
-with tabs assumed to be on 8-column boundaries.  There are no
-special formatting escapes, so you can't italicize or anything
-like that.  A \ means \, and nothing else.
+Verbatim paragraphs are usually used for presenting a codeblock or
+other text which does not require any special parsing or formatting,
+and which shouldn't be wrapped.
+
+A verbatim paragraph is distinguished by having its first character
+be a space or a tab.  (And commonly, all its lines begin with spaces
+and/or tabs.)  It should be reproduced exactly, with tabs assumed to
+be on 8-column boundaries.  There are no special formatting codes,
+so you can't italicize or anything like that.  A \ means \, and
+nothing else.
+
 
 =head2 Command Paragraph
 
-All command paragraphs start with "=", followed by an
-identifier, followed by arbitrary text that the command can
-use however it pleases.  Currently recognized commands are
+A command paragraph is used for special treatment of whole chunks
+of text, usually as headings or parts of lists.
+
+All command paragraphs (which are typically only one line long) start
+with "=", followed by an identifier, followed by arbitrary text that
+the command can use however it pleases.  Currently recognized commands
+are
 
-    =head1 heading
-    =head2 heading
-    =head3 heading
-    =head4 heading
-    =item text
-    =over N
+    =head1 Heading Text
+    =head2 Heading Text
+    =head3 Heading Text
+    =head4 Heading Text
+    =over indentlevel
+    =item stuff
     =back
     =cut
     =pod
-    =for X
-    =begin X
-    =end X
+    =begin format
+    =end format
+    =for format text...
+
+To explain them each in detail:
+
+=over
+
+=item C<=head1 I<Heading Text>>
 
-=over 4
+=item C<=head2 I<Heading Text>>
 
-=item =pod
+=item C<=head3 I<Heading Text>>
 
-=item =cut
+=item C<=head4 I<Heading Text>>
 
-The "=pod" directive does nothing beyond telling the compiler to lay
-off parsing code through the next "=cut".  It's useful for adding
-another paragraph to the doc if you're mixing up code and pod a lot.
+Head1 through head4 produce headings, head1 being the highest
+level.  The text in the rest of this paragraph is the content of the
+heading.  For example:
 
-=item =head1
+  =head2 Object Attributes
 
-=item =head2
+The text "Object Attributes" comprises the heading there.  (Note that
+head3 and head4 are recent additions, not supported in older Pod
+translators.)  The text in these heading commands can use
+formatting codes, as seen here:
 
-=item =head3
+  =head2 Possible Values for C<$/>
 
-=item =head4
+Such commands are explained in the
+"L<Formatting Codes|/"Formatting Codes">" section, below.
 
-Head1, head2, head3 and head4 produce first, second, third and fourth
-level headings, with the text in the same paragraph as the "=headn"
-directive forming the heading description.
+=item C<=over I<indentlevel>>
 
-=item =over
+=item C<=item I<stuff...>>
 
-=item =back
+=item C<=back>
 
-=item =item
+Item, over, and back require a little more explanation:  "=over" starts
+a region specifically for the generation of a list using "=item"
+commands, or for indenting (groups of) normal paragraphs.  At the end
+of your list, use "=back" to end it.  The I<indentlevel> option to
+"=over" indicates how far over to indent, generally in ems (where
+one em is the width of an "M" in the document's base font) or roughly
+comparable units; if there is no I<indentlevel> option, it defaults
+to four.  (And some formatters may just ignore whatever I<indentlevel>
+you provide.)  In the I<stuff> in C<=item I<stuff...>>, you may
+use formatting codes, as seen here:
 
-Item, over, and back require a little more explanation: "=over" starts a
-section specifically for the generation of a list using "=item" commands. At
-the end of your list, use "=back" to end it. You will probably want to give
-"4" as the number to "=over", as some formatters will use this for indentation.
-The unit of indentation is optional. If the unit is not given the natural
-indentation of the formatting system applied will be used. Note also that
-there are some basic rules to using =item: don't use them outside of 
-an =over/=back block, use at least one inside an =over/=back block, you don't
-_have_ to include the =back if the list just runs off the document, and
-perhaps most importantly, keep the items consistent: either use "=item *" for
-all of them, to produce bullets, or use "=item 1.", "=item 2.", etc., to
-produce numbered lists, or use "=item foo", "=item bar", etc., i.e., things
-that looks nothing like bullets or numbers. If you start with bullets or
-numbers, stick with them, as many formatters use the first "=item" type to
-decide how to format the list.
+  =item Using C<$|> to Control Buffering
 
-=item =for
+Such commands are explained in the
+"L<Formatting Codes|/"Formatting Codes">" section, below.
 
-=item =begin
+Note also that there are some basic rules to using "=over" ...
+"=back" regions:
 
-=item =end
+=over
 
-For, begin, and end let you include sections that are not interpreted
-as pod text, but passed directly to particular formatters. A formatter
-that can utilize that format will use the section, otherwise it will be
-completely ignored.  The directive "=for" specifies that the entire next
-paragraph is in the format indicated by the first word after
-"=for", like this:
+=item *
+
+Don't use "=item"s outside of an "=over" ... "=back" region.
+
+=item *
 
- =for html <br>
+The first thing after the "=over" command should be an "=item", unless
+there aren't going to be any items at all in this "=over" ... "=back"
+region.
+
+=item *
+
+Don't put "=headI<n>" commands inside an "=over" ... "=back" region.
+
+=item *
+
+And perhaps most importantly, keep the items consistent: either use
+"=item *" for all of them, to produce bullets; or use "=item 1.",
+"=item 2.", etc., to produce numbered lists; or use "=item foo",
+"=item bar", etc. -- namely, things that look nothing like bullets or
+numbers.
+
+If you start with bullets or numbers, stick with them, as
+formatters use the first "=item" type to decide how to format the
+list.
+
+=back
+
+=item C<=cut>
+
+To end a Pod block, use a blank line,
+then a line beginning with "=cut", and a blank
+line after it.  This lets Perl (and the Pod formatter) know that
+this is where Perl code is resuming.  (The blank line before the "=cut"
+is not technically necessary, but many older Pod processors require it.)
+
+=item C<=pod>
+
+The "=pod" command by itself doesn't do much of anything, but it
+signals to Perl (and Pod formatters) that a Pod block starts here.  A
+Pod block starts with I<any> command paragraph, so a "=pod" command is
+usually used just when you want to start a Pod block with an ordinary
+paragraph or a verbatim paragraph.  For example:
+
+  =item stuff()
+  
+  This function does stuff.
+  
+  =cut
+  
+  sub stuff {
+    ...
+  }
+  
+  =pod
+  
+  Remember to check its return value, as in:
+  
+    stuff() || die "Couldn't do stufF!";
+  
+  =cut
+
+=item C<=begin I<formatname>>
+
+=item C<=end I<formatname>>
+
+=item C<=for I<formatname> I<text...>>
+
+For, begin, and end will let you have regions of text/code/data that
+are not generally interpreted as normal Pod text, but are passed
+directly to particular formatters, or are otherwise special.  A
+formatter that can use that format will use the region, otherwise it
+will be completely ignored.
+
+A command "=begin I<formatname>", some paragraphs, and a
+command "=end I<formatname>", mean that the text/data inbetween
+is meant for formatters that understand the special format
+called I<formatname>.  For example,
+
+  =begin html
+  
+  <hr> <img src="thang.png">
   <p> This is a raw HTML paragraph </p>
+  
+  =end html
+
+The command "=for I<formatname> I<text...>"
+specifies that the remainder of just this paragraph (starting
+right after I<formatname>) is in that special format.  
+
+  =for html <hr> <img src="thang.png">
+  <p> This is a raw HTML paragraph </p>
+
+This means the same thing as the above "=begin html" ... "=end html"
+region.
 
-The paired commands "=begin" and "=end" work very similarly to "=for", but
-instead of only accepting a single paragraph, all text from "=begin" to a
-paragraph with a matching "=end" are treated as a particular format.
+That is, with "=for", you can have only one paragraph's worth
+of text (i.e., the text in "=foo targetname text..."), but with
+"=begin targetname" ... "=end targetname", you can have any amount
+of stuff inbetween.  (Note that there still must be a blank line
+after the "=begin" command and a blank line before the "=end"
+command.
 
 Here are some examples of how to use these:
 
- =begin html
+  =begin html
+
+  <br>Figure 1.<br><IMG SRC="figure1.png"><br>
+
+  =end html
+
+  =begin text
+
+    ---------------
+    |  foo        |
+    |        bar  |
+    ---------------
 
- <br>Figure 1.<IMG SRC="figure1.png"><br>
+  ^^^^ Figure 1. ^^^^
 
- =end html
+  =end text
 
- =begin text
+Some format names that formatters currently are known to accept
+include "roff", "man", "latex", "tex", "text", and "html".  (Some
+formatters will treat some of these as synonyms.)
 
-   ---------------
-   |  foo        |
-   |        bar  |
-   ---------------
+A format name of "comment" is common for just making notes (presumably
+to yourself) that won't appear in any formatted version of the Pod
+document:
 
- ^^^^ Figure 1. ^^^^
+  =for comment
+  Make sure that all the available options are documented!
 
- =end text
+Some I<formatnames> will require a leading colon (as in
+C<"=for :formatname">, or
+C<"=begin :formatname" ... "=end :formatname">),
+to signal that the text is not raw data, but instead I<is> Pod text
+(i.e., possibly containing formatting codes) that's just not for
+normal formatting (e.g., may not be a normal-use paragraph, but might
+be for formatting as a footnote).
 
-Some format names that formatters currently are known to accept include
-"roff", "man", "latex", "tex", "text", and "html". (Some formatters will
-treat some of these as synonyms.)
+=back
 
-And don't forget, when using any command, that the command lasts up until
-the end of the B<paragraph>, not the line. Hence in the examples below, you
-can see the empty lines after each command to end its paragraph.
+And don't forget, when using any command, that the command lasts up
+until the end of its I<paragraph>, not its line.  So in the
+examples below, you can see that every command needs the blank
+line after it, to end its paragraph.
 
 Some examples of lists include:
 
- =over 4
+  =over
+
+  =item *
+
+  First item
+
+  =item *
+
+  Second item
+
+  =back
+
+  =over
+
+  =item Foo()
+
+  Description of Foo function
+
+  =item Bar()
 
- =item *
+  Description of Bar function
 
- First item
+  =back
 
- =item *
 
- Second item
+=head2 Formatting Codes
 
- =back
+In ordinary paragraphs and in some command paragraphs, various
+formatting codes (a.k.a. "interior sequences") can be used:
 
- =over 4
+=for comment
+ "interior sequences" is such an opaque term.
+ Prefer "formatting codes" instead.
 
- =item Foo()
+=over
 
- Description of Foo function
+=item C<IE<lt>textE<gt>> -- italic text
 
- =item Bar()
+Used for emphasis ("C<be IE<lt>careful!E<gt>>") and parameters
+("C<redo IE<lt>LABELE<gt>>")
+
+=item C<BE<lt>textE<gt>> -- bold text
+
+Used for switches ("C<perl's BE<lt>-nE<gt> switch>"), programs
+("C<some systems provide a BE<lt>chfnE<gt> for that>"),
+emphasis ("C<be BE<lt>careful!E<gt>>"), and so on
+("C<and that feature is known as BE<lt>autovivificationE<gt>>").
+
+=item C<CE<lt>codeE<gt>> -- code text
+
+Renders code in a typewriter font, or gives some other indication that
+this represents program text ("C<CE<lt>gmtime($^T)E<gt>>") or some other
+form of computerese ("C<CE<lt>drwxr-xr-xE<gt>>").
+
+=item C<LE<lt>nameE<gt>> -- a hyperlink
+
+There are various syntaxes, listed below.  In the syntaxes given,
+C<text>, C<name>, and C<section> cannot contain the characters
+'/' and '|'; and any '<' or '>' should be matched.
+
+=over
+
+=item *
 
- Description of Bar function
+C<LE<lt>nameE<gt>>
 
- =back
+Link to a Perl manual page (e.g., C<LE<lt>Net::PingE<gt>>).  Note
+that C<name> should not contain spaces.  This syntax
+is also occasionally used for references to UNIX man pages, as in
+C<LE<lt>crontab(5)E<gt>>.
+
+=item *
+
+C<LE<lt>name/"sec"E<gt>> or C<LE<lt>name/secE<gt>>
+
+Link to a section in other manual page.  E.g.,
+C<LE<lt>perlsyn/"For Loops"E<gt>>
+
+=item *
+
+C<LE<lt>/"sec"E<gt>> or C<LE<lt>/secE<gt>> or C<LE<lt>"sec"E<gt>>
+
+Link to a section in this manual page.  E.g.,
+C<LE<lt>/"Object Methods"E<gt>>
 
 =back
 
-=head2 Ordinary Block of Text
-
-It will be filled, and maybe even
-justified.  Certain interior sequences are recognized both
-here and in commands:
-
-    I<text>     Italicize text, used for emphasis or variables
-    B<text>     Embolden text, used for switches and programs
-    S<text>     Text contains non-breaking spaces
-    C<code>     Render code in a typewriter font, or give some other
-                indication that this represents program text
-    L<name>     A link (cross reference) to name
-                   L<name>             manual page
-                   L<name/ident>       item in manual page
-                   L<name/"sec">       section in other manual page
-                   L<"sec">            section in this manual page
-                                       (the quotes are optional)
-                   L</"sec">           ditto
-               same as above but only 'text' is used for output.
-               (Text can not contain the characters '/' and '|', 
-               and should contain matched '<' or '>')
-                   L<text|name>
-                   L<text|name/ident>
-                   L<text|name/"sec">
-                   L<text|"sec">
-                   L<text|/"sec">
-
-    F<file>    Used for filenames
-    X<index>   An index entry
-    Z<>                A zero-width character
-    E<escape>   A named character (very similar to HTML escapes)
-                   E<lt>               A literal <
-                   E<gt>               A literal >
-                   E<sol>              A literal /
-                   E<verbar>           A literal |
-                   (these are optional except in other interior
-                    sequences and when preceded by a capital letter)
-                   E<n>                Character number n (probably in ASCII)
-                   E<html>             Some non-numeric HTML entity, such
-                                       as E<Agrave>
-
-Most of the time, you will only need a single set of angle brackets to
-delimit the beginning and end of interior sequences.  However, sometimes
-you will want to put a right angle bracket (or greater-than sign '>')
-inside of a sequence.  This is particularly common when using a sequence
-to provide a different font-type for a snippet of code.  As with all
-things in Perl, there is more than one way to do it.  One way is to
-simply escape the closing bracket using an C<E> sequence:
+A section is started by the named heading or item.  For
+example, C<LE<lt>perlvar/$.E<gt>> or C<LE<lt>perlvar/"$."E<gt>> both
+link to the section started by "C<=item $.>" in perlvar.  And
+C<LE<lt>perlsyn/For LoopsE<gt>> or C<LE<lt>perlsyn/"For Loops"E<gt>>
+both link to the section started by "C<=head2 For Loops>"
+in perlsyn.
+
+To control what text is used for display, you
+use "C<LE<lt>text|...E<gt>>", as in:
+
+=over
+
+=item *
+
+C<LE<lt>text|nameE<gt>>
+
+Link this text to that manual page.  E.g.,
+C<LE<lt>Perl Error Messages|perldiagE<gt>>
+
+=item *
+
+C<LE<lt>text|name/"sec"E<gt>> or C<LE<lt>text|name/secE<gt>>
+
+Link this text to that section in that manual page.  E.g.,
+C<LE<lt>SWITCH statements|perlsyn/"Basic BLOCKs and Switch
+Statements"E<gt>>
+
+=item *
+
+C<LE<lt>text|/"sec"E<gt>> or C<LE<lt>text|/secE<gt>>
+or C<LE<lt>text|"sec"E<gt>>
+
+Link this text to that section in this manual page.  E.g.,
+C<LE<lt>the various attributes|/"Member Data"E<gt>>
+
+=back
+
+Or you can link to a web page:
+
+=over
+
+=item *
+
+C<LE<lt>scheme:...E<gt>>
+
+Links to an absolute URL.  For example,
+C<LE<lt>http://www.perl.org/E<gt>>.  But note
+that there is no corresponding C<LE<lt>text|scheme:...E<gt>> syntax, for
+various reasons.
+
+=back
+
+=item C<EE<lt>escapeE<gt>> -- a character escape
+
+Very similar to HTML/XML C<&I<foo>;> "entity references":
+
+=over
+
+=item *
+
+C<EE<lt>ltE<gt>> -- a literal E<lt> (less than)
+
+=item *
+
+C<EE<lt>gtE<gt>> -- a literal E<gt> (greater than)
+
+=item *
+
+C<EE<lt>verbarE<gt>> -- a literal | (I<ver>tical I<bar>)
+
+=item *
+
+C<EE<lt>solE<gt>> = a literal / (I<sol>idus)
+
+The above four are optional except in other formatting codes,
+notably C<LE<lt>...E<gt>>, and when preceded by a
+capital letter.
+
+=item *
+
+C<EE<lt>htmlnameE<gt>>
+
+Some non-numeric HTML entity name, such as C<EE<lt>eacuteE<gt>>,
+meaning the same thing as C<&eacute;> in HTML -- i.e., a lowercase
+e with an acute (/-shaped) accent.
+
+=item *
+
+C<EE<lt>numberE<gt>>
+
+The ASCII/Latin-1/Unicode character with that number.  A
+leading "0x" means that I<number> is hex, as in
+C<EE<lt>0x201EE<gt>>.  A leading "0" means that I<number> is octal,
+as in C<EE<lt>075E<gt>>.  Otherwise I<number> is interpreted as being
+in decimal, as in C<EE<lt>181E<gt>>.
+
+Note that older Pod formatters might not recognize octal or
+hex numeric escapes, and that many formatters cannot reliably
+render characters above 255.  (Some formatters may even have
+to use compromised renderings of Latin-1 characters, like
+rendering C<EE<lt>eacuteE<gt>> as just a plain "e".)
+
+=back
+
+=item C<FE<lt>filenameE<gt>> -- used for filenames
+
+Typically displayed in italics.  Example: "C<FE<lt>.cshrcE<gt>>"
+
+=item C<SE<lt>textE<gt>> -- text contains non-breaking spaces
+
+This means that the words in I<text> should not be broken
+across lines.  Example: S<C<SE<lt>$x ? $y : $zE<gt>>>.
+
+=item C<XE<lt>topic nameE<gt>> -- an index entry
+
+This is ignored by most formatters, but some may use it for building
+indexes.  It always renders as empty-string.
+Example: C<XE<lt>absolutizing relative URLsE<gt>>
+
+=item C<ZE<lt>E<gt>> -- a null (zero-effect) formatting code
+
+This is rarely used.  It's one way to get around using an
+EE<lt>...E<gt> code sometimes.  For example, instead of
+"C<NEE<lt>ltE<gt>3>" (for "NE<lt>3") you could write
+"C<NZE<lt>E<gt>E<lt>3>" (the "ZE<lt>E<gt>" breaks up the "N" and
+the "E<lt>" so they can't be considered
+the part of a (fictitious) "NE<lt>...E<gt>" code.
+
+=for comment
+ This was formerly explained as a "zero-width character".  But it in
+ most parser models, it parses to nothing at all, as opposed to parsing
+ as if it were a E<zwnj> or E<zwj>, which are REAL zero-width characters.
+ So "width" and "character" are exactly the wrong words.
+
+=back
+
+Most of the time, you will need only a single set of angle brackets to
+delimit the beginning and end of formatting codes.  However,
+sometimes you will want to put a real right angle bracket (a
+greater-than sign, '>') inside of a formatting code.  This is particularly
+common when using a formatting code to provide a different font-type for a
+snippet of code.  As with all things in Perl, there is more than
+one way to do it.  One way is to simply escape the closing bracket
+using an C<E> code:
 
     C<$a E<lt>=E<gt> $b>
 
 This will produce: "C<$a E<lt>=E<gt> $b>"
 
-A more readable, and perhaps more "plain" way is to use an alternate set of
-delimiters that doesn't require a ">" to be escaped.  As of perl5.5.660,
-doubled angle brackets ("<<" and ">>") may be used I<if and only if there
-is whitespace immediately following the opening delimiter and immediately
-preceding the closing delimiter!> For example, the following will do the
-trick:
+A more readable, and perhaps more "plain" way is to use an alternate
+set of delimiters that doesn't require a single ">" to be escaped.  With
+the Pod formatters that are standard starting with perl5.5.660, doubled
+angle brackets ("<<" and ">>") may be used I<if and only if there is
+whitespace right after the opening delimiter and whitespace right
+before the closing delimiter!>  For example, the following will
+do the trick:
 
     C<< $a <=> $b >>
 
 In fact, you can use as many repeated angle-brackets as you like so
 long as you have the same number of them in the opening and closing
 delimiters, and make sure that whitespace immediately follows the last
-'<' of the opening delimiter, and immediately precedes the first '>' of
-the closing delimiter.  So the following will also work:
+'<' of the opening delimiter, and immediately precedes the first '>'
+of the closing delimiter.  (The whitespace is ignored.)  So the
+following will also work:
 
     C<<< $a <=> $b >>>
-    C<<<< $a <=> $b >>>>
+    C<<<<  $a <=> $b     >>>>
 
-This is currently supported by pod2text (Pod::Text), pod2man (Pod::Man),
-and any other pod2xxx and Pod::Xxxx translator that uses Pod::Parser
-1.093 or later.
+And they all mean exactly the same as this:
+
+    C<$a E<lt>=E<gt> $b>
+
+As a further example, this means that if you wanted to put these bits of
+code in C<C> (code) style:
+
+    open(X, ">>thing.dat") || die $!
+    $foo->bar();
+
+you could do it like so:
+
+    C<<< open(X, ">>thing.dat") || die $! >>>
+    C<< $foo->bar(); >>
 
+which is presumably easier to read than the old way:
+
+    C<open(X, "E<gt>E<gt>thing.dat") || die $!>
+    C<$foo-E<gt>bar(); >>
+
+This is currently supported by pod2text (Pod::Text), pod2man (Pod::Man),
+and any other pod2xxx or Pod::Xxxx translators that use
+Pod::Parser 1.093 or later, or Pod::Tree 1.02 or later.
 
 =head2 The Intent
 
-That's it.  The intent is simplicity, not power.  I wanted paragraphs
-to look like paragraphs (block format), so that they stand out
-visually, and so that I could run them through fmt easily to reformat
-them (that's F7 in my version of B<vi>).  I wanted the translator (and not
-me) to worry about whether " or ' is a left quote or a right quote
-within filled text, and I wanted it to leave the quotes alone, dammit, in
-verbatim mode, so I could slurp in a working program, shift it over 4
-spaces, and have it print out, er, verbatim.  And presumably in a
-constant width font.
-
-In particular, you can leave things like this verbatim in your text:
-
-    Perl
-    FILEHANDLE
-    $variable
-    function()
-    manpage(3r)
-
-Doubtless a few other commands or sequences will need to be added along
-the way, but I've gotten along surprisingly well with just these.
-
-Note that I'm not at all claiming this to be sufficient for producing a
-book.  I'm just trying to make an idiot-proof common source for nroff,
-TeX, and other markup languages, as used for online documentation.
-Translators exist for B<pod2man>  (that's for nroff(1) and troff(1)),
-B<pod2text>, B<pod2html>, B<pod2latex>, and B<pod2fm>.
+The intent is simplicity of use, not power of expression.  Paragraphs
+look like paragraphs (block format), so that they stand out
+visually, and so that I could run them through C<fmt> easily to reformat
+them (that's F7 in my version of B<vi>, or Esc Q in my version of
+B<emacs>).  I wanted the translator to always leave the C<'> and C<`> and
+C<"> quotes alone, in verbatim mode, so I could slurp in a
+working program, shift it over four spaces, and have it print out, er,
+verbatim.  And presumably in a monospace font.
+
+The Pod format is not necessarily sufficient for writing a book.  Pod
+is just meant to be an idiot-proof common source for nroff, HTML,
+TeX, and other markup languages, as used for online
+documentation.  Translators exist for B<pod2text>, B<pod2html>,
+B<pod2man> (that's for nroff(1) and troff(1)), B<pod2latex>, and
+B<pod2fm>.  Various others are available in CPAN.
+
 
 =head2 Embedding Pods in Perl Modules
 
-You can embed pod documentation in your Perl scripts.  Start your
-documentation with a "=head1" command at the beginning, and end it
-with a "=cut" command.  Perl will ignore the pod text.  See any of the
-supplied library modules for examples.  If you're going to put your
-pods at the end of the file, and you're using an __END__ or __DATA__
-cut mark, make sure to put an empty line there before the first pod
-directive.
+You can embed Pod documentation in your Perl modules and scripts.
+Start your documentation with an empty line, a "=head1" command at the
+beginning, and end it with a "=cut" command and an empty line.  Perl
+will ignore the Pod text.  See any of the supplied library modules for
+examples.  If you're going to put your Pod at the end of the file, and
+you're using an __END__ or __DATA__ cut mark, make sure to put an
+empty line there before the first Pod command.
 
-    __END__
+  __END__
 
-    =head1 NAME
+  =head1 NAME
 
-    modern - I am a modern module
+  Time::Local - efficiently compute time from local and GMT time
 
-If you had not had that empty line there, then the translators wouldn't
-have seen it.
+Without that empty line before the "=head1", many translators wouldn't
+have recognized the "=head1" as starting a Pod block.
 
-=head2 Common Pod Pitfalls
+=head2 Hints for Writing Pod
 
-=over 4
+=over
 
 =item *
 
-Pod translators usually will require paragraphs to be separated by
-completely empty lines.  If you have an apparently empty line with
-some spaces on it, this can cause odd formatting.
+The B<podchecker> command is provided for checking Pod syntax for errors
+and warnings.  For example, it checks for completely blank lines in
+Pod blocks and for unknown commands and formatting codes.  You should
+still also pass your document through one or more translators and proofread
+the result, or print out the result and proofread that.  Some of the
+problems found may be bugs in the translators, which you may or may not
+wish to work around.
 
 =item *
 
-Translators will mostly add wording around a LE<lt>E<gt> link, so that
-C<LE<lt>foo(1)E<gt>> becomes "the I<foo>(1) manpage", for example (see
-B<pod2man> for details).  Thus, you shouldn't write things like C<the
-LE<lt>fooE<gt> manpage>, if you want the translated document to read
-sensibly.
+If you're more familiar with writing in HTML than with writing in Pod, you
+can try your hand at writing documentation in simple HTML, and coverting
+it to Pod with the experimental L<Pod::HTML2Pod|Pod::HTML2Pod> module,
+(available in CPAN), and looking at the resulting code.  The experimental
+L<Pod::PXML|Pod::PXML> module in CPAN might also be useful.
+
+=item *
+
+Many older Pod translators require the lines before every Pod
+command and after every Pod command (including "=cut"!) to be a blank
+line.  Having something like this:
+
+ # - - - - - - - - - - - -
+ =item $firecracker->boom()
+ This noisily detonates the firecracker object.
+ =cut
+ sub boom {
+ ...
+
+...will make such Pod translators completely fail to see the Pod block
+at all.
+
+Instead, have it like this:
+
+ # - - - - - - - - - - - -
+ =item $firecracker->boom()
+ This noisily detonates the firecracker object.
+ =cut
+ sub boom {
+ ...
+
+=item *
+
+Some older Pod translators require paragraphs (including command
+paragraphs like "=head2 Functions") to be separated by I<completely>
+empty lines.  If you have an apparently empty line with some spaces
+on it, this might not count as a separator for those translators, and
+that could cause odd formatting.
+
+=item *
 
-If you need total control of the text used for a link in the output
-use the form LE<lt>show this text|fooE<gt> instead.
+Older translators might add wording around an LE<lt>E<gt> link, so that
+C<LE<lt>Foo::BarE<gt>> may become "the Foo::Bar manpage", for example.
+So you shouldn't write things like C<the LE<lt>fooE<gt>
+documentation>, if you want the translated document to read sensibly
+-- instead write C<the LE<lt>Foo::Bar|Foo::BarE<gt> documentation> or
+C<LE<lt>the Foo::Bar documentation|Foo::BarE<gt>>, to control how the
+link comes out.
 
 =item *
 
-The B<podchecker> command is provided to check pod syntax
-for errors and warnings. For example, it checks for completely
-blank lines in pod segments and for unknown escape sequences.
-It is still advised to pass it through
-one or more translators and proofread the result, or print out the
-result and proofread that.  Some of the problems found may be bugs in
-the translators, which you may or may not wish to work around.
+Going past the 70th column in a verbatim block might be ungracefully
+wrapped by some formatters.
 
 =back
 
 =head1 SEE ALSO
 
-L<pod2man>, L<perlsyn/"PODs: Embedded Documentation">,
-L<podchecker>
+L<perlpodspec>, L<perlsyn/"PODs: Embedded Documentation">,
+L<perlnewmod>, L<perldoc>, L<pod2html>, L<pod2man>, L<podchecker>.
 
 =head1 AUTHOR
 
-Larry Wall
+Larry Wall, Sean M. Burke
 
+=cut
diff --git a/pod/perlpodspec.pod b/pod/perlpodspec.pod
new file mode 100644 (file)
index 0000000..c87e1cb
--- /dev/null
@@ -0,0 +1,1876 @@
+
+=head1 NAME
+
+perlpodspec - Plain Old Documentation: format specification and notes
+
+=head1 DESCRIPTION
+
+This document is detailed notes on the Pod markup language.  Most
+people will only have to read L<perlpod|perlpod> to know how to write
+in Pod, but this document may answer some incidental questions to do
+with parsing and rendering Pod.
+
+In this document, "must" / "must not", "should" /
+"should not", and "may" have their conventional (cf. RFC 2119)
+meanings: "X must do Y" means that if X doesn't do Y, it's against
+this specification, and should really be fixed.  "X should do Y"
+means that it's recommended, but X may fail to do Y, if there's a
+good reason.  "X may do Y" is merely a note that X can do Y at
+will (although it is up to the reader to detect any connotation of
+"and I think it would be I<nice> if X did Y" versus "it wouldn't
+really I<bother> me if X did Y").
+
+Notably, when I say "the parser should do Y", the
+parser may fail to do Y, if the calling application explicitly
+requests that the parser I<not> do Y.  I often phrase this as
+"the parser should, by default, do Y."  This doesn't I<require>
+the parser to provide an option for turning off whatever
+feature Y is (like expanding tabs in verbatim paragraphs), although
+it implicates that such an option I<may> be provided.
+
+=head1 Pod Definitions
+
+Pod is embedded in files, typically Perl source files -- although you
+can write a file that's nothing but Pod.
+
+A B<line> in a file consists of zero or more non-newline characters,
+terminated by either a newline or the end of the file.
+
+A B<newline sequence> is usually a platform-dependent concept, but
+Pod parsers should understand it to mean any of CR (ASCII 13), LF
+(ASCII 10), or a CRLF (ASCII 13 followed immediately by ASCII 10), in
+addition to any other system-specific meaning.  The first CR/CRLF/LF
+sequence in the file may be used as the basis for identifying the
+newline sequence for parsing the rest of the file.
+
+A B<blank line> is a line consisting entirely of zero or more spaces
+(ASCII 32) or tabs (ASCII 9), and terminated by a newline or end-of-file.
+A B<non-blank line> is a line containing one or more characters other
+than space or tab (and terminated by a newline or end-of-file).
+
+(I<Note:> Many older Pod parsers did not accept a line consisting of
+spaces/tabs and then a newline as a blank line -- the only lines they
+considered blank were lines consisting of I<no characters at all>,
+terminated by a newline.)
+
+B<Whitespace> is used in this document as a blanket term for spaces,
+tabs, and newline sequences.  (By itself, this term usually refers
+to literal whitespace.  That is, sequences of whitespace characters
+in Pod source, as opposed to "EE<lt>32>", which is a formatting
+code that I<denotes> a whitespace character.)
+
+A B<Pod parser> is a module meant for parsing Pod (regardless of
+whether this involves calling callbacks or building a parse tree or
+directly formatting it).  A B<Pod formatter> (or B<Pod translator>)
+is a module or program that converts Pod to some other format (HTML,
+plaintext, TeX, PostScript, RTF).  A B<Pod processor> might be a
+formatter or translator, or might be a program that does something
+else with the Pod (like wordcounting it, scanning for index points,
+etc.).
+
+Pod content is contained in B<Pod blocks>.  A Pod block starts with a
+line that matches <m/\A=[a-zA-Z]/>, and continues up to the next line
+that matches C<m/\A=cut/> -- or up to the end of the file, if there is
+no C<m/\A=cut/> line.
+
+=for comment
+ The current perlsyn says:
+ [beginquote]
+   Note that pod translators should look at only paragraphs beginning
+   with a pod directive (it makes parsing easier), whereas the compiler
+   actually knows to look for pod escapes even in the middle of a
+   paragraph.  This means that the following secret stuff will be ignored
+   by both the compiler and the translators.
+      $a=3;
+      =secret stuff
+       warn "Neither POD nor CODE!?"
+      =cut back
+      print "got $a\n";
+   You probably shouldn't rely upon the warn() being podded out forever.
+   Not all pod translators are well-behaved in this regard, and perhaps
+   the compiler will become pickier.
+ [endquote]
+ I think that those paragraphs should just be removed; paragraph-based
+ parsing  seems to have been largely abandoned, because of the hassle
+ with non-empty blank lines messing up what people meant by "paragraph".
+ Even if the "it makes parsing easier" bit were especially true,
+ it wouldn't be worth the confusion of having perl and pod2whatever
+ actually disagree on what can constitute a Pod block.
+
+Within a Pod block, there are B<Pod paragraphs>.  A Pod paragraph
+consists of non-blank lines of text, separated by one or more blank
+lines.
+
+For purposes of Pod processing, there are four types of paragraphs in
+a Pod block:
+
+=over
+
+=item *
+
+A command paragraph (also called a "directive").  The first line of
+this paragraph must match C<m/\A=[a-zA-Z]/>.  Command paragraphs are
+typically one line, as in:
+
+  =head1 NOTES
+
+  =item *
+
+But they may span several (non-blank) lines:
+
+  =for comment
+  Hm, I wonder what it would look like if
+  you tried to write a BNF for Pod from this.
+  
+  =head3 Dr. Strangelove, or: How I Learned to
+  Stop Worrying and Love the Bomb
+
+I<Some> command paragraphs allow formatting codes in their content
+(i.e., after the part that matches C<m/\A=[a-zA-Z]\S*\s*/>), as in:
+
+  =head1 Did You Remember to C<use strict;>?
+
+In other words, the Pod processing handler for "head1" will apply the
+same processing to "Did You Remember to CE<lt>use strict;>?" that it
+would to an ordinary paragraph -- i.e., formatting codes (like
+"CE<lt>...>") are parsed and presumably formatted appropriately, and
+whitespace in the form of literal spaces and/or tabs is not
+significant.
+
+=item *
+
+A B<verbatim paragraph>.  The first line of this paragraph must be a
+literal space or tab, and this paragraph must not be inside a "=begin
+I<identifier>", ... "=end I<identifier>" sequence unless
+"I<identifier>" begins with a colon (":").  That is, if a paragraph
+starts with a literal space or tab, but I<is> inside a
+"=begin I<identifier>", ... "=end I<identifier>" region, then it's
+a data paragraph, unless "I<identifier>" begins with a colon.
+
+Whitespace I<is> significant in verbatim paragraphs (although, in
+processing, tabs are probably expanded).
+
+=item *
+
+An B<ordinary paragraph>.  A paragraph is an ordinary paragraph
+if its first line matches neither C<m/\A=[a-zA-Z]/> nor
+C<m/\A[ \t]/>, I<and> if it's not inside a "=begin I<identifier>",
+... "=end I<identifier>" sequence unless "I<identifier>" begins with
+a colon (":").
+
+=item *
+
+A B<data paragraph>.  This is a paragraph that I<is> inside a "=begin
+I<identifier>" ... "=end I<identifier>" sequence where
+"I<identifier>" does I<not> begin with a literal colon (":").  In
+some sense, a data paragraph is not part of Pod at all (i.e.,
+effectively it's "out-of-band"), since it's not subject to most kinds
+of Pod parsing; but it is specified here, since Pod
+parsers need to be able to call an event for it, or store it in some
+form in a parse tree, or at least just parse I<around> it.
+
+=back
+
+For example: consider the following paragraphs:
+
+  # <- that's the 0th column
+
+  =head1 Foo
+  
+  Stuff
+  
+    $foo->bar
+  
+  =cut
+
+Here, "=head1 Foo" and "=cut" are command paragraphs because the first
+line of each matches C<m/\A=[a-zA-Z]/>.  "I<[space][space]>$foo->bar"
+is a verbatim paragraph, because its first line starts with a literal
+whitespace character (and there's no "=begin"..."=end" region around).
+
+The "=begin I<identifier>" ... "=end I<identifier>" commands stop
+paragraphs that they surround from being parsed as data or verbatim
+paragraphs, if I<identifier> doesn't begin with a colon.  This
+is discussed in detail in the section
+L</About Data Paragraphs and "=beginE<sol>=end" Regions>.
+
+=head1 Pod Commands
+
+This section is intended to supplement and clarify the discussion in
+L<perlpod/"Command Paragraph">.  These are the currently recognized
+Pod commands:
+
+=over
+
+=item "=head1", "=head2", "=head3", "=head4"
+
+This command indicates that the text in the remainder of the paragraph
+is a heading.  That text may contain formatting codes.  Examples:
+
+  =head1 Object Attributes
+  
+  =head3 What B<Not> to Do!
+
+=item "=pod"
+
+This command indicates that this paragraph begins a Pod block.  (If we
+are already in the middle of a Pod block, this command has no effect at
+all.)  If there is any text in this command paragraph after "=pod",
+it must be ignored.  Examples:
+
+  =pod
+  
+  This is a plain Pod paragraph.
+  
+  =pod This text is ignored.
+
+=item "=cut"
+
+This command indicates that this line is the end of this previously
+started Pod block.  If there is any text after "=cut" on the line, it must be
+ignored.  Examples:
+
+  =cut
+
+  =cut The documentation ends here.
+
+  =cut
+  # This is the first line of program text.
+  sub foo { # This is the second.
+
+It is an error to try to I<start> a Pod black with a "=cut" command.  In
+that case, the Pod processor must halt parsing of the input file, and
+must by default emit a warning.
+
+=item "=over"
+
+This command indicates that this is the start of a list/indent
+region.  If there is any text following the "=over", it must consist
+of only a nonzero positive numeral.  The semantics of this numeral is
+explained in the L</"About =over...=back Regions"> section, further
+below.  Formatting codes are not expanded.  Examples:
+
+  =over 3
+  
+  =over 3.5
+  
+  =over
+
+=item "=item"
+
+This command indicates that an item in a list begins here.  Formatting
+codes are processed.  The semantics of the (optional) text in the
+remainder of this paragraph are
+explained in the L</"About =over...=back Regions"> section, further
+below.  Examples:
+
+  =item
+  
+  =item *
+  
+  =item      *    
+  
+  =item 14
+  
+  =item   3.
+  
+  =item C<< $thing->stuff(I<dodad>) >>
+  
+  =item For transporting us beyond seas to be tried for pretended
+  offenses
+  
+  =item He is at this time transporting large armies of foreign
+  mercenaries to complete the works of death, desolation and
+  tyranny, already begun with circumstances of cruelty and perfidy
+  scarcely paralleled in the most barbarous ages, and totally
+  unworthy the head of a civilized nation.
+
+=item "=back"
+
+This command indicates that this is the end of the region begun
+by the most recent "=over" command.  It permits no text after the
+"=back" command.
+
+=item "=begin formatname"
+
+This marks the following paragraphs (until the matching "=end
+formatname") as being for some special kind of processing.  Unless
+"formatname" begins with a colon, the contained non-command
+paragraphs are data paragraphs.  But if "formatname" I<does> begin
+with a colon, then non-command paragraphs are ordinary paragraphs
+or data paragraphs.  This is discussed in detail in the section
+L</About Data Paragraphs and "=beginE<sol>=end" Regions>.
+
+It is advised that formatnames match the regexp
+C<m/\A:?[-a-zA-Z0-9_]+\z/>.  Implementors should anticipate future
+expansion in the semantics and syntax of the first parameter
+to "=begin"/"=end"/"=for".
+
+=item "=end formatname"
+
+This marks the end of the region opened by the matching
+"=begin formatname" region.  If "formatname" is not the formatname
+of the most recent open "=begin formatname" region, then this
+is an error, and must generate an error message.  This
+is discussed in detail in the section
+L</About Data Paragraphs and "=beginE<sol>=end" Regions>.
+
+=item "=for formatname text..."
+
+This is synonymous with:
+
+     =begin formatname
+     
+     text...
+     
+     =end formatname
+
+That is, it creates a region consisting of a single paragraph; that
+paragraph is to be treated as a normal paragraph if "formatname"
+begins with a ":"; if "formatname" I<doesn't> begin with a colon,
+then "text..." will constitute a data paragraph.  There is no way
+to use "=for formatname text..." to express "text..." as a verbatim
+paragraph.
+
+=back
+
+If a Pod processor sees any command other than the ones listed
+above (like "=head", or "=haed1", or "=stuff", or "=cuttlefish",
+or "=w123"), that processor must by default treat this as an
+error.  It must not process the paragraph beginning with that
+command, must by default warn of this as an error, and may
+abort the parse.  A Pod parser may allow a way for particular
+applications to add to the above list of known commands, and to
+stipulate, for each additional command, whether formatting
+codes should be processed.
+
+Future versions of this specification may add additional
+commands.
+
+
+
+=head1 Pod Formatting Codes
+
+(Note that in previous drafts of this document and of perlpod,
+formatting codes were referred to as "interior sequences", and
+this term may still be found in the documentation for Pod parsers,
+and in error messages from Pod processors.)
+
+There are two syntaxes for formatting codes:
+
+=over
+
+=item *
+
+A formatting code starts with a capital letter (just US-ASCII [A-Z])
+followed by a "<", any number of characters, and ending with the first
+matching ">".  Examples:
+
+    That's what I<you> think!
+
+    What's C<dump()> for?
+
+    X<C<chmod> and C<unlink()> Under Different Operating Systems>
+
+=item *
+
+A formatting code starts with a capital letter (just US-ASCII [A-Z])
+followed by two or more "<"'s, one or more whitespace characters,
+any number of characters, one or more whitespace characters,
+and ending with the first matching sequence of two or more ">"'s, where
+the number of ">"'s equals the number of "<"'s in the opening of this
+formatting code.  Examples:
+
+    That's what I<< you >> think!
+
+    C<<< open(X, ">>thing.dat") || die $! >>>
+
+    B<< $foo->bar(); >>
+
+With this syntax, the whitespace character(s) after the "CE<lt><<"
+and before the ">>" (or whatever letter) are I<not> renderable -- they
+do not signify whitespace, are merely part of the formatting codes
+themselves.  That is, these are all synonymous:
+
+    C<thing>
+    C<< thing >>
+    C<<           thing     >>
+    C<<<   thing >>>
+    C<<<<
+    thing
+               >>>>
+
+and so on.
+
+=back
+
+In parsing Pod, a notably tricky part is the correct parsing of
+(potentially nested!) formatting codes.  Implementors should
+consult the code in the C<parse_text> routine in Pod::Parser as an
+example of a correct implementation.
+
+=over
+
+=item C<IE<lt>textE<gt>> -- italic text
+
+See the brief discussion in L<perlpod/"Formatting Codes">.
+
+=item C<BE<lt>textE<gt>> -- bold text
+
+See the brief discussion in L<perlpod/"Formatting Codes">.
+
+=item C<CE<lt>codeE<gt>> -- code text
+
+See the brief discussion in L<perlpod/"Formatting Codes">.
+
+=item C<FE<lt>filenameE<gt>> -- style for filenames
+
+See the brief discussion in L<perlpod/"Formatting Codes">.
+
+=item C<XE<lt>topic nameE<gt>> -- an index entry
+
+See the brief discussion in L<perlpod/"Formatting Codes">.
+
+This code is unusual in that most formatters completely discard
+this code and its content.  Other formatters will render it with
+invisible codes that can be used in building an index of
+the current document.
+
+=item C<ZE<lt>E<gt>> -- a null (zero-effect) formatting code
+
+Discussed briefly in L<perlpod/"Formatting Codes">.
+
+This code is unusual is that it should have no content.  That is,
+a processor may complain if it sees C<ZE<lt>potatoesE<gt>>.  Whether
+or not it complains, the I<potatoes> text should ignored.
+
+=item C<LE<lt>nameE<gt>> -- a hyperlink
+
+The complicated syntaxes of this code are discussed at length in
+L<perlpod/"Formatting Codes">, and implementation details are
+discussed below, in L</"About LE<lt>...E<gt> Codes">.  Parsing the
+contents of LE<lt>content> is tricky.  Notably, the content has to be
+checked for whether it looks like a URL, or whether it has to be split
+on literal "|" and/or "/" (in the right order!), and so on,
+I<before> EE<lt>...> codes are resolved.
+
+=item C<EE<lt>escapeE<gt>> -- a character escape
+
+See L<perlpod/"Formatting Codes">, and several points in
+L</Notes on Implementing Pod Processors>.
+
+=item C<SE<lt>textE<gt>> -- text contains non-breaking spaces
+
+This formatting code is syntactically simple, but semantically
+complex.  What it means is that each space in the printable
+content of this code signifies a nonbreaking space.
+
+Consider:
+
+    C<$x ? $y    :  $z>
+
+    S<C<$x ? $y     :  $z>>
+
+Both signify the monospace (c[ode] style) text consisting of
+"$x", one space, "?", one space, ":", one space, "$z".  The
+difference is that in the latter, with the S code, those spaces
+are not "normal" spaces, but instead are nonbreaking spaces.
+
+=back
+
+
+If a Pod processor sees any formatting code other than the ones
+listed above (as in "NE<lt>...>", or "QE<lt>...>", etc.), that
+processor must by default treat this as an error.
+A Pod parser may allow a way for particular
+applications to add to the above list of known formatting codes;
+a Pod parser might even allow a way to stipulate, for each additional
+command, whether it requires some form of special processing, as
+LE<lt>...> does.
+
+Future versions of this specification may add additional
+formatting codes.
+
+Historical note:  A few older Pod processors would not see a ">" as
+closing a "CE<lt>" code, if the ">" was immediately preceded by
+a "-".  This was so that this:
+
+    C<$foo->bar>
+
+would parse as equivalent to this:
+
+    C<$foo-E<lt>bar>
+
+instead of as equivalent to a "C" formatting code containing 
+only "$foo-", and then a "bar>" outside the "C" formatting code.  This
+problem has since been solved by the addition of syntaxes like this:
+
+    C<< $foo->bar >>
+
+Compliant parsers must not treat "->" as special.
+
+Formatting codes absolutely cannot span paragraphs.  If a code is
+opened in one paragraph, and no closing code is found by the end of
+that paragraph, the Pod parser must close that formatting code,
+and should complain (as in "Unterminated I code in the paragraph
+starting at line 123: 'Time objects are not...'").  So these
+two paragraphs:
+
+  I<I told you not to do this!
+  
+  Don't make me say it again!>
+
+...must I<not> be parsed as two paragraphs in italics (with the I
+code starting in one paragraph and starting in another.)  Instead,
+the first paragraph should generate a warning, but that aside, the
+above code must parse as if it were:
+
+  I<I told you not to do this!>
+  
+  Don't make me say it again!E<gt>
+
+(In SGMLish jargon, all Pod commands are like block-level
+elements, whereas all Pod formatting codes are like inline-level
+elements.)
+
+
+
+=head1 Notes on Implementing Pod Processors
+
+The following is a long section of miscellaneous requirements
+and suggestions to do with Pod processing.
+
+=over
+
+=item *
+
+Pod formatters should tolerate lines in verbatim blocks that are of
+any length, even if that means having to break them (possibly several
+times, for very long lines) to avoid text running off the side of the
+page.  Pod formatters may warn of such line-breaking.  Such warnings
+are particularly appropriate for lines are over 100 characters long, which
+are usually not intentional.
+
+=item *
+
+Pod parsers must recognize I<all> of the three well-known newline
+formats: CR, LF, and CRLF.  See L<perlport|perlport>.
+
+=item *
+
+Pod parsers should accept input lines that are of any length.
+
+=item *
+
+Since Perl recognizes a Unicode Byte Order Mark at the start of files
+as signaling that the file is Unicode encoded as in UTF-16 (whether
+big-endian or little-endian) or UTF-8, Pod parsers should do the
+same.  Otherwise, the character encoding should be understood as
+being UTF-8 if the first highbit byte sequence in the file seems
+valid as a UTF-8 sequence, or otherwise as Latin-1.
+
+Future versions of this specification may specify
+how Pod can accept other encodings.  Presumably treatment of other
+encodings in Pod parsing would be as in XML parsing: whatever the
+encoding declared by a particular Pod file, content is to be
+stored in memory as Unicode characters.
+
+=item *
+
+The well known Unicode Byte Order Marks are as follows:  if the
+file begins with the two literal byte values 0xFE 0xFF, this is
+the BOM for big-endian UTF-16.  If the file begins with the two
+literal byte value 0xFF 0xFE, this is the BOM for little-endian
+UTF-16.  If the file begins with the three literal byte values
+0xEF 0xBB 0xBF, this is the BOM for UTF-8.
+
+=for comment
+ use bytes; print map sprintf(" 0x%02X", ord $_), split '', "\x{feff}";
+ 0xEF 0xBB 0xBF
+
+=for comment
+ If toke.c is modified to support UTF32, add mention of those here.
+
+=item *
+
+A naive but sufficient heuristic for testing the first highbit
+byte-sequence in a BOM-less file (whether in code or in Pod!), to see
+whether that sequence is valid as UTF-8 (RFC 2279) is to check whether
+that the first byte in the sequence is in the range 0xC0 - 0xFD
+I<and> whether the next byte is in the range
+0x80 - 0xBF.  If so, the parser may conclude that this file is in
+UTF-8, and all highbit sequences in the file should be assumed to
+be UTF-8.  Otherwise the parser should treat the file as being
+in Latin-1.  In the unlikely circumstance that the first highbit
+sequence in a truly non-UTF-8 file happens to appear to be UTF-8, one
+can cater to our heuristic (as well as any more intelligent heuristic)
+by prefacing that line with a comment line containing a highbit
+sequence that is clearly I<not> valid as UTF-8.  A line consisting
+of simply "#", an e-acute, and any non-highbit byte,
+is sufficient to establish this file's encoding.
+
+=for comment
+ If/WHEN some brave soul makes these heuristics into a generic
+ text-file class (or file discipline?), we can presumably delete
+ mention of these icky details from this file, and can instead
+ tell people to just use appropriate class/discipline.
+ Auto-recognition of newline sequences would be another desirable
+ feature of such a class/discipline.
+ HINT HINT HINT.
+
+=for comment
+ "The probability that a string of characters
+ in any other encoding appears as valid UTF-8 is low" - RFC2279
+
+=item *
+
+This document's requirements and suggestions about encodings
+do not apply to Pod processors running on non-ASCII platforms,
+notably EBCDIC platforms.
+
+=item *
+
+Pod processors must treat a "=for [label] [content...]" paragraph as
+meaning the same thing as a "=begin [label]" paragraph, content, and
+an "=end [label]" paragraph.  (The parser may conflate these two
+constructs, or may leave them distinct, in the expectation that the
+formatter will nevertheless treat them the same.)
+
+=item *
+
+When rendering Pod to a format that allows comments (i.e., to nearly
+any format other than plaintext), a Pod formatter must insert comment
+text identifying its name and version number, and the name and
+version numbers of any modules it might be using to process the Pod.
+Minimal examples:
+
+  %% POD::Pod2PS v3.14159, using POD::Parser v1.92
+  
+  <!-- Pod::HTML v3.14159, using POD::Parser v1.92 -->
+  
+  {\doccomm generated by Pod::Tree::RTF 3.14159 using Pod::Tree 1.08}
+  
+  .\" Pod::Man version 3.14159, using POD::Parser version 1.92
+
+Formatters may also insert additional comments, including: the
+release date of the Pod formatter program, the contact address for
+the author(s) of the formatter, the current time, the name of input
+file, the formatting options in effect, version of Perl used, etc.
+
+Formatters may also choose to note errors/warnings as comments,
+besides or instead of emitting them otherwise (as in messages to
+STDERR, or C<die>ing).
+
+=item *
+
+Pod parsers I<may> emit warnings or error messages ("Unknown E code
+EE<lt>zslig>!") to STDERR (whether through printing to STDERR, or
+C<warn>ing/C<carp>ing, or C<die>ing/C<croak>ing), but I<must> allow
+suppressing all such STDERR output, and instead allow an option for
+reporting errors/warnings
+in some other way, whether by triggering a callback, or noting errors
+in some attribute of the document object, or some similarly unobtrusive
+mechanism -- or even by appending a "Pod Errors" section to the end of
+the parsed form of the document.
+
+=item *
+
+In cases of exceptionally aberrant documents, Pod parsers may abort the
+parse.  Even then, using C<die>ing/C<croak>ing is to be avoided; where
+possible, the parser library may simply close the input file
+and add text like "*** Formatting Aborted ***" to the end of the
+(partial) in-memory document.
+
+=item *
+
+In paragraphs where formatting codes (like EE<lt>...>, BE<lt>...>)
+are understood (i.e., I<not> verbatim paragraphs, but I<including>
+ordinary paragraphs, and command paragraphs that produce renderable
+text, like "=head1"), literal whitespace should generally be considered
+"insignificant", in that one literal space has the same meaning as any
+(nonzero) number of literal spaces, literal newlines, and literal tabs
+(as long as this produces no blank lines, since those would terminate
+the paragraph).  Pod parsers should compact literal whitespace in each
+processed paragraph, but may provide an option for overriding this
+(since some processing tasks do not require it), or may follow
+additional special rules (for example, specially treating
+period-space-space or period-newline sequences).
+
+=item *
+
+Pod parsers should not, by default, try to coerce apostrophe (') and
+quote (") into smart quotes (little 9's, 66's, 99's, etc), nor try to
+turn backtick (`) into anything else but a single backtick character
+(distinct from an openquote character!), nor "--" into anything but
+two minus signs.  They I<must never> do any of those things to text
+in CE<lt>...> formatting codes, and never I<ever> to text in verbatim
+paragraphs.
+
+=item *
+
+When rendering Pod to a format that has two kinds of hyphens (-), one
+that's a nonbreaking hyphen, and another that's a breakable hyphen
+(as in "object-oriented", which can be split across lines as
+"object-", newline, "oriented"), formatters are encouraged to
+generally translate "-" to nonbreaking hyphen, but may apply
+heuristics to convert some of these to breaking hyphens.
+
+=item *
+
+Pod formatters should make reasonable efforts to keep words of Perl
+code from being broken across lines.  For example, "Foo::Bar" in some
+formatting systems is seen as eligible for being broken across lines
+as "Foo::" newline "Bar" or even "Foo::-" newline "Bar".  This should
+be avoided where possible, either by disabling all line-breaking in
+mid-word, or by wrapping particular words with internal punctuation
+in "don't break this across lines" codes (which in some formats may
+not be a single code, but might be a matter of inserting non-breaking
+zero-width spaces between every pair of characters in a word.)
+
+=item *
+
+Pod parsers should, by default, expand tabs in verbatim paragraphs as
+they are processed, before passing them to the formatter or other
+processor.  Parsers may also allow an option for overriding this.
+
+=item *
+
+Pod parsers should, by default, remove newlines from the end of
+ordinary and verbatim paragraphs before passing them to the
+formatter.  For example, while the paragraph you're reading now
+could be considered, in Pod source, to end with (and contain)
+the newline(s) that end it, it should be processed as ending with
+(and containing) the period character that ends this sentence.
+
+=item *
+
+Pod parsers, when reporting errors, should make some effort to report
+an approximate line number ("Nested EE<lt>>'s in Paragraph #52, near
+line 633 of Thing/Foo.pm!"), instead of merely noting the paragraph
+number ("Nested EE<lt>>'s in Paragraph #52 of Thing/Foo.pm!").  Where
+this is problematic, the paragraph number should at least be
+accompanied by an excerpt from the paragraph ("Nested EE<lt>>'s in
+Paragraph #52 of Thing/Foo.pm, which begins 'Read/write accessor for
+the CE<lt>interest rate> attribute...'").
+
+=item *
+
+Pod parsers, when processing a series of verbatim paragraphs one
+after another, should consider them to be one large verbatim
+paragraph that happens to contain blank lines.  I.e., these two
+lines, which have an blank line between them:
+
+       use Foo;
+
+       print Foo->VERSION
+
+should be unified into one paragraph ("\tuse Foo;\n\n\tprint
+Foo->VERSION") before being passed to the formatter or other
+processor.  Parsers may also allow an option for overriding this.
+
+While this might be too cumbersome to implement in event-based Pod
+parsers, it is straightforward for parsers that return parse trees.
+
+=item *
+
+Pod formatters, where feasible, are advised to avoid splitting short
+verbatim paragraphs (under twelve lines, say) across pages.
+
+=item *
+
+Pod parsers must treat a line with only spaces and/or tabs on it as a
+"blank line" such as separates paragraphs.  (Some older parsers
+recognized only two adjacent newlines as a "blank line" but would not
+recognize a newline, a space, and a newline, as a blank line.  This
+is noncompliant behavior.)
+
+=item *
+
+Authors of Pod formatters/processors should make every effort to
+avoid writing their own Pod parser.  There are already several in
+CPAN, with a wide range of interface styles -- and one of them,
+Pod::Parser, comes with modern versions of Perl.
+
+=item *
+
+Characters in Pod documents may be conveyed either as literals, or by
+number in EE<lt>n> codes, or by an equivalent mnemonic, as in
+EE<lt>eacute> which is exactly equivalent to EE<lt>233>.
+
+Characters in the range 32-126 refer to those well known US-ASCII
+characters (also defined there by Unicode, with the same meaning),
+which all Pod formatters must render faithfully.  Characters
+in the ranges 0-31 and 127-159 should not be used (neither as
+literals, nor as EE<lt>number> codes), except for the
+literal byte-sequences for newline (13, 13 10, or 13), and tab (9).
+
+Characters in the range 160-255 refer to Latin-1 characters (also
+defined there by Unicode, with the same meaning).  Characters above
+255 should be understood to refer to Unicode characters.
+
+=item *
+
+Be warned
+that some formatters cannot reliably render characters outside 32-126;
+and many are able to handle 32-126 and 160-255, but nothing above
+255.
+
+=item *
+
+Besides the well-known "EE<lt>lt>" and "EE<lt>gt>" codes for
+less-than and greater-than, Pod parsers must understand "EE<lt>sol>"
+for "/" (solidus, slash), and "EE<lt>verbar>" for "|" (vertical bar,
+pipe).  Pod parsers should also understand "EE<lt>lchevron>" and
+"EE<lt>rchevron>" as legacy codes for characters 171 and 187, i.e.,
+"left-pointing double angle quotation mark" = "left pointing
+guillemet" and "right-pointing double angle quotation mark" = "right
+pointing guillemet".  (These look like little "<<" and ">>", and they
+are now preferably expressed with the HTML/XHTML codes "EE<lt>laquo>"
+and "EE<lt>raquo>".)
+
+=item *
+
+Pod parsers should understand all "EE<lt>html>" codes as defined
+in the entity declarations in the most recent XHTML specification at
+C<www.W3.org>.  Pod parsers must understand at least the entities
+that define characters in the range 160-255 (Latin-1).  Pod parsers,
+when faced with some unknown "EE<lt>I<identifier>>" code,
+shouldn't simply replace it with nullstring (by default, at least),
+but may pass it through as a string consisting of the literal characters
+E, less-than, I<identifier>, greater-than.  Or Pod parsers may offer the
+alternative option of processing such unknown
+"EE<lt>I<identifier>>" codes by firing an event especially
+for such codes, or by adding a special node-type to the in-memory
+document tree.  Such "EE<lt>I<identifier>>" may have special meaning
+to some processors, or some processors may choose to add them to
+a special error report.
+
+=item *
+
+Pod parsers must also support the XHTML codes "EE<lt>quot>" for
+character 34 (doublequote, "), "EE<lt>amp>" for character 38
+(ampersand, &), and "EE<lt>apos>" for character 39 (apostrophe, ').
+
+=item *
+
+Note that in all cases of "EE<lt>whatever>", I<whatever> (whether
+an htmlname, or a number in any base) must consist only of
+alphanumeric characters -- that is, I<whatever> must watch
+C<m/\A\w+\z/>.  So "EE<lt> 0 1 2 3 >" is invalid, because
+it contains spaces, which aren't alphanumeric characters.  This
+presumably does not I<need> special treatment by a Pod processor;
+" 0 1 2 3 " doesn't look like a number in any base, so it would
+presumably be looked up in the table of HTML-like names.  Since
+there is (and cannot be) an HTML-like entity called " 0 1 2 3 ",
+this will be treated as an error.  However, Pod processors may
+treat "EE<lt> 0 1 2 3 >" or "EE<lt>e-acute>" as I<syntactically>
+invalid, potentially earning a different error message than the
+error message (or warning, or event) generated by a merely unknown
+(but theoretically valid) htmlname, as in "EE<lt>qacute>"
+[sic].  However, Pod parsers are not required to make this
+distinction.
+
+=item *
+
+Note that EE<lt>number> I<must not> be interpreted as simply
+"codepoint I<number> in the current/native character set".  It always
+means only "the character represented by codepoint I<number> in
+Unicode."  (This is identical to the semantics of &#I<number>; in XML.)
+
+This will likely require many formatters to have tables mapping from
+treatable Unicode codepoints (such as the "\xE9" for the e-acute
+character) to the escape sequences or codes necessary for conveying
+such sequences in the target output format.  A converter to *roff
+would, for example know that "\xE9" (whether conveyed literally, or via
+a EE<lt>...> sequence) is to be conveyed as "e\\*'".
+Similarly, a program rendering Pod in a MacOS application window, would
+presumably need to know that "\xE9" maps to codepoint 142 in MacRoman
+encoding that (at time of writing) is native for MacOS.  Such
+Unicode2whatever mappings are presumably already widely available for
+common output formats.  (Such mappings may be incomplete!  Implementers
+are not expected to bend over backwards in an attempt to render
+Cherokee syllabics, Etruscan runes, Byzantine musical symbols, or any
+of the other weird things that Unicode can encode.)  And
+if a Pod document uses a character not found in such a mapping, the
+formatter should consider it an unrenderable character.
+
+=item *
+
+If, surprisingly, the implementor of a Pod formatter can't find a
+satisfactory pre-existing table mapping from Unicode characters to
+escapes in the target format (e.g., a decent table of Unicode
+characters to *roff escapes), it will be necessary to build such a
+table.  If you are in this circumstance, you should begin with the
+characters in the range 0x00A0 - 0x00FF, which is mostly the heavily
+used accented characters.  Then proceed (as patience permits and
+fastidiousness compels) through the characters that the (X)HTML
+standards groups judged important enough to merit mnemonics
+for.  These are declared in the (X)HTML specifications at the
+www.W3.org site.  At time of writing (September 2001), the most recent
+entity declaration files are:
+
+  http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
+  http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent
+  http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent
+
+Then you can progress through any remaining notable Unicode characters
+in the range 0x2000-0x204D (consult the character tables at
+www.unicode.org), and whatever else strikes your fancy.  For example,
+in F<xhtml-symbol.ent>, there is the entry:
+
+  <!ENTITY infin    "&#8734;"> <!-- infinity, U+221E ISOtech -->
+
+While the mapping "infin" to the character "\x{221E}" will (hopefully)
+have been already handled by the Pod parser, the presence of the
+character in this file means that it's reasonably important enough to
+include in a formatter's table that maps from notable Unicode characters
+to the codes necessary for rendering them.  So for a Unicode-to-*roff
+mapping, for example, this would merit the entry:
+
+  "\x{221E}" => '\(in',
+
+It is eagerly hoped that in the future, increasing numbers of formats
+(and formatters) will support Unicode characters directly (as (X)HTML
+does with C<&infin;>, C<&#8734;>, or C<&#x221E;>), reducing the need
+for idiosyncratic mappings of Unicode-to-I<my_escapes>.
+
+=item *
+
+It is up to individual Pod formatter to display good judgment when
+confronted with an unrenderable character (which is distinct from an
+unknown EE<lt>thing> sequence that the parser couldn't resolve to
+anything, renderable or not).  It is good practice to map Latin letters
+with diacritics (like "EE<lt>eacute>"/"EE<lt>233>") to the corresponding
+unaccented US-ASCII letters (like a simple character 101, "e"), but
+clearly this is often not feasable, and an unrenderable character may
+be represented as "?", or the like.  In attempting a sane fallback
+(as from EE<lt>233> to "e"), Pod formatters may use the
+%Latin1Code_to_fallback table in L<Pod::Escapes|Pod::Escapes>, or
+L<Text::Unidecode|Text::Unidecode>, if available.
+
+For example, this Pod text:
+
+  magic is enabled if you set C<$Currency> to 'E<euro>'.
+
+may be rendered as:
+"magic is enabled if you set C<$Currency> to 'I<?>'" or as
+"magic is enabled if you set C<$Currency> to 'B<[euro]>'", or as
+"magic is enabled if you set C<$Currency> to '[x20AC]', etc.
+
+A Pod formatter may also note, in a comment or warning, a list of what
+unrenderable characters were encountered.
+
+=item *
+
+EE<lt>...> may freely appear in any formatting code (other than
+in another EE<lt>...> or in an ZE<lt>>).  That is, "XE<lt>The
+EE<lt>euro>1,000,000 Solution>" is valid, as is "LE<lt>The
+EE<lt>euro>1,000,000 Solution|Million::Euros>".
+
+=item *
+
+Some Pod formatters output to formats that implement nonbreaking
+spaces as an individual character (which I'll call "NBSP"), and
+others output to formats that implement nonbreaking spaces just as
+spaces wrapped in a "don't break this across lines" code.  Note that
+at the level of Pod, both sorts of codes can occur: Pod can contain a
+NBSP character (whether as a literal, or as a "EE<lt>160>" or
+"EE<lt>nbsp>" code); and Pod can contain "SE<lt>foo
+IE<lt>barE<gt> baz>" codes, where "mere spaces" (character 32) in
+such codes are taken to represent nonbreaking spaces.  Pod
+parsers should consider supporting the optional parsing of "SE<lt>foo
+IE<lt>barE<gt> baz>" as if it were
+"fooI<NBSP>IE<lt>barE<gt>I<NBSP>baz", and, going the other way, the
+optional parsing of groups of words joined by NBSP's as if each group
+were in a SE<lt>...> code, so that formatters may use the
+representation that maps best to what the output format demands.
+
+=item *
+
+Some processors may find it the C<SE<lt>...E<gt>> code easiest to
+implement by replacing each space in the parse tree under the content
+of the S, with an NBSP.  But note: the replacement should apply I<not> to
+spaces in I<all> text, but I<only> to spaces in I<printable> text.  (This
+distinction may or may not be evident in the particular tree/event
+model implemented by the Pod parser.)  For example, consider this
+unusual case:
+
+   S<L</Autoloaded Functions>>
+
+This means that the space in the middle of the visible link text must
+not be broken across lines.  In other words, it's the same as this:
+
+   L<"AutoloadedE<160>Functions"/Autoloaded Functions>
+
+However, a misapplied space-to-NBSP replacement could (wrongly)
+produce something equivalent to this:
+
+   L<"AutoloadedE<160>Functions"/AutoloadedE<160>Functions>
+
+...which is almost definitely not going to work as a hyperlink (assuming
+this formatter outputs a format supporting hypertext).
+
+Formatters may choose to just not support the S format code,
+especially in cases where the output format simply has no NBSP
+character/code and no code for "don't break this stuff across lines".
+
+=item *
+
+Besides the NBSP character discussed above, implementors are reminded
+of the existence of the other "special" character in Latin-1, the
+"soft hyphen" chararacter, also known as "discretionary hyphen",
+i.e. C<EE<lt>173E<gt>> = C<EE<lt>0xADE<gt>> =
+C<EE<lt>shyE<gt>>).  This character expresses an optional hyphenation
+point.  That is, it normally renders as nothing, but may render as a
+"-" if a formatter breaks the word at that point.  Pod formatters
+should, as appropriate, do one of the following:  1) render this with
+a code with the same meaning (e.g., "\-" in RTF), 2) pass it through
+in the expectation that the formatter understands this character as
+such, or 3) delete it.
+
+For example:
+
+  sigE<shy>action
+  manuE<shy>script
+  JarkE<shy>ko HieE<shy>taE<shy>nieE<shy>mi
+
+These signal to a formatter that if it is to hyphenate "sigaction"
+or "manuscript", then it should be done as
+"sig-I<[linebreak]>action" or "manu-I<[linebreak]>script"
+(and if it doesn't hyphenate it, then the C<EE<lt>shyE<gt>> doesn't
+show up at all).  And if it is
+to hyphenate "Jarkko" and/or "Hietaniemi", it can do
+so only at the points where there is a C<EE<lt>shyE<gt>> code.
+
+In practice, it is anticipated that this character will not be used
+often, but formatters should either support it, or delete it.
+
+=item *
+
+If you think that you want to add a new command to Pod (like, say, a
+"=biblio" command), consider whether you could get the same
+effect with a for or begin/end sequence: "=for biblio ..." or "=begin
+biblio" ... "=end biblio".  Pod processors that don't understand
+"=for biblio", etc, will simply ignore it, whereas they may complain
+loudly if they see "=biblio".
+
+=item *
+
+Throughout this document, "Pod" has been the preferred spelling for
+the name of the documentation format.  One may also use "POD" or
+"pod".  For the the documentation that is (typically) in the Pod
+format, you may use "pod", or "Pod", or "POD".  Understanding these
+distinctions is useful; but obsessing over how to spell them, usually
+is not.
+
+=back
+
+
+
+
+
+=head1 About LE<lt>...E<gt> Codes
+
+As you can tell from a glance at L<perlpod|perlpod>, the LE<lt>...>
+code is the most complex of the Pod formatting codes.  The points below
+will hopefully clarify what it means and how processors should deal
+with it.
+
+=over
+
+=item *
+
+In parsing an LE<lt>...> code, Pod parsers must distinguish at least
+four attributes:
+
+=over
+
+=item First:
+
+The link-text.  If there is none, this must be undef.  (E.g., in
+"LE<lt>Perl Functions|perlfunc>", the link-text is "Perl Functions".
+In "LE<lt>Time::HiRes>" and even "LE<lt>|Time::HiRes>", there is no
+link text.  Note that link text may contain formatting.)
+
+=item Second:
+
+The possibly inferred link-text -- i.e., if there was no real link
+text, then this is the text that we'll infer in its place.  (E.g., for
+"LE<lt>Getopt::Std>", the inferred link text is "Getopt::Std".)
+
+=item Third:
+
+The name or URL, or undef if none.  (E.g., in "LE<lt>Perl
+Functions|perlfunc>", the name -- also sometimes called the page --
+is "perlfunc".  In "LE<lt>/CAVEATS>", the name is undef.)
+
+=item Fourth:
+
+The section (AKA "item" in older perlpods), or undef if none.  E.g.,
+in L<Getopt::Std/DESCRIPTION>, "DESCRIPTION" is the section.  (Note
+that this is not the same as a manpage section like the "5" in "man 5
+crontab".  "Section Foo" in the Pod sense means the part of the text
+that's introduced by the heading or item whose text is "Foo".
+
+=back
+
+Pod parsers may also note additional attributes including:
+
+=over
+
+=item Fifth:
+
+A flag for whether item 3 (if present) is a URL (like
+"http://lists.perl.org" is), in which case there should be no section
+attribute; a Pod name (like "perldoc" and "Getopt::Std" are); or
+possibly a man page name (like "crontab(5)" is).
+
+=item Sixth:
+
+The raw original LE<lt>...> content, before text is split on
+"|", "/", etc, and before EE<lt>...> codes are expanded.
+
+=back
+
+(The above were numbered only for concise reference below.  It is not
+a requirement that these be passed as an actual list or array.)
+
+For example:
+
+  L<Foo::Bar>
+    =>  undef,                          # link text
+        "Foo::Bar",                     # possibly inferred link text
+        "Foo::Bar",                     # name
+        undef,                          # section
+        'pod',                          # what sort of link
+        "Foo::Bar"                      # original content
+
+  L<Perlport's section on NL's|perlport/Newlines>
+    =>  "Perlport's section on NL's",   # link text
+        "Perlport's section on NL's",   # possibly inferred link text
+        "perlport",                     # name
+        "Newlines",                     # section
+        'pod',                          # what sort of link
+        "Perlport's section on NL's|perlport/Newlines" # orig. content
+
+  L<perlport/Newlines>
+    =>  undef,                          # link text
+        '"Newlines" in perlport',       # possibly inferred link text
+        "perlport",                     # name
+        "Newlines",                     # section
+        'pod',                          # what sort of link
+        "perlport/Newlines"             # original content
+
+  L<crontab(5)/"DESCRIPTION">
+    =>  undef,                          # link text
+        '"DESCRIPTION" in crontab(5)',  # possibly inferred link text
+        "crontab(5)",                   # name
+        "DESCRIPTION",                  # section
+        'man',                          # what sort of link
+        'crontab(5)/"DESCRIPTION"'      # original content
+
+  L</Object Attributes>
+    =>  undef,                          # link text
+        '"Object Attributes"',          # possibly inferred link text
+        undef,                          # name
+        "Object Attributes",            # section
+        'pod',                          # what sort of link
+        "/Object Attributes"            # original content
+
+  L<http://www.perl.org/>
+    =>  undef,                          # link text
+        "http://www.perl.org/",         # possibly inferred link text
+        "http://www.perl.org/",         # name
+        undef,                          # section
+        'url',                          # what sort of link
+        "http://www.perl.org/"          # original content
+
+Note that you can distinguish URL-links from anything else by the
+fact that they match C<m/\A\w+:[^:\s]\S*\z/>.  So
+C<LE<lt>http://www.perl.comE<gt>> is a URL, but
+C<LE<lt>HTTP::ResponseE<gt>> isn't.
+
+=item *
+
+In case of LE<lt>...> codes with no "text|" part in them,
+older formatters have exhibited great variation in actually displaying
+the link or cross reference.  For example, LE<lt>crontab(5)> would render
+as "the C<crontab(5)> manpage", or "in the C<crontab(5)> manpage"
+or just "C<crontab(5)>".
+
+Pod processors must now treat "text|"-less links as follows:
+
+  L<name>         =>  L<name|name>
+  L</section>     =>  L<"section"|/section>
+  L<name/section> =>  L<"section" in name|name/section>
+
+=item *
+
+Note that section names might contain markup.  I.e., if a section
+starts with:
+
+  =head2 About the C<-M> Operator
+
+or with:
+
+  =item About the C<-M> Operator
+
+then a link to it would look like this:
+
+  L<somedoc/About the C<-M> Operator>
+
+Formatters may choose to ignore the markup for purposes of resolving
+the link and use only the renderable characters in the section name,
+as in:
+
+  <h1><a name="About_the_-M_Operator">About the <code>-M</code>
+  Operator</h1>
+  
+  ...
+  
+  <a href="somedoc#About_the_-M_Operator">About the <code>-M</code>
+  Operator" in somedoc</a>
+
+=item *
+
+Previous versions of perlpod distinguished C<LE<lt>name/"section"E<gt>>
+links from C<LE<lt>name/itemE<gt>> links (and their targets).  These
+have been merged syntactically and semantically in the current
+specification, and I<section> can refer either to a "=headI<n> Heading
+Content" command or to a "=item Item Content" command.  This
+specification does not specify what behavior should be in the case
+of a given document having several things all seeming to produce the
+same I<section> identifier (e.g., in HTML, several things all producing
+the same I<anchorname> in <a name="I<anchorname>">...</a>
+elements).  Where Pod processors can control this behavior, they should
+use the first such anchor.  That is, C<LE<lt>Foo/BarE<gt>> refers to the
+I<first> "Bar" section in Foo.
+
+But for some processors/formats this cannot be easily controlled; as
+with the HTML example, the behavior of multiple ambiguous
+<a name="I<anchorname>">...</a> is most easily just left up to
+browsers to decide.
+
+=item *
+
+Authors wanting to link to a particular (absolute) URL, must do so
+only with "LE<lt>scheme:...>" codes (like
+LE<lt>http://www.perl.org>), and must not attempt "LE<lt>Some Site
+Name|scheme:...>" codes.  This restriction avoids many problems
+in parsing and rendering LE<lt>...> codes.
+
+=item *
+
+In a C<LE<lt>text|...E<gt>> code, text may contain formatting codes
+for formatting or for EE<lt>...> escapes, as in:
+
+  L<B<ummE<234>stuff>|...>
+
+For C<LE<lt>...E<gt>> codes without a "name|" part, only
+C<EE<lt>...E<gt>> and C<ZE<lt>E<gt>> codes may occur -- no
+other formatting codes.  That is, authors should not use
+"C<LE<lt>BE<lt>Foo::BarE<gt>E<gt>>".
+
+Note, however, that formatting codes and ZE<lt>>'s can occur in any
+and all parts of an LE<lt>...> (i.e., in I<name>, I<section>, I<text>,
+and I<url>).
+
+Authors must not nest LE<lt>...> codes.  For example, "LE<lt>The
+LE<lt>Foo::Bar> man page>" should be treated as an error.
+
+=item *
+
+Note that Pod authors may use formatting codes inside the "text"
+part of "LE<lt>text|name>" (and so on for LE<lt>text|/"sec">).
+
+In other words, this is valid:
+
+  Go read L<the docs on C<$.>|perlvar/"$.">
+
+Some output formats that do allow rendering "LE<lt>...>" codes as
+hypertext, might not allow the link-text to be formatted; in
+that case, formatters will have to just ignore that formatting.
+
+=item *
+
+At time of writing, C<LE<lt>nameE<gt>> values are of two types:
+either the name of a Pod page like C<LE<lt>Foo::BarE<gt>> (which
+might be a real Perl module or program in an @INC / PATH
+directory, or a .pod file in those places); or the name of a UNIX
+man page, like C<LE<lt>crontab(5)E<gt>>.  In theory, C<LE<lt>chmodE<gt>>
+in ambiguous between a Pod page called "chmod", or the Unix man page
+"chmod" (in whatever man-section).  However, the presence of a string
+in parens, as in "crontab(5)", is sufficient to signal that what
+is being discussed is not a Pod page, and so is presumably a
+UNIX man page.  The distinction is of no importance to many
+Pod processors, but some processors that render to hypertext formats
+may need to distinguish them in order to know how to render a
+given C<LE<lt>fooE<gt>> code.
+
+=item *
+
+Previous versions of perlpod allowed for a C<LE<lt>sectionE<gt>> syntax
+(as in "C<LE<lt>Object AttributesE<gt>>"), which was not easily distinguishable
+from C<LE<lt>nameE<gt>> syntax.  This syntax is no longer in the
+specification, and has been replaced by the C<LE<lt>"section"E<gt>> syntax
+(where the quotes were formerly optional).  Pod parsers should tolerate
+the C<LE<lt>sectionE<gt>> syntax, for a while at least.  The suggested
+heuristic for distinguishing C<LE<lt>sectionE<gt>> from C<LE<lt>nameE<gt>>
+is that if it contains any whitespace, it's a I<section>.  Pod processors
+may warn about this being deprecated syntax.
+
+=back
+
+=head1 About =over...=back Regions
+
+"=over"..."=back" regions are used for various kinds of list-like
+structures.  (I use the term "region" here simply as a collective
+term for everything from the "=over" to the matching "=back".)
+
+=over
+
+=item *
+
+The non-zero numeric I<indentlevel> in "=over I<indentlevel>" ...
+"=back" is used for giving the formatter a clue as to how many
+"spaces" (ems, or roughly equivalent units) it should tab over,
+although many formatters will have to convert this to an absolute
+measurement that may not exactly match with the size of spaces (or M's)
+in the document's base font.  Other formatters may have to completely
+ignore the number.  The lack of any explicit I<indentlevel> parameter is
+equivalent to an I<indentlevel> value of 4.  Pod processors may
+complain if I<indentlevel> is present but is not a positive number
+matching C<m/\A(\d*\.)?\d+\z/>.
+
+=item *
+
+Authors of Pod formatters are reminded that "=over" ... "=back" may
+map to several different constructs in your output format.  For
+example, in converting Pod to (X)HTML, it can map to any of
+<ul>...</ul>, <ol>...</ol>, <dl>...</dl>, or
+<blockquote>...</blockquote>.  Similarly, "=item" can map to <li> or
+<dt>.
+
+=item *
+
+Each "=over" ... "=back" region should be one of the following:
+
+=over
+
+=item *
+
+An "=over" ... "=back" region containing only "=item *" commands,
+each followed by some number of ordinary/verbatim paragraphs, other
+nested "=over" ... "=back" regions, "=for..." paragraphs, and
+"=begin"..."=end" regions.
+
+(Pod processors must tolerate a bare "=item" as if it were "=item
+*".)  Whether "*" is rendered as a literal asterisk, an "o", or as
+some kind of real bullet character, is left up to the Pod formatter,
+and may depend on the level of nesting.
+
+=item *
+
+An "=over" ... "=back" region containing only
+C<m/\A=item\s+\d+\.?\s*\z/> paragraphs, each one (or each group of them)
+followed by some number of ordinary/verbatim paragraphs, other nested
+"=over" ... "=back" regions, "=for..." paragraphs, and/or
+"=begin"..."=end" codes.  Note that the numbers must start at 1
+in each section, and must proceed in order and without skipping
+numbers.
+
+(Pod processors must tolerate lines like "=item 1" as if they were
+"=item 1.", with the period.)
+
+=item *
+
+An "=over" ... "=back" region containing only "=item [text]"
+commands, each one (or each group of them) followed by some number of
+ordinary/verbatim paragraphs, other nested "=over" ... "=back"
+regions, or "=for..." paragraphs, and "=begin"..."=end" regions.
+
+The "=item [text]" paragraph should not match
+C<m/\A=item\s+\d+\.?\s*\z/> or C<m/\A=item\s+\*\s*\z/>, nor should it
+match just C<m/\A=item\s*\z/>.
+
+=item *
+
+An "=over" ... "=back" region containing no "=item" paragraphs at
+all, and containing only some number of 
+ordinary/verbatim paragraphs, and possibly also some nested "=over"
+... "=back" regions, "=for..." paragraphs, and "=begin"..."=end"
+regions.  Such an itemless "=over" ... "=back" region in Pod is
+equivalent in meaning to a "<blockquote>...</blockquote>" element in
+HTML.
+
+=back
+
+Note that with all the above cases, you can determine which type of
+"=over" ... "=back" you have, by examining the first (non-"=cut", 
+non-"=pod") Pod paragraph after the "=over" command.
+
+=item *
+
+Pod formatters I<must> tolerate arbitrarily large amounts of text
+in the "=item I<text...>" paragraph.  In practice, most such
+paragraphs are short, as in:
+
+  =item For cutting off our trade with all parts of the world
+
+But they may be arbitrarily long:
+
+  =item For transporting us beyond seas to be tried for pretended
+  offenses
+
+  =item He is at this time transporting large armies of foreign
+  mercenaries to complete the works of death, desolation and
+  tyranny, already begun with circumstances of cruelty and perfidy
+  scarcely paralleled in the most barbarous ages, and totally
+  unworthy the head of a civilized nation.
+
+=item *
+
+Pod processors should tolerate "=item *" / "=item I<number>" commands
+with no accompanying paragraph.  The middle item is an example:
+
+  =over
+  
+  =item 1
+  
+  Pick up dry cleaning.
+  
+  =item 2
+  
+  =item 3
+  
+  Stop by the store.  Get Abba Zabas, Stoli, and cheap lawn chairs.
+  
+  =back
+
+=item *
+
+No "=over" ... "=back" region can contain headings.  Processors may
+treat such a heading as an error.
+
+=item *
+
+Note that an "=over" ... "=back" region should have some
+content.  That is, authors should not have an empty region like this:
+
+  =over
+  
+  =back
+
+Pod processors seeing such a contentless "=over" ... "=back" region,
+may ignore it, or may report it as an error.
+
+=item *
+
+Processors must tolerate an "=over" list that goes off the end of the
+document (i.e., which has no matching "=back"), but they may warn
+about such a list.
+
+=item *
+
+Authors of Pod formatters should note that this construct:
+
+  =item Neque
+
+  =item Porro
+
+  =item Quisquam Est
+  
+  Qui dolorem ipsum quia dolor sit amet, consectetur, adipisci 
+  velit, sed quia non numquam eius modi tempora incidunt ut
+  labore et dolore magnam aliquam quaerat voluptatem.
+
+  =item Ut Enim
+
+is semantically ambiguous, in a way that makes formatting decisions
+a bit difficult.  On the one hand, it could be mention of an item
+"Neque", mention of another item "Porro", and mention of another
+item "Quisquam Est", with just the last one requiring the explanatory
+paragraph "Qui dolorem ipsum quia dolor..."; and then an item
+"Ut Enim".  In that case, you'd want to format it like so:
+
+  Neque
+  
+  Porro
+  
+  Quisquam Est
+    Qui dolorem ipsum quia dolor sit amet, consectetur, adipisci
+    velit, sed quia non numquam eius modi tempora incidunt ut
+    labore et dolore magnam aliquam quaerat voluptatem.
+
+  Ut Enim
+
+But it could equally well be a discussion of three (related or equivalent)
+items, "Neque", "Porro", and "Quisquam Est", followed by a paragraph
+explaining them all, and then a new item "Ut Enim".  In that case, you'd
+probably want to format it like so:
+
+  Neque
+  Porro
+  Quisquam Est
+    Qui dolorem ipsum quia dolor sit amet, consectetur, adipisci
+    velit, sed quia non numquam eius modi tempora incidunt ut
+    labore et dolore magnam aliquam quaerat voluptatem.
+
+  Ut Enim
+
+But (for the forseeable future), Pod does not provide any way for Pod
+authors to distinguish which grouping is meant by the above
+"=item"-cluster structure.  So formatters should format it like so:
+
+  Neque
+
+  Porro
+
+  Quisquam Est
+
+    Qui dolorem ipsum quia dolor sit amet, consectetur, adipisci
+    velit, sed quia non numquam eius modi tempora incidunt ut
+    labore et dolore magnam aliquam quaerat voluptatem.
+
+  Ut Enim
+
+That is, there should be (at least roughtly) equal spacing between
+items as between paragraphs (although that spacing may well be less
+than the full height of a line of text).  This leaves it to the reader
+to use (con)textual cues to figure out whether the "Qui dolorem
+ipsum..." paragraph applies to the "Quisquam Est" item or to all three
+items "Neque", "Porro", and "Quisquam Est".  While not an ideal
+situation, this is preferable to providing formatting cues that may
+be actually contrary to the author's intent.
+
+=back
+
+
+
+=head1 About Data Paragraphs and "=begin/=end" Regions
+
+Data paragraphs are typically used for inlining non-Pod data that is
+to be used (typically passed through) when rendering the document to
+a specific format:
+
+  =begin rtf
+  
+  \par{\pard\qr\sa4500{\i Printed\~\chdate\~\chtime}\par}
+  
+  =end rtf
+
+The exact same effect could, incidentally, be achieved with a single
+"=for" paragraph:
+
+  =for rtf \par{\pard\qr\sa4500{\i Printed\~\chdate\~\chtime}\par}
+
+(Although that is not formally a data paragraph, it has the same
+meaning as one, and Pod parsers may parse it as one.)
+
+Another example of a data paragraph:
+
+  =begin html
+  
+  I like <em>PIE</em>!
+  
+  <hr>Especially pecan pie!
+  
+  =end html
+
+If these were ordinary paragraphs, the Pod parser would try to
+expand the "EE<lt>/em>" (in the first paragraph) as a formatting
+code, just like "EE<lt>lt>" or "EE<lt>eacute>".  But since this
+is in a "=begin I<identifier>"..."=end I<identifier>" region I<and>
+the identifier "html" doesn't begin have a ":" prefix, the contents
+of this region are stored as data paragraphs, instead of being
+processed as ordinary paragraphs (or if they began with a spaces
+and/or tabs, as verbatim paragraphs).
+
+As a further example: At time of writing, no "biblio" identifier is
+supported, but suppose some processor were written to recognize it as
+a way of (say) denoting a bibliographic reference (necessarily
+containing formatting codes in ordinary paragraphs).  The fact that
+"biblio" paragraphs were meant for ordinary processing would be
+indicated by prefacing each "biblio" identifier with a colon:
+
+  =begin :biblio
+
+  Wirth, Niklaus.  1976.  I<Algorithms + Data Structures =
+  Programs.>  Prentice-Hall, Englewood Cliffs, NJ.
+
+  =end :biblio
+
+This would signal to the parser that paragraphs in this begin...end
+region are subject to normal handling as ordinary/verbatim paragraphs
+(while still tagged as meant only for processors that understand the
+"biblio" identifier).  The same effect could be had with:
+
+  =for :biblio
+  Wirth, Niklaus.  1976.  I<Algorithms + Data Structures =
+  Programs.>  Prentice-Hall, Englewood Cliffs, NJ.
+
+The ":" on these identifiers means simply "process this stuff
+normally, even though the result will be for some special target".
+I suggest that parser APIs report "biblio" as the target identifier,
+but also report that it had a ":" prefix.  (And similarly, with the
+above "html", report "html" as the target identifier, and note the
+I<lack> of a ":" prefix.)
+
+Note that a "=begin I<identifier>"..."=end I<identifier>" region where
+I<identifier> begins with a colon, I<can> contain commands.  For example:
+
+  =begin :biblio
+  
+  Wirth's classic is available in several editions, including:
+  
+  =for comment
+   hm, check abebooks.com for how much used copies cost.
+  
+  =over
+  
+  =item
+  
+  Wirth, Niklaus.  1975.  I<Algorithmen und Datenstrukturen.>
+  Teubner, Stuttgart.  [Yes, it's in German.]
+  
+  =item
+  
+  Wirth, Niklaus.  1976.  I<Algorithms + Data Structures =
+  Programs.>  Prentice-Hall, Englewood Cliffs, NJ.
+  
+  =back
+  
+  =end :biblio
+
+Note, however, a "=begin I<identifier>"..."=end I<identifier>"
+region where I<identifier> does I<not> begin with a colon, should not
+directly contain "=head1" ... "=head4" commands, nor "=over", nor "=back",
+nor "=item".  For example, this may be considered invalid:
+
+  =begin somedata
+  
+  This is a data paragraph.
+  
+  =head1 Don't do this!
+  
+  This is a data paragraph too.
+  
+  =end somedata
+
+A Pod processor may signal that the above (specifically the "=head1"
+paragraph) is an error.  Note, however, that the following should
+I<not> be treated as an error:
+
+  =begin somedata
+  
+  This is a data paragraph.
+  
+  =cut
+  
+  # Yup, this isn't Pod anymore.
+  sub excl { (rand() > .5) ? "hoo!" : "hah!" }
+  
+  =pod
+  
+  This is a data paragraph too.
+  
+  =end somedata
+
+And this too is valid:
+
+  =begin someformat
+  
+  This is a data paragraph.
+  
+    And this is a data paragraph.
+  
+  =begin someotherformat
+  
+  This is a data paragraph too.
+  
+    And this is a data paragraph too.
+  
+  =begin :yetanotherformat
+
+  =head2 This is a command paragraph!
+
+  This is an ordinary paragraph!
+  
+    And this is a verbatim paragraph!
+  
+  =end :yetanotherformat
+  
+  =end someotherformat
+  
+  Another data paragraph!
+  
+  =end someformat
+
+The contents of the above "=begin :yetanotherformat" ...
+"=end :yetanotherformat" region I<aren't> data paragraphs, because
+the immediately containing region's identifier (":yetanotherformat")
+begins with a colon.  In practice, most regions that contain
+data paragraphs will contain I<only> data paragraphs; however, 
+the above nesting is syntactically valid as Pod, even if it is
+rare.  However, the handlers for some formats, like "html",
+will accept only data paragraphs, not nested regions; and they may
+complain if they see (targeted for them) nested regions, or commands,
+other than "=end", "=pod", and "=cut".
+
+Also consider this valid structure:
+
+  =begin :biblio
+  
+  Wirth's classic is available in several editions, including:
+  
+  =over
+  
+  =item
+  
+  Wirth, Niklaus.  1975.  I<Algorithmen und Datenstrukturen.>
+  Teubner, Stuttgart.  [Yes, it's in German.]
+  
+  =item
+  
+  Wirth, Niklaus.  1976.  I<Algorithms + Data Structures =
+  Programs.>  Prentice-Hall, Englewood Cliffs, NJ.
+
+  =back
+  
+  Buy buy buy!
+  
+  =begin html
+  
+  <img src='wirth_spokesmodeling_book.png'>
+  
+  <hr>
+  
+  =end html
+  
+  Now now now!
+  
+  =end :biblio
+
+There, the "=begin html"..."=end html" region is nested inside
+the larger "=begin :biblio"..."=end :biblio" region.  Note that the
+content of the "=begin html"..."=end html" region is data
+paragraph(s), because the immediately containing region's identifier
+("html") I<doesn't> begin with a colon.
+
+Pod parsers, when processing a series of data paragraphs one
+after another (within a single region), should consider them to
+be one large data paragraph that happens to contain blank lines.  So
+the content of the above "=begin html"..."=end html" I<may> be stored
+as two data paragraphs (one consisting of
+"<img src='wirth_spokesmodeling_book.png'>\n"
+and another consisting of "<hr>\n"), but I<should> be stored as
+a single data paragraph (consisting of 
+"<img src='wirth_spokesmodeling_book.png'>\n\n<hr>\n").
+
+Pod processors should tolerate empty
+"=begin I<something>"..."=end I<something>" regions,
+empty "=begin :I<something>"..."=end :I<something>" regions, and
+contentless "=for I<something>" and "=for :I<something>"
+paragraphs.  I.e., these should be tolerated:
+
+  =for html
+  
+  =begin html
+  
+  =end html
+  
+  =begin :biblio
+  
+  =end :biblio
+
+Incidentally, note that there's no easy way to express a data
+paragraph starting with something that looks like a command.  Consider:
+
+  =begin stuff
+  
+  =shazbot
+  
+  =end stuff
+
+There, "=shazbot" will be parsed as a Pod command "shazbot", not as a data
+paragraph "=shazbot\n".  However, you can express a data paragraph consisting
+of "=shazbot\n" using this code:
+
+  =for stuff =shazbot
+
+The situation where this is necessary, is presumably quite rare.
+
+Note that =end commands must match the currently open =begin command.  That
+is, they must properly nest.  For example, this is valid:
+
+  =begin outer
+  
+  X
+  
+  =begin inner
+  
+  Y
+  
+  =end inner
+  
+  Z
+  
+  =end outer
+
+while this is invalid:
+
+  =begin outer
+  
+  X
+  
+  =begin inner
+  
+  Y
+  
+  =end outer
+  
+  Z
+  
+  =end inner
+  
+This latter is improper because when the "=end outer" command is seen, the
+currently open region has the formatname "inner", not "outer".  (It just
+happens that "outer" is the format name of a higher-up region.)  This is
+an error.  Processors must by default report this as an error, and may halt
+processing the document containing that error.  A corrolary of this is that
+regions cannot "overlap" -- i.e., the latter block above does not represent
+a region called "outer" which contains X and Y, overlapping a region called
+"inner" which contains Y and Z.  But because it is invalid (as all
+apparently overlapping regions would be), it doesn't represent that, or
+anything at all.
+
+Similarly, this is invalid:
+
+  =begin thing
+  
+  =end hting
+
+This is an error because the region is opened by "thing", and the "=end"
+tries to close "hting" [sic].
+
+This is also invalid:
+
+  =begin thing
+  
+  =end
+
+This is invalid because every "=end" command must have a formatname
+parameter.
+
+=head1 SEE ALSO
+
+L<perlpod>, L<perlsyn/"PODs: Embedded Documentation">,
+L<podchecker>
+
+=head1 AUTHOR
+
+Sean M. Burke
+
+=cut
+
+
index 3ad81d4..859c2a4 100644 (file)
@@ -642,7 +642,7 @@ more elaborate constructs
 
 =back
 
-=head2 perlpod - plain old documentation
+=head2 perlpod - the Plain Old Documentation format
 
 =over 4
 
@@ -650,20 +650,73 @@ more elaborate constructs
 
 =over 4
 
+=item Ordinary Paragraph
+
 =item Verbatim Paragraph
 
 =item Command Paragraph
 
-=item Ordinary Block of Text
+C<=head1 I<Heading Text>>, C<=head2 I<Heading Text>>, C<=head3 I<Heading
+Text>>, C<=head4 I<Heading Text>>, C<=over I<indentlevel>>, C<=item
+I<stuff...>>, C<=back>, C<=cut>, C<=pod>, C<=begin I<formatname>>, C<=end
+I<formatname>>, C<=for I<formatname> I<text...>>
+
+=item Formatting Codes
+
+C<IE<lt>textE<gt>> -- italic text, C<BE<lt>textE<gt>> -- bold text,
+C<CE<lt>codeE<gt>> -- code text, C<LE<lt>nameE<gt>> -- a hyperlink,
+C<EE<lt>escapeE<gt>> -- a character escape, C<FE<lt>filenameE<gt>> -- used
+for filenames, C<SE<lt>textE<gt>> -- text contains non-breaking spaces,
+C<XE<lt>topic nameE<gt>> -- an index entry, C<ZE<lt>E<gt>> -- a null
+(zero-effect) formatting code
 
 =item The Intent
 
 =item Embedding Pods in Perl Modules
 
-=item Common Pod Pitfalls
+=item Hints for Writing Pod
+
+=back
+
+=item SEE ALSO
+
+=item AUTHOR
 
 =back
 
+=head2 perlpodspec - Plain Old Documentation: format specification and
+notes
+
+=over 4
+
+=item DESCRIPTION
+
+=item Pod Definitions
+
+=item Pod Commands
+
+"=head1", "=head2", "=head3", "=head4", "=pod", "=cut", "=over", "=item",
+"=back", "=begin formatname", "=end formatname", "=for formatname text..."
+
+=item Pod Formatting Codes
+
+C<IE<lt>textE<gt>> -- italic text, C<BE<lt>textE<gt>> -- bold text,
+C<CE<lt>codeE<gt>> -- code text, C<FE<lt>filenameE<gt>> -- style for
+filenames, C<XE<lt>topic nameE<gt>> -- an index entry, C<ZE<lt>E<gt>> -- a
+null (zero-effect) formatting code, C<LE<lt>nameE<gt>> -- a hyperlink,
+C<EE<lt>escapeE<gt>> -- a character escape, C<SE<lt>textE<gt>> -- text
+contains non-breaking spaces
+
+=item Notes on Implementing Pod Processors
+
+=item About LE<lt>...E<gt> Codes
+
+First:, Second:, Third:, Fourth:, Fifth:, Sixth:
+
+=item About =over...=back Regions
+
+=item About Data Paragraphs and "=begin/=end" Regions
+
 =item SEE ALSO
 
 =item AUTHOR
index 6bd0423..9b4d2e3 100644 (file)
@@ -254,7 +254,8 @@ The following reserved ranges have C<In> tests:
     Plane 16 Private Use
 
 For example C<"\x{AC00}" =~ \p{HangulSyllable}> will test true.
-(Handling of surrogates is not implemented yet.)
+(Handling of surrogates is not implemented yet, because Perl
+uses UTF-8 and not UTF-16 internally to represent Unicode.)
 
 Additionally, because scripts differ in their directionality
 (for example Hebrew is written right to left), all characters
@@ -285,66 +286,66 @@ have their directionality defined:
 The scripts available for C<\p{In...}> and C<\P{In...}>, for example
 \p{InCyrillic>, are as follows, for example C<\p{InLatin}> or C<\P{InHan}>:
 
-    Latin
-    Greek
-    Cyrillic
-    Armenian
-    Hebrew
     Arabic
-    Syriac
-    Thaana
-    Devanagari
+    Armenian
     Bengali
-    Gurmukhi
+    Bopomofo
+    Canadian-Aboriginal
+    Cherokee
+    Cyrillic
+    Deseret
+    Devanagari
+    Ethiopic
+    Georgian
+    Gothic
+    Greek
     Gujarati
-    Oriya
-    Tamil
-    Telugu
+    Gurmukhi
+    Han
+    Hangul
+    Hebrew
+    Hiragana
+    Inherited
     Kannada
-    Malayalam
-    Sinhala
-    Thai
+    Katakana
+    Khmer
     Lao
-    Tibetan
+    Latin
+    Malayalam
+    Mongolian
     Myanmar
-    Georgian
-    Hangul
-    Ethiopic
-    Cherokee
-    Canadian Aboriginal
     Ogham
+    Old-Italic
+    Oriya
     Runic
-    Khmer
-    Mongolian
-    Hiragana
-    Katakana
-    Bopomofo
-    Han
+    Sinhala
+    Syriac
+    Tamil
+    Telugu
+    Thaana
+    Thai
+    Tibetan
     Yi
-    Old Italic
-    Gothic
-    Deseret
-    Inherited
 
 There are also extended property classes that supplement the basic
 properties, defined by the F<PropList> Unicode database:
 
-    White_space
+    ASCII_Hex_Digit
     Bidi_Control
-    Join_Control
     Dash
-    Hyphen
-    Quotation_Mark
-    Other_Math
-    Hex_Digit
-    ASCII_Hex_Digit
-    Other_Alphabetic
-    Ideographic
     Diacritic
     Extender
+    Hex_Digit
+    Hyphen
+    Ideographic
+    Join_Control
+    Noncharacter_Code_Point
+    Other_Alphabetic
     Other_Lowercase
+    Other_Math
     Other_Uppercase
-    Noncharacter_Code_Point
+    Quotation_Mark
+    White_space
 
 and further derived properties:
 
@@ -365,11 +366,14 @@ and further derived properties:
 
 In addition to B<scripts>, Unicode also defines B<blocks> of
 characters.  The difference between scripts and blocks is that the
-former concept is closer to natural languages, while the latter
+scripts concept is closer to natural languages, while the blocks
 concept is more an artificial grouping based on groups of 256 Unicode
 characters.  For example, the C<Latin> script contains letters from
-many blocks, but it does not contain all the characters from those
-blocks, it does not for example contain digits.
+many blocks.  On the other hand, the C<Latin> script does not contain
+all the characters from those blocks, it does not for example contain
+digits because digits are shared across many scripts.  Digits and
+other similar groups, like punctuation, are in a category called
+C<Common>.
 
 For more about scripts see the UTR #24:
 http://www.unicode.org/unicode/reports/tr24/
@@ -386,102 +390,102 @@ preferential Unicode character class definition; this meant that
 the definitions of some character classes changed (the ones in the
 below list that have the C<Block> appended).
 
+   Alphabetic Presentation Forms
+   Arabic Block
+   Arabic Presentation Forms-A
+   Arabic Presentation Forms-B
+   Armenian Block
+   Arrows
    Basic Latin
-   Latin 1 Supplement
-   Latin Extended-A
-   Latin Extended-B
-   IPA Extensions
-   Spacing Modifier Letters
+   Bengali Block
+   Block Elements
+   Bopomofo Block
+   Bopomofo Extended
+   Box Drawing
+   Braille Patterns
+   Byzantine Musical Symbols
+   CJK Compatibility
+   CJK Compatibility Forms
+   CJK Compatibility Ideographs
+   CJK Compatibility Ideographs Supplement
+   CJK Radicals Supplement
+   CJK Symbols and Punctuation
+   CJK Unified Ideographs
+   CJK Unified Ideographs Extension A
+   CJK Unified Ideographs Extension B
+   Cherokee Block
    Combining Diacritical Marks
-   Greek Block
+   Combining Half Marks
+   Combining Marks for Symbols
+   Control Pictures
+   Currency Symbols
    Cyrillic Block
-   Armenian Block
-   Hebrew Block
-   Arabic Block
-   Syriac Block
-   Thaana Block
+   Deseret Block
    Devanagari Block
-   Bengali Block
-   Gurmukhi Block
-   Gujarati Block
-   Oriya Block
-   Tamil Block
-   Telugu Block
-   Kannada Block
-   Malayalam Block
-   Sinhala Block
-   Thai Block
-   Lao Block
-   Tibetan Block
-   Myanmar Block
+   Dingbats
+   Enclosed Alphanumerics
+   Enclosed CJK Letters and Months
+   Ethiopic Block
+   General Punctuation
+   Geometric Shapes
    Georgian Block
+   Gothic Block
+   Greek Block
+   Greek Extended
+   Gujarati Block
+   Gurmukhi Block
+   Halfwidth and Fullwidth Forms
+   Hangul Compatibility Jamo
    Hangul Jamo
-   Ethiopic Block
-   Cherokee Block
-   Unified Canadian Aboriginal Syllabics
-   Ogham Block
-   Runic Block
+   Hangul Syllables
+   Hebrew Block
+   High Private Use Surrogates
+   High Surrogates
+   Hiragana Block
+   IPA Extensions
+   Ideographic Description Characters
+   Kanbun
+   Kangxi Radicals
+   Kannada Block
+   Katakana Block
    Khmer Block
-   Mongolian Block
+   Lao Block
+   Latin 1 Supplement
    Latin Extended Additional
-   Greek Extended
-   General Punctuation
-   Superscripts and Subscripts
-   Currency Symbols
-   Combining Marks for Symbols
+   Latin Extended-A
+   Latin Extended-B
    Letterlike Symbols
-   Number Forms
-   Arrows
+   Low Surrogates
+   Malayalam Block
+   Mathematical Alphanumeric Symbols
    Mathematical Operators
+   Miscellaneous Symbols
    Miscellaneous Technical
-   Control Pictures
+   Mongolian Block
+   Musical Symbols
+   Myanmar Block
+   Number Forms
+   Ogham Block
+   Old Italic Block
    Optical Character Recognition
-   Enclosed Alphanumerics
-   Box Drawing
-   Block Elements
-   Geometric Shapes
-   Miscellaneous Symbols
-   Dingbats
-   Braille Patterns
-   CJK Radicals Supplement
-   Kangxi Radicals
-   Ideographic Description Characters
-   CJK Symbols and Punctuation
-   Hiragana Block
-   Katakana Block
-   Bopomofo Block
-   Hangul Compatibility Jamo
-   Kanbun
-   Bopomofo Extended
-   Enclosed CJK Letters and Months
-   CJK Compatibility
-   CJK Unified Ideographs Extension A
-   CJK Unified Ideographs
-   Yi Syllables
-   Yi Radicals
-   Hangul Syllables
-   High Surrogates
-   High Private Use Surrogates
-   Low Surrogates
+   Oriya Block
    Private Use
-   CJK Compatibility Ideographs
-   Alphabetic Presentation Forms
-   Arabic Presentation Forms-A
-   Combining Half Marks
-   CJK Compatibility Forms
+   Runic Block
+   Sinhala Block
    Small Form Variants
-   Arabic Presentation Forms-B
+   Spacing Modifier Letters
    Specials
-   Halfwidth and Fullwidth Forms
-   Old Italic Block
-   Gothic Block
-   Deseret Block
-   Byzantine Musical Symbols
-   Musical Symbols
-   Mathematical Alphanumeric Symbols
-   CJK Unified Ideographs Extension B
-   CJK Compatibility Ideographs Supplement
+   Superscripts and Subscripts
+   Syriac Block
    Tags
+   Tamil Block
+   Telugu Block
+   Thaana Block
+   Thai Block
+   Tibetan Block
+   Unified Canadian Aboriginal Syllabics
+   Yi Radicals
+   Yi Syllables
 
 =item *
 
@@ -548,15 +552,37 @@ wide bit complement.
 
 =item *
 
-lc(), uc(), lcfirst(), and ucfirst() work only for some of the
-simplest cases, where the mapping goes from a single Unicode character
-to another single Unicode character, and where the mapping does not
-depend on surrounding characters, or on locales.  More complex cases,
-where for example one character maps into several, are not yet
-implemented.  See the Unicode Technical Report #21, Case Mappings,
-for more details.  The Unicode::UCD module (part of Perl since 5.8.0)
-casespec() and casefold() interfaces supply information about the more
-complex cases.
+lc(), uc(), lcfirst(), and ucfirst() work for the following cases:
+
+=over 8
+
+=item *
+
+the case mapping is from a single Unicode character to another
+single Unicode character
+
+=item *
+
+the case mapping is from a single Unicode character to more
+than one Unicode character
+
+=back
+
+What doesn't yet work are the followng cases:
+
+=over 8
+
+=item *
+
+the "final sigma" (Greek)
+
+=item *
+
+anything to with locales (Lithuanian, Turkish, Azeri)
+
+=back
+
+See the Unicode Technical Report #21, Case Mappings, for more details.
 
 =item *
 
diff --git a/proto.h b/proto.h
index ff3ac5f..b56817a 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -797,6 +797,7 @@ PERL_CALLCONV SV*   Perl_swash_init(pTHX_ char* pkg, char* name, SV* listsv, I32 m
 PERL_CALLCONV UV       Perl_swash_fetch(pTHX_ SV *sv, U8 *ptr, bool do_utf8);
 PERL_CALLCONV void     Perl_taint_env(pTHX);
 PERL_CALLCONV void     Perl_taint_proper(pTHX_ const char* f, const char* s);
+PERL_CALLCONV UV       Perl_to_utf8_case(pTHX_ U8 *p, U8* ustrp, STRLEN *lenp, SV **swash, char *normal, char *special);
 PERL_CALLCONV UV       Perl_to_utf8_lower(pTHX_ U8 *p, U8* ustrp, STRLEN *lenp);
 PERL_CALLCONV UV       Perl_to_utf8_upper(pTHX_ U8 *p, U8* ustrp, STRLEN *lenp);
 PERL_CALLCONV UV       Perl_to_utf8_title(pTHX_ U8 *p, U8* ustrp, STRLEN *lenp);
index 2d347b8..0deabb2 100644 (file)
@@ -84,8 +84,17 @@ looking at magic, or by checking if it is tied again threads::shared.
 shared_sv *
 Perl_sharedsv_find(pTHX_ SV* sv)
 {
-    /* does all it can to find a shared_sv struct, returns NULL otherwise */
-    shared_sv* ssv = NULL;
+  /* does all it can to find a shared_sv struct, returns NULL otherwise */
+    shared_sv* ssv = NULL; 
+    switch (SvTYPE(sv)) {
+        case SVt_PVMG:
+            {MAGIC* mg = mg_find(sv, PERL_MAGIC_ext);
+            
+            if(strcmp(mg->mg_ptr,"threads::shared"))
+                break;
+            ssv = (shared_sv*) SvIV(mg->mg_obj);
+           }
+    }            
     return ssv;
 }
 
@@ -164,9 +173,9 @@ Increments the threadcount of a sharedsv.
 void
 Perl_sharedsv_thrcnt_inc(pTHX_ shared_sv* ssv)
 {
-  SHAREDSvEDIT(ssv);
+  SHAREDSvLOCK(ssv);
   SvREFCNT_inc(ssv->sv);
-  SHAREDSvRELEASE(ssv);
+  SHAREDSvUNLOCK(ssv);
 }
 
 /*
@@ -182,7 +191,7 @@ void
 Perl_sharedsv_thrcnt_dec(pTHX_ shared_sv* ssv)
 {
     SV* sv;
-    SHAREDSvEDIT(ssv);
+    SHAREDSvLOCK(ssv);
     sv = SHAREDSvGET(ssv);
     if (SvREFCNT(sv) == 1) {
         switch (SvTYPE(sv)) {
@@ -211,8 +220,8 @@ Perl_sharedsv_thrcnt_dec(pTHX_ shared_sv* ssv)
         }
         }
     }
-    SvREFCNT_dec(sv);
-    SHAREDSvRELEASE(ssv);
+    Perl_sv_free(PL_sharedsv_space,SHAREDSvGET(ssv));
+    SHAREDSvUNLOCK(ssv);
 }
 
 #endif /* USE_ITHREADS */
index 2db3a8a..9333c6c 100644 (file)
--- a/t/op/lc.t
+++ b/t/op/lc.t
@@ -1,59 +1,93 @@
 #!./perl
 
-print "1..40\n";
+print "1..42\n";
+
+my $test = 1;
+
+sub ok {
+    if ($_[0]) {
+       if ($_[1]) {
+           print "ok $test - $_[1]\n";
+       } else {
+           print "ok $test\n";
+       }
+    } else {
+       if ($_[1]) {
+           print "not ok $test - $_[1]\n";
+       } else {
+           print "not ok $test\n";
+       }
+    }
+    $test++;
+}
 
 $a = "HELLO.* world";
 $b = "hello.* WORLD";
 
-print "ok 1\n"  if "\Q$a\E."      eq "HELLO\\.\\*\\ world.";
-print "ok 2\n"  if "\u$a"         eq "HELLO\.\* world";
-print "ok 3\n"  if "\l$a"         eq "hELLO\.\* world";
-print "ok 4\n"  if "\U$a"         eq "HELLO\.\* WORLD";
-print "ok 5\n"  if "\L$a"         eq "hello\.\* world";
-
-print "ok 6\n"  if quotemeta($a)  eq "HELLO\\.\\*\\ world";
-print "ok 7\n"  if ucfirst($a)    eq "HELLO\.\* world";
-print "ok 8\n"  if lcfirst($a)    eq "hELLO\.\* world";
-print "ok 9\n"  if uc($a)         eq "HELLO\.\* WORLD";
-print "ok 10\n" if lc($a)         eq "hello\.\* world";
-
-print "ok 11\n"  if "\Q$b\E."     eq "hello\\.\\*\\ WORLD.";
-print "ok 12\n"  if "\u$b"        eq "Hello\.\* WORLD";
-print "ok 13\n"  if "\l$b"        eq "hello\.\* WORLD";
-print "ok 14\n"  if "\U$b"        eq "HELLO\.\* WORLD";
-print "ok 15\n"  if "\L$b"        eq "hello\.\* world";
-
-print "ok 16\n"  if quotemeta($b) eq "hello\\.\\*\\ WORLD";
-print "ok 17\n"  if ucfirst($b)   eq "Hello\.\* WORLD";
-print "ok 18\n"  if lcfirst($b)   eq "hello\.\* WORLD";
-print "ok 19\n"  if uc($b)        eq "HELLO\.\* WORLD";
-print "ok 20\n"  if lc($b)        eq "hello\.\* world";
+ok("\Q$a\E."      eq "HELLO\\.\\*\\ world.", '\Q\E HELLO.* world');
+ok("\u$a"         eq "HELLO\.\* world",      '\u');
+ok("\l$a"         eq "hELLO\.\* world",      '\l');
+ok("\U$a"         eq "HELLO\.\* WORLD",      '\U');
+ok("\L$a"         eq "hello\.\* world",      '\L');
+
+ok(quotemeta($a)  eq "HELLO\\.\\*\\ world",  'quotemeta');
+ok(ucfirst($a)    eq "HELLO\.\* world",      'ucfirst');
+ok(lcfirst($a)    eq "hELLO\.\* world",      'lcfirst');
+ok(uc($a)         eq "HELLO\.\* WORLD",      'uc');
+ok(lc($a)         eq "hello\.\* world",      'lc');
+
+ok("\Q$b\E."      eq "hello\\.\\*\\ WORLD.", '\Q\E hello.* WORLD');
+ok("\u$b"         eq "Hello\.\* WORLD",      '\u');
+ok("\l$b"         eq "hello\.\* WORLD",      '\l');
+ok("\U$b"         eq "HELLO\.\* WORLD",      '\U');
+ok("\L$b"         eq "hello\.\* world",      '\L');
+
+ok(quotemeta($b)  eq "hello\\.\\*\\ WORLD",  'quotemeta');
+ok(ucfirst($b)    eq "Hello\.\* WORLD",      'ucfirst');
+ok(lcfirst($b)    eq "hello\.\* WORLD",      'lcfirst');
+ok(uc($b)         eq "HELLO\.\* WORLD",      'uc');
+ok(lc($b)         eq "hello\.\* world",      'lc');
+
+# \x{100} is LATIN CAPITAL LETTER A WITH MACRON; its bijective lowercase is
+# \x{100}, LATIN SMALL LETTER A WITH MACRON.
 
 $a = "\x{100}\x{101}\x{41}\x{61}";
 $b = "\x{101}\x{100}\x{61}\x{41}";
 
-print "ok 21\n" if "\Q$a\E."      eq "\x{100}\x{101}\x{41}\x{61}.";
-print "ok 22\n" if "\u$a"         eq "\x{100}\x{101}\x{41}\x{61}";
-print "ok 23\n" if "\l$a"         eq "\x{101}\x{101}\x{41}\x{61}";
-print "ok 24\n" if "\U$a"         eq "\x{100}\x{100}\x{41}\x{41}";
-print "ok 25\n" if "\L$a"         eq "\x{101}\x{101}\x{61}\x{61}";
-
-print "ok 26\n" if quotemeta($a)  eq "\x{100}\x{101}\x{41}\x{61}";
-print "ok 27\n" if ucfirst($a)    eq "\x{100}\x{101}\x{41}\x{61}";
-print "ok 28\n" if lcfirst($a)    eq "\x{101}\x{101}\x{41}\x{61}";
-print "ok 29\n" if uc($a)         eq "\x{100}\x{100}\x{41}\x{41}";
-print "ok 30\n" if lc($a)         eq "\x{101}\x{101}\x{61}\x{61}";
-
-print "ok 31\n" if "\Q$b\E."      eq "\x{101}\x{100}\x{61}\x{41}.";
-print "ok 32\n" if "\u$b"         eq "\x{100}\x{100}\x{61}\x{41}";
-print "ok 33\n" if "\l$b"         eq "\x{101}\x{100}\x{61}\x{41}";
-print "ok 34\n" if "\U$b"         eq "\x{100}\x{100}\x{41}\x{41}";
-print "ok 35\n" if "\L$b"         eq "\x{101}\x{101}\x{61}\x{61}";
-
-print "ok 36\n"  if quotemeta($b) eq "\x{101}\x{100}\x{61}\x{41}";
-print "ok 37\n"  if ucfirst($b)   eq "\x{100}\x{100}\x{61}\x{41}";
-print "ok 38\n"  if lcfirst($b)   eq "\x{101}\x{100}\x{61}\x{41}";
-print "ok 39\n"  if uc($b)        eq "\x{100}\x{100}\x{41}\x{41}";
-print "ok 40\n"  if lc($b)        eq "\x{101}\x{101}\x{61}\x{61}";
+ok("\Q$a\E."      eq "\x{100}\x{101}\x{41}\x{61}.", '\Q\E \x{100}\x{101}\x{41}\x{61}');
+ok("\u$a"         eq "\x{100}\x{101}\x{41}\x{61}",  '\u');
+ok("\l$a"         eq "\x{101}\x{101}\x{41}\x{61}",  '\l');
+ok("\U$a"         eq "\x{100}\x{100}\x{41}\x{41}",  '\U');
+ok("\L$a"         eq "\x{101}\x{101}\x{61}\x{61}",  '\L');
+
+ok(quotemeta($a)  eq "\x{100}\x{101}\x{41}\x{61}",  'quotemeta');
+ok(ucfirst($a)    eq "\x{100}\x{101}\x{41}\x{61}",  'ucfirst');
+ok(lcfirst($a)    eq "\x{101}\x{101}\x{41}\x{61}",  'lcfirst');
+ok(uc($a)         eq "\x{100}\x{100}\x{41}\x{41}",  'uc');
+ok(lc($a)         eq "\x{101}\x{101}\x{61}\x{61}",  'lc');
+
+ok("\Q$b\E."      eq "\x{101}\x{100}\x{61}\x{41}.", '\Q\E \x{101}\x{100}\x{61}\x{41}');
+ok("\u$b"         eq "\x{100}\x{100}\x{61}\x{41}",  '\u');
+ok("\l$b"         eq "\x{101}\x{100}\x{61}\x{41}",  '\l');
+ok("\U$b"         eq "\x{100}\x{100}\x{41}\x{41}",  '\U');
+ok("\L$b"         eq "\x{101}\x{101}\x{61}\x{61}",  '\L');
+
+ok(quotemeta($b)  eq "\x{101}\x{100}\x{61}\x{41}",  'quotemeta');
+ok(ucfirst($b)    eq "\x{100}\x{100}\x{61}\x{41}",  'ucfirst');
+ok(lcfirst($b)    eq "\x{101}\x{100}\x{61}\x{41}",  'lcfirst');
+ok(uc($b)         eq "\x{100}\x{100}\x{41}\x{41}",  'uc');
+ok(lc($b)         eq "\x{101}\x{101}\x{61}\x{61}",  'lc');
+
+# \x{DF} is LATIN SMALL LETTER SHARP S, its uppercase is SS or \x{53}\x{53};
+# \x{149} is LATIN SMALL LETTER N PRECEDED BY APOSTROPHE, its uppercase is
+# \x{2BC}\x{E4} or MODIFIER LETTER APOSTROPHE and N.
+
+ok("\U\x{DF}ab\x{149}cd" eq "\x{53}\x{53}AB\x{2BC}\x{4E}CD",
+   "multicharacter uppercase");
+
+# The \x{DF} is its own lowercase, ditto for \x{149}.
+# There are no single character -> multiple characters lowercase mappings.
 
+ok("\L\x{DF}AB\x{149}CD" eq "\x{DF}ab\x{149}cd",
+   "multicharacter lowercase");
 
old mode 100755 (executable)
new mode 100644 (file)
diff --git a/utf8.c b/utf8.c
index 0c09469..4a3fe1d 100644 (file)
--- a/utf8.c
+++ b/utf8.c
@@ -1181,45 +1181,63 @@ Perl_is_utf8_mark(pTHX_ U8 *p)
 }
 
 UV
-Perl_to_utf8_upper(pTHX_ U8 *p, U8* ustrp, STRLEN *lenp)
+Perl_to_utf8_case(pTHX_ U8 *p, U8* ustrp, STRLEN *lenp, SV **swashp,char *normal, char *special)
 {
     UV uv;
 
-    if (!PL_utf8_toupper)
-       PL_utf8_toupper = swash_init("utf8", "ToUpper", &PL_sv_undef, 4, 0);
-    uv = swash_fetch(PL_utf8_toupper, p, TRUE);
-    uv = uv ? UNI_TO_NATIVE(uv) : utf8_to_uvchr(p, 0);
+    if (!*swashp)
+        *swashp = swash_init("utf8", normal, &PL_sv_undef, 4, 0);
+    uv = swash_fetch(*swashp, p, TRUE);
+    if (uv)
+        uv = UNI_TO_NATIVE(uv);
+    else {
+        HV *hv;
+        SV *keysv;
+        HE *he;
+
+        uv = utf8_to_uvchr(p, 0);
+
+        if ((hv    = get_hv(special, FALSE)) &&
+            (keysv = sv_2mortal(Perl_newSVpvf(aTHX_ "%"UVuf, uv))) &&
+            (he    = hv_fetch_ent(hv, keysv, FALSE, 0))) {
+             SV *val = HeVAL(he);
+             char *s = SvPV(val, *lenp);
+             U8 c = *(U8*)s;
+             if (*lenp > 1 || UNI_IS_INVARIANT(c))
+                  Copy(s, ustrp, *lenp, U8);
+             else {
+                  /* something in the 0x80..0xFF range */
+                  ustrp[0] = UTF8_EIGHT_BIT_HI(c);
+                  ustrp[1] = UTF8_EIGHT_BIT_LO(c);
+                  *lenp = 2;
+             }
+             return 0;
+        }
+    }
     *lenp = UNISKIP(uv);
     uvuni_to_utf8(ustrp, uv);
     return uv;
 }
 
 UV
-Perl_to_utf8_title(pTHX_ U8 *p, U8* ustrp, STRLEN *lenp)
+Perl_to_utf8_upper(pTHX_ U8 *p, U8* ustrp, STRLEN *lenp)
 {
-    UV uv;
+    return Perl_to_utf8_case(aTHX_ p, ustrp, lenp,
+                            &PL_utf8_toupper, "ToUpper", "utf8::ToSpecUpper");
+}
 
-    if (!PL_utf8_totitle)
-       PL_utf8_totitle = swash_init("utf8", "ToTitle", &PL_sv_undef, 4, 0);
-    uv = swash_fetch(PL_utf8_totitle, p, TRUE);
-    uv = uv ? UNI_TO_NATIVE(uv) : utf8_to_uvchr(p, 0);
-    *lenp = UNISKIP(uv);
-    uvuni_to_utf8(ustrp, uv);
-    return uv;
+UV
+Perl_to_utf8_title(pTHX_ U8 *p, U8* ustrp, STRLEN *lenp)
+{
+    return Perl_to_utf8_case(aTHX_ p, ustrp, lenp,
+                            &PL_utf8_totitle, "ToTitle", "utf8::ToSpecTitle");
 }
 
 UV
 Perl_to_utf8_lower(pTHX_ U8 *p, U8* ustrp, STRLEN *lenp)
 {
-    UV uv;
-
-    if (!PL_utf8_tolower)
-       PL_utf8_tolower = swash_init("utf8", "ToLower", &PL_sv_undef, 4, 0);
-    uv = swash_fetch(PL_utf8_tolower, p, TRUE);
-    uv = uv ? UNI_TO_NATIVE(uv) : utf8_to_uvchr(p, 0);
-    *lenp = UNISKIP(uv);
-    uvuni_to_utf8(ustrp, uv);
-    return uv;
+    return Perl_to_utf8_case(aTHX_ p, ustrp, lenp,
+                            &PL_utf8_tolower, "ToLower", "utf8::ToSpecLower");
 }
 
 /* a "swash" is a swatch hash */