diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 1999-08-04 07:59:05 +0000 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 1999-08-04 07:59:05 +0000 |
commit | 423cee853811c26846bd1948939b85f9866dfb4a (patch) | |
tree | a1adb3cff6fd86474503248d2eba6747f0adeb02 /lib/charnames.pm | |
parent | fd1e013efb606b51dc27fba846b1bedb38910a76 (diff) | |
download | perl-423cee853811c26846bd1948939b85f9866dfb4a.tar.gz |
Introduce the charnames pragma.
Subject: [PATCH 5.005_58] Free \C (for named chars), move to \O
From: Ilya Zakharevich <[9]ilya@math.ohio-state.edu>
To: Chip Salzenberg <[11]chip@perlsupport.com>
Cc: Mailing list Perl5 <[12]perl5-porters@perl.org>
Date: Sat, 31 Jul 1999 05:44:05 -0400
Message-Id: <[13]199907311407.IAA25042@localhost.frii.com>
From: Ilya Zakharevich <ilya@math.ohio-state.edu>
To: Mailing list Perl5 <perl5-porters@perl.org>
Subject: [PATCH 5.005_58] Named characters in Perl
Date: Mon, 2 Aug 1999 19:25:40 -0400
Message-ID: <19990802192540.B24407@monk.mps.ohio-state.edu>
p4raw-id: //depot/cfgperl@3916
Diffstat (limited to 'lib/charnames.pm')
-rw-r--r-- | lib/charnames.pm | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/lib/charnames.pm b/lib/charnames.pm new file mode 100644 index 0000000000..e407ff7c8a --- /dev/null +++ b/lib/charnames.pm @@ -0,0 +1,134 @@ +package charnames; + +my $fname = 'unicode/UnicodeData-Latest.txt'; +my $txt; + +# This is not optimized in any way yet +sub charnames { + $name = shift; + $txt = do "unicode/Name.pl" unless $txt; + my @off; + if ($^H{charnames_full} and $txt =~ /\t\t$name$/m) { + @off = ($-[0], $+[0]); + } + unless (@off) { + if ($^H{charnames_short} and $name =~ /^(.*?):(.*)/s) { + my ($script, $cname) = ($1,$2); + my $case = ( $cname =~ /[[:upper:]]/ ? "CAPITAL" : "SMALL"); + if ($txt =~ m/\t\t\U$script\E (?:$case )?LETTER \U$cname$/m) { + @off = ($-[0], $+[0]); + } + } + } + unless (@off) { + my $case = ( $name =~ /[[:upper:]]/ ? "CAPITAL" : "SMALL"); + for ( @{$^H{charnames_scripts}} ) { + (@off = ($-[0], $+[0])), last + if $txt =~ m/\t\t$_ (?:$case )?LETTER \U$name$/m; + } + } + die "Unknown charname '$name'" unless @off; + + # use caller 'encoding'; # Does not work at compile time? + + my $ord = hex substr $txt, $off[0] - 4, 4; + if ($^H & 0x8) { + use utf8; + return chr $ord; + } + return chr $ord if $ord <= 255; + my $hex = sprintf '%X=0%o', $ord, $ord; + my $fname = substr $txt, $off[0] + 2, $off[1] - $off[0] - 2; + die "Character 0x$hex with name '$fname' is above 0xFF"; +} + +sub import { + shift; + die "No scripts for `use charnames'" unless @_; + $^H |= 0x20000; + $^H{charnames} = \&charnames ; + my %h; + @h{@_} = (1) x @_; + $^H{charnames_full} = delete $h{':full'}; + $^H{charnames_short} = delete $h{':short'}; + $^H{charnames_scripts} = [map uc, keys %h]; +} + + +1; +__END__ + +=head1 NAME + +charnames - define character names for C<\C{named}> string literal escape. + +=head1 SYNOPSIS + + use charnames ':full'; + print "\C{GREEK SMALL LETTER SIGMA} is called sigma.\n"; + + use charnames ':short'; + print "\C{greek:Sigma} is an upper-case sigma.\n"; + + use charnames qw(cyrillic greek); + print "\C{sigma} is Greek sigma, and \C{be} is Cyrillic b.\n"; + +=head1 DESCRIPTION + +Pragma C<use charnames> supports arguments C<:full>, C<:short> and +script names. If C<:full> is present, for expansion of +C<\C{CHARNAME}}> string C<CHARNAME> is first looked in the list of +standard Unicode names of chars. If C<:short> is present, and +C<CHARNAME> has the form C<SCRIPT:CNAME>, then C<CNAME> is looked up +as a letter in script C<SCRIPT>. If pragma C<use charnames> is used +with script name arguments, then for C<\C{CHARNAME}}> the name +C<CHARNAME> is looked up as a letter in the given scripts (in the +specified order). + +For lookup of C<CHARNAME> inside a given script C<SCRIPTNAME> +F<charcodes.pm> looks for the names + + SCRIPTNAME CAPITAL LETTER CHARNAME + SCRIPTNAME SMALL LETTER CHARNAME + SCRIPTNAME LETTER CHARNAME + +in the table of standard Unicode names. If C<CHARNAME> is lowercase, +then the C<CAPITAL> variant is ignored, otherwise C<SMALL> variant is +ignored. + +=head1 CUSTOM TRANSLATORS + +The mechanism of translation is C<\C{...}> escapes is general and not +hardwired into F<charnames.pm>. A module can install custom +translations (inside the scope which C<use>s the module) by the +following magic incantation: + + sub import { + shift; + $^H |= 0x20000; + $^H{charnames} = \&translator; + } + +Here translator() is a subroutine which takes C<CHARNAME> as an +argument, and returns text to insert into the string instead of the +C<\C{CHARNAME}> escape. Since the text to insert should be different +in C<utf8> mode and out of it, the function should check the current +state of C<utf8>-flag as in + + sub translator { + if ($^H & 0x8) { + return utf_translator(@_); + } else { + return no_utf_translator(@_); + } + } + +=head1 BUGS + +Since evaluation of the translation function happens in a middle of +compilation (of a string literal), the translation function should not +do any C<eval>s or C<require>s. This restriction should be lifted in +a future version of Perl. + +=cut + |