summaryrefslogtreecommitdiff
path: root/lib/charnames.pm
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>1999-08-04 07:59:05 +0000
committerJarkko Hietaniemi <jhi@iki.fi>1999-08-04 07:59:05 +0000
commit423cee853811c26846bd1948939b85f9866dfb4a (patch)
treea1adb3cff6fd86474503248d2eba6747f0adeb02 /lib/charnames.pm
parentfd1e013efb606b51dc27fba846b1bedb38910a76 (diff)
downloadperl-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.pm134
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
+