summaryrefslogtreecommitdiff
path: root/lib/charnames.pm
diff options
context:
space:
mode:
authorKarl Williamson <public@khwilliamson.com>2010-09-12 21:33:12 -0600
committerFather Chrysostomos <sprout@cpan.org>2010-09-25 00:47:02 -0700
commitfb121860c2407cd1d1566d63a95a5220fa93d8e4 (patch)
treecc61893dd3ffe9966e079addeaa538172e2290e9 /lib/charnames.pm
parent8ebef31d4feab4b7c35ff0eb427632a67b1abdd9 (diff)
downloadperl-fb121860c2407cd1d1566d63a95a5220fa93d8e4.tar.gz
Teach Perl about Unicode named character sequences
mktables is changed to process the Unicode named sequence file. charnames.pm is changed to cache the looked-up values in utf8. A new function, string_vianame is created that can handle named sequences, as the interface for vianame cannot. The subroutine lookup_name() is slightly refactored to do almost all of the common work for \N{} and the vianame routines. It now understands named sequences as created my mktables.. tests and documentation are added. In the randomized testing section, half use vianame() and half string_vianame().
Diffstat (limited to 'lib/charnames.pm')
-rw-r--r--lib/charnames.pm994
1 files changed, 560 insertions, 434 deletions
diff --git a/lib/charnames.pm b/lib/charnames.pm
index 82f7903ca5..80b4d6e560 100644
--- a/lib/charnames.pm
+++ b/lib/charnames.pm
@@ -2,401 +2,407 @@ package charnames;
use strict;
use warnings;
use File::Spec;
-our $VERSION = '1.15';
+our $VERSION = '1.16';
use bytes (); # for $bytes::hint_bits
+# The hashes are stored as utf8 strings. This makes it easier to deal with
+# sequences. I (khw) also tried making Name.pl utf8, but it slowed things
+# down by a factor of 7. I then tried making Name.pl store the ut8
+# equivalents but not calling them utf8. That led to similar speed as leaving
+# it alone, but since that is harder for a human to parse, I left it as-is.
+
my %system_aliases = (
# Icky 3.2 names with parentheses.
- 'LINE FEED' => 0x0A, # LINE FEED (LF)
- 'FORM FEED' => 0x0C, # FORM FEED (FF)
- 'CARRIAGE RETURN' => 0x0D, # CARRIAGE RETURN (CR)
- 'NEXT LINE' => 0x85, # NEXT LINE (NEL)
+ 'LINE FEED' => pack("U", 0x0A), # LINE FEED (LF)
+ 'FORM FEED' => pack("U", 0x0C), # FORM FEED (FF)
+ 'CARRIAGE RETURN' => pack("U", 0x0D), # CARRIAGE RETURN (CR)
+ 'NEXT LINE' => pack("U", 0x85), # NEXT LINE (NEL)
# Some variant names from Wikipedia
- 'SINGLE-SHIFT 2' => 0x8E,
- 'SINGLE-SHIFT 3' => 0x8F,
- 'PRIVATE USE 1' => 0x91,
- 'PRIVATE USE 2' => 0x92,
- 'START OF PROTECTED AREA' => 0x96,
- 'END OF PROTECTED AREA' => 0x97,
+ 'SINGLE-SHIFT 2' => pack("U", 0x8E),
+ 'SINGLE-SHIFT 3' => pack("U", 0x8F),
+ 'PRIVATE USE 1' => pack("U", 0x91),
+ 'PRIVATE USE 2' => pack("U", 0x92),
+ 'START OF PROTECTED AREA' => pack("U", 0x96),
+ 'END OF PROTECTED AREA' => pack("U", 0x97),
# Convenience. Standard abbreviations for the controls
- 'NUL' => 0x00, # NULL
- 'SOH' => 0x01, # START OF HEADING
- 'STX' => 0x02, # START OF TEXT
- 'ETX' => 0x03, # END OF TEXT
- 'EOT' => 0x04, # END OF TRANSMISSION
- 'ENQ' => 0x05, # ENQUIRY
- 'ACK' => 0x06, # ACKNOWLEDGE
- 'BEL' => 0x07, # BELL
- 'BS' => 0x08, # BACKSPACE
- 'HT' => 0x09, # HORIZONTAL TABULATION
- 'LF' => 0x0A, # LINE FEED (LF)
- 'VT' => 0x0B, # VERTICAL TABULATION
- 'FF' => 0x0C, # FORM FEED (FF)
- 'CR' => 0x0D, # CARRIAGE RETURN (CR)
- 'SO' => 0x0E, # SHIFT OUT
- 'SI' => 0x0F, # SHIFT IN
- 'DLE' => 0x10, # DATA LINK ESCAPE
- 'DC1' => 0x11, # DEVICE CONTROL ONE
- 'DC2' => 0x12, # DEVICE CONTROL TWO
- 'DC3' => 0x13, # DEVICE CONTROL THREE
- 'DC4' => 0x14, # DEVICE CONTROL FOUR
- 'NAK' => 0x15, # NEGATIVE ACKNOWLEDGE
- 'SYN' => 0x16, # SYNCHRONOUS IDLE
- 'ETB' => 0x17, # END OF TRANSMISSION BLOCK
- 'CAN' => 0x18, # CANCEL
- 'EOM' => 0x19, # END OF MEDIUM
- 'SUB' => 0x1A, # SUBSTITUTE
- 'ESC' => 0x1B, # ESCAPE
- 'FS' => 0x1C, # FILE SEPARATOR
- 'GS' => 0x1D, # GROUP SEPARATOR
- 'RS' => 0x1E, # RECORD SEPARATOR
- 'US' => 0x1F, # UNIT SEPARATOR
- 'DEL' => 0x7F, # DELETE
- 'BPH' => 0x82, # BREAK PERMITTED HERE
- 'NBH' => 0x83, # NO BREAK HERE
- 'NEL' => 0x85, # NEXT LINE (NEL)
- 'SSA' => 0x86, # START OF SELECTED AREA
- 'ESA' => 0x87, # END OF SELECTED AREA
- 'HTS' => 0x88, # CHARACTER TABULATION SET
- 'HTJ' => 0x89, # CHARACTER TABULATION WITH JUSTIFICATION
- 'VTS' => 0x8A, # LINE TABULATION SET
- 'PLD' => 0x8B, # PARTIAL LINE FORWARD
- 'PLU' => 0x8C, # PARTIAL LINE BACKWARD
- 'RI ' => 0x8D, # REVERSE LINE FEED
- 'SS2' => 0x8E, # SINGLE SHIFT TWO
- 'SS3' => 0x8F, # SINGLE SHIFT THREE
- 'DCS' => 0x90, # DEVICE CONTROL STRING
- 'PU1' => 0x91, # PRIVATE USE ONE
- 'PU2' => 0x92, # PRIVATE USE TWO
- 'STS' => 0x93, # SET TRANSMIT STATE
- 'CCH' => 0x94, # CANCEL CHARACTER
- 'MW ' => 0x95, # MESSAGE WAITING
- 'SPA' => 0x96, # START OF GUARDED AREA
- 'EPA' => 0x97, # END OF GUARDED AREA
- 'SOS' => 0x98, # START OF STRING
- 'SCI' => 0x9A, # SINGLE CHARACTER INTRODUCER
- 'CSI' => 0x9B, # CONTROL SEQUENCE INTRODUCER
- 'ST ' => 0x9C, # STRING TERMINATOR
- 'OSC' => 0x9D, # OPERATING SYSTEM COMMAND
- 'PM ' => 0x9E, # PRIVACY MESSAGE
- 'APC' => 0x9F, # APPLICATION PROGRAM COMMAND
+ 'NUL' => pack("U", 0x00), # NULL
+ 'SOH' => pack("U", 0x01), # START OF HEADING
+ 'STX' => pack("U", 0x02), # START OF TEXT
+ 'ETX' => pack("U", 0x03), # END OF TEXT
+ 'EOT' => pack("U", 0x04), # END OF TRANSMISSION
+ 'ENQ' => pack("U", 0x05), # ENQUIRY
+ 'ACK' => pack("U", 0x06), # ACKNOWLEDGE
+ 'BEL' => pack("U", 0x07), # BELL
+ 'BS' => pack("U", 0x08), # BACKSPACE
+ 'HT' => pack("U", 0x09), # HORIZONTAL TABULATION
+ 'LF' => pack("U", 0x0A), # LINE FEED (LF)
+ 'VT' => pack("U", 0x0B), # VERTICAL TABULATION
+ 'FF' => pack("U", 0x0C), # FORM FEED (FF)
+ 'CR' => pack("U", 0x0D), # CARRIAGE RETURN (CR)
+ 'SO' => pack("U", 0x0E), # SHIFT OUT
+ 'SI' => pack("U", 0x0F), # SHIFT IN
+ 'DLE' => pack("U", 0x10), # DATA LINK ESCAPE
+ 'DC1' => pack("U", 0x11), # DEVICE CONTROL ONE
+ 'DC2' => pack("U", 0x12), # DEVICE CONTROL TWO
+ 'DC3' => pack("U", 0x13), # DEVICE CONTROL THREE
+ 'DC4' => pack("U", 0x14), # DEVICE CONTROL FOUR
+ 'NAK' => pack("U", 0x15), # NEGATIVE ACKNOWLEDGE
+ 'SYN' => pack("U", 0x16), # SYNCHRONOUS IDLE
+ 'ETB' => pack("U", 0x17), # END OF TRANSMISSION BLOCK
+ 'CAN' => pack("U", 0x18), # CANCEL
+ 'EOM' => pack("U", 0x19), # END OF MEDIUM
+ 'SUB' => pack("U", 0x1A), # SUBSTITUTE
+ 'ESC' => pack("U", 0x1B), # ESCAPE
+ 'FS' => pack("U", 0x1C), # FILE SEPARATOR
+ 'GS' => pack("U", 0x1D), # GROUP SEPARATOR
+ 'RS' => pack("U", 0x1E), # RECORD SEPARATOR
+ 'US' => pack("U", 0x1F), # UNIT SEPARATOR
+ 'DEL' => pack("U", 0x7F), # DELETE
+ 'BPH' => pack("U", 0x82), # BREAK PERMITTED HERE
+ 'NBH' => pack("U", 0x83), # NO BREAK HERE
+ 'NEL' => pack("U", 0x85), # NEXT LINE (NEL)
+ 'SSA' => pack("U", 0x86), # START OF SELECTED AREA
+ 'ESA' => pack("U", 0x87), # END OF SELECTED AREA
+ 'HTS' => pack("U", 0x88), # CHARACTER TABULATION SET
+ 'HTJ' => pack("U", 0x89), # CHARACTER TABULATION WITH JUSTIFICATION
+ 'VTS' => pack("U", 0x8A), # LINE TABULATION SET
+ 'PLD' => pack("U", 0x8B), # PARTIAL LINE FORWARD
+ 'PLU' => pack("U", 0x8C), # PARTIAL LINE BACKWARD
+ 'RI ' => pack("U", 0x8D), # REVERSE LINE FEED
+ 'SS2' => pack("U", 0x8E), # SINGLE SHIFT TWO
+ 'SS3' => pack("U", 0x8F), # SINGLE SHIFT THREE
+ 'DCS' => pack("U", 0x90), # DEVICE CONTROL STRING
+ 'PU1' => pack("U", 0x91), # PRIVATE USE ONE
+ 'PU2' => pack("U", 0x92), # PRIVATE USE TWO
+ 'STS' => pack("U", 0x93), # SET TRANSMIT STATE
+ 'CCH' => pack("U", 0x94), # CANCEL CHARACTER
+ 'MW ' => pack("U", 0x95), # MESSAGE WAITING
+ 'SPA' => pack("U", 0x96), # START OF GUARDED AREA
+ 'EPA' => pack("U", 0x97), # END OF GUARDED AREA
+ 'SOS' => pack("U", 0x98), # START OF STRING
+ 'SCI' => pack("U", 0x9A), # SINGLE CHARACTER INTRODUCER
+ 'CSI' => pack("U", 0x9B), # CONTROL SEQUENCE INTRODUCER
+ 'ST ' => pack("U", 0x9C), # STRING TERMINATOR
+ 'OSC' => pack("U", 0x9D), # OPERATING SYSTEM COMMAND
+ 'PM ' => pack("U", 0x9E), # PRIVACY MESSAGE
+ 'APC' => pack("U", 0x9F), # APPLICATION PROGRAM COMMAND
# There are no names for these in the Unicode standard;
# perhaps should be deprecated, but then again there are
# no alternative names, so am not deprecating. And if
# did, the code would have to change to not recommend an
# alternative for these.
- 'PADDING CHARACTER' => 0x80,
- 'PAD' => 0x80,
- 'HIGH OCTET PRESET' => 0x81,
- 'HOP' => 0x81,
- 'INDEX' => 0x84,
- 'IND' => 0x84,
- 'SINGLE GRAPHIC CHARACTER INTRODUCER' => 0x99,
- 'SGC' => 0x99,
+ 'PADDING CHARACTER' => pack("U", 0x80),
+ 'PAD' => pack("U", 0x80),
+ 'HIGH OCTET PRESET' => pack("U", 0x81),
+ 'HOP' => pack("U", 0x81),
+ 'INDEX' => pack("U", 0x84),
+ 'IND' => pack("U", 0x84),
+ 'SINGLE GRAPHIC CHARACTER INTRODUCER' => pack("U", 0x99),
+ 'SGC' => pack("U", 0x99),
# More convenience. For further convenience,
# it is suggested some way of using the NamesList
# aliases be implemented, but there are ambiguities in
# NamesList.txt
- 'BOM' => 0xFEFF, # BYTE ORDER MARK
- 'BYTE ORDER MARK'=> 0xFEFF,
- 'CGJ' => 0x034F, # COMBINING GRAPHEME JOINER
- 'FVS1' => 0x180B, # MONGOLIAN FREE VARIATION SELECTOR ONE
- 'FVS2' => 0x180C, # MONGOLIAN FREE VARIATION SELECTOR TWO
- 'FVS3' => 0x180D, # MONGOLIAN FREE VARIATION SELECTOR THREE
- 'LRE' => 0x202A, # LEFT-TO-RIGHT EMBEDDING
- 'LRM' => 0x200E, # LEFT-TO-RIGHT MARK
- 'LRO' => 0x202D, # LEFT-TO-RIGHT OVERRIDE
- 'MMSP' => 0x205F, # MEDIUM MATHEMATICAL SPACE
- 'MVS' => 0x180E, # MONGOLIAN VOWEL SEPARATOR
- 'NBSP' => 0x00A0, # NO-BREAK SPACE
- 'NNBSP' => 0x202F, # NARROW NO-BREAK SPACE
- 'PDF' => 0x202C, # POP DIRECTIONAL FORMATTING
- 'RLE' => 0x202B, # RIGHT-TO-LEFT EMBEDDING
- 'RLM' => 0x200F, # RIGHT-TO-LEFT MARK
- 'RLO' => 0x202E, # RIGHT-TO-LEFT OVERRIDE
- 'SHY' => 0x00AD, # SOFT HYPHEN
- 'VS1' => 0xFE00, # VARIATION SELECTOR-1
- 'VS2' => 0xFE01, # VARIATION SELECTOR-2
- 'VS3' => 0xFE02, # VARIATION SELECTOR-3
- 'VS4' => 0xFE03, # VARIATION SELECTOR-4
- 'VS5' => 0xFE04, # VARIATION SELECTOR-5
- 'VS6' => 0xFE05, # VARIATION SELECTOR-6
- 'VS7' => 0xFE06, # VARIATION SELECTOR-7
- 'VS8' => 0xFE07, # VARIATION SELECTOR-8
- 'VS9' => 0xFE08, # VARIATION SELECTOR-9
- 'VS10' => 0xFE09, # VARIATION SELECTOR-10
- 'VS11' => 0xFE0A, # VARIATION SELECTOR-11
- 'VS12' => 0xFE0B, # VARIATION SELECTOR-12
- 'VS13' => 0xFE0C, # VARIATION SELECTOR-13
- 'VS14' => 0xFE0D, # VARIATION SELECTOR-14
- 'VS15' => 0xFE0E, # VARIATION SELECTOR-15
- 'VS16' => 0xFE0F, # VARIATION SELECTOR-16
- 'VS17' => 0xE0100, # VARIATION SELECTOR-17
- 'VS18' => 0xE0101, # VARIATION SELECTOR-18
- 'VS19' => 0xE0102, # VARIATION SELECTOR-19
- 'VS20' => 0xE0103, # VARIATION SELECTOR-20
- 'VS21' => 0xE0104, # VARIATION SELECTOR-21
- 'VS22' => 0xE0105, # VARIATION SELECTOR-22
- 'VS23' => 0xE0106, # VARIATION SELECTOR-23
- 'VS24' => 0xE0107, # VARIATION SELECTOR-24
- 'VS25' => 0xE0108, # VARIATION SELECTOR-25
- 'VS26' => 0xE0109, # VARIATION SELECTOR-26
- 'VS27' => 0xE010A, # VARIATION SELECTOR-27
- 'VS28' => 0xE010B, # VARIATION SELECTOR-28
- 'VS29' => 0xE010C, # VARIATION SELECTOR-29
- 'VS30' => 0xE010D, # VARIATION SELECTOR-30
- 'VS31' => 0xE010E, # VARIATION SELECTOR-31
- 'VS32' => 0xE010F, # VARIATION SELECTOR-32
- 'VS33' => 0xE0110, # VARIATION SELECTOR-33
- 'VS34' => 0xE0111, # VARIATION SELECTOR-34
- 'VS35' => 0xE0112, # VARIATION SELECTOR-35
- 'VS36' => 0xE0113, # VARIATION SELECTOR-36
- 'VS37' => 0xE0114, # VARIATION SELECTOR-37
- 'VS38' => 0xE0115, # VARIATION SELECTOR-38
- 'VS39' => 0xE0116, # VARIATION SELECTOR-39
- 'VS40' => 0xE0117, # VARIATION SELECTOR-40
- 'VS41' => 0xE0118, # VARIATION SELECTOR-41
- 'VS42' => 0xE0119, # VARIATION SELECTOR-42
- 'VS43' => 0xE011A, # VARIATION SELECTOR-43
- 'VS44' => 0xE011B, # VARIATION SELECTOR-44
- 'VS45' => 0xE011C, # VARIATION SELECTOR-45
- 'VS46' => 0xE011D, # VARIATION SELECTOR-46
- 'VS47' => 0xE011E, # VARIATION SELECTOR-47
- 'VS48' => 0xE011F, # VARIATION SELECTOR-48
- 'VS49' => 0xE0120, # VARIATION SELECTOR-49
- 'VS50' => 0xE0121, # VARIATION SELECTOR-50
- 'VS51' => 0xE0122, # VARIATION SELECTOR-51
- 'VS52' => 0xE0123, # VARIATION SELECTOR-52
- 'VS53' => 0xE0124, # VARIATION SELECTOR-53
- 'VS54' => 0xE0125, # VARIATION SELECTOR-54
- 'VS55' => 0xE0126, # VARIATION SELECTOR-55
- 'VS56' => 0xE0127, # VARIATION SELECTOR-56
- 'VS57' => 0xE0128, # VARIATION SELECTOR-57
- 'VS58' => 0xE0129, # VARIATION SELECTOR-58
- 'VS59' => 0xE012A, # VARIATION SELECTOR-59
- 'VS60' => 0xE012B, # VARIATION SELECTOR-60
- 'VS61' => 0xE012C, # VARIATION SELECTOR-61
- 'VS62' => 0xE012D, # VARIATION SELECTOR-62
- 'VS63' => 0xE012E, # VARIATION SELECTOR-63
- 'VS64' => 0xE012F, # VARIATION SELECTOR-64
- 'VS65' => 0xE0130, # VARIATION SELECTOR-65
- 'VS66' => 0xE0131, # VARIATION SELECTOR-66
- 'VS67' => 0xE0132, # VARIATION SELECTOR-67
- 'VS68' => 0xE0133, # VARIATION SELECTOR-68
- 'VS69' => 0xE0134, # VARIATION SELECTOR-69
- 'VS70' => 0xE0135, # VARIATION SELECTOR-70
- 'VS71' => 0xE0136, # VARIATION SELECTOR-71
- 'VS72' => 0xE0137, # VARIATION SELECTOR-72
- 'VS73' => 0xE0138, # VARIATION SELECTOR-73
- 'VS74' => 0xE0139, # VARIATION SELECTOR-74
- 'VS75' => 0xE013A, # VARIATION SELECTOR-75
- 'VS76' => 0xE013B, # VARIATION SELECTOR-76
- 'VS77' => 0xE013C, # VARIATION SELECTOR-77
- 'VS78' => 0xE013D, # VARIATION SELECTOR-78
- 'VS79' => 0xE013E, # VARIATION SELECTOR-79
- 'VS80' => 0xE013F, # VARIATION SELECTOR-80
- 'VS81' => 0xE0140, # VARIATION SELECTOR-81
- 'VS82' => 0xE0141, # VARIATION SELECTOR-82
- 'VS83' => 0xE0142, # VARIATION SELECTOR-83
- 'VS84' => 0xE0143, # VARIATION SELECTOR-84
- 'VS85' => 0xE0144, # VARIATION SELECTOR-85
- 'VS86' => 0xE0145, # VARIATION SELECTOR-86
- 'VS87' => 0xE0146, # VARIATION SELECTOR-87
- 'VS88' => 0xE0147, # VARIATION SELECTOR-88
- 'VS89' => 0xE0148, # VARIATION SELECTOR-89
- 'VS90' => 0xE0149, # VARIATION SELECTOR-90
- 'VS91' => 0xE014A, # VARIATION SELECTOR-91
- 'VS92' => 0xE014B, # VARIATION SELECTOR-92
- 'VS93' => 0xE014C, # VARIATION SELECTOR-93
- 'VS94' => 0xE014D, # VARIATION SELECTOR-94
- 'VS95' => 0xE014E, # VARIATION SELECTOR-95
- 'VS96' => 0xE014F, # VARIATION SELECTOR-96
- 'VS97' => 0xE0150, # VARIATION SELECTOR-97
- 'VS98' => 0xE0151, # VARIATION SELECTOR-98
- 'VS99' => 0xE0152, # VARIATION SELECTOR-99
- 'VS100' => 0xE0153, # VARIATION SELECTOR-100
- 'VS101' => 0xE0154, # VARIATION SELECTOR-101
- 'VS102' => 0xE0155, # VARIATION SELECTOR-102
- 'VS103' => 0xE0156, # VARIATION SELECTOR-103
- 'VS104' => 0xE0157, # VARIATION SELECTOR-104
- 'VS105' => 0xE0158, # VARIATION SELECTOR-105
- 'VS106' => 0xE0159, # VARIATION SELECTOR-106
- 'VS107' => 0xE015A, # VARIATION SELECTOR-107
- 'VS108' => 0xE015B, # VARIATION SELECTOR-108
- 'VS109' => 0xE015C, # VARIATION SELECTOR-109
- 'VS110' => 0xE015D, # VARIATION SELECTOR-110
- 'VS111' => 0xE015E, # VARIATION SELECTOR-111
- 'VS112' => 0xE015F, # VARIATION SELECTOR-112
- 'VS113' => 0xE0160, # VARIATION SELECTOR-113
- 'VS114' => 0xE0161, # VARIATION SELECTOR-114
- 'VS115' => 0xE0162, # VARIATION SELECTOR-115
- 'VS116' => 0xE0163, # VARIATION SELECTOR-116
- 'VS117' => 0xE0164, # VARIATION SELECTOR-117
- 'VS118' => 0xE0165, # VARIATION SELECTOR-118
- 'VS119' => 0xE0166, # VARIATION SELECTOR-119
- 'VS120' => 0xE0167, # VARIATION SELECTOR-120
- 'VS121' => 0xE0168, # VARIATION SELECTOR-121
- 'VS122' => 0xE0169, # VARIATION SELECTOR-122
- 'VS123' => 0xE016A, # VARIATION SELECTOR-123
- 'VS124' => 0xE016B, # VARIATION SELECTOR-124
- 'VS125' => 0xE016C, # VARIATION SELECTOR-125
- 'VS126' => 0xE016D, # VARIATION SELECTOR-126
- 'VS127' => 0xE016E, # VARIATION SELECTOR-127
- 'VS128' => 0xE016F, # VARIATION SELECTOR-128
- 'VS129' => 0xE0170, # VARIATION SELECTOR-129
- 'VS130' => 0xE0171, # VARIATION SELECTOR-130
- 'VS131' => 0xE0172, # VARIATION SELECTOR-131
- 'VS132' => 0xE0173, # VARIATION SELECTOR-132
- 'VS133' => 0xE0174, # VARIATION SELECTOR-133
- 'VS134' => 0xE0175, # VARIATION SELECTOR-134
- 'VS135' => 0xE0176, # VARIATION SELECTOR-135
- 'VS136' => 0xE0177, # VARIATION SELECTOR-136
- 'VS137' => 0xE0178, # VARIATION SELECTOR-137
- 'VS138' => 0xE0179, # VARIATION SELECTOR-138
- 'VS139' => 0xE017A, # VARIATION SELECTOR-139
- 'VS140' => 0xE017B, # VARIATION SELECTOR-140
- 'VS141' => 0xE017C, # VARIATION SELECTOR-141
- 'VS142' => 0xE017D, # VARIATION SELECTOR-142
- 'VS143' => 0xE017E, # VARIATION SELECTOR-143
- 'VS144' => 0xE017F, # VARIATION SELECTOR-144
- 'VS145' => 0xE0180, # VARIATION SELECTOR-145
- 'VS146' => 0xE0181, # VARIATION SELECTOR-146
- 'VS147' => 0xE0182, # VARIATION SELECTOR-147
- 'VS148' => 0xE0183, # VARIATION SELECTOR-148
- 'VS149' => 0xE0184, # VARIATION SELECTOR-149
- 'VS150' => 0xE0185, # VARIATION SELECTOR-150
- 'VS151' => 0xE0186, # VARIATION SELECTOR-151
- 'VS152' => 0xE0187, # VARIATION SELECTOR-152
- 'VS153' => 0xE0188, # VARIATION SELECTOR-153
- 'VS154' => 0xE0189, # VARIATION SELECTOR-154
- 'VS155' => 0xE018A, # VARIATION SELECTOR-155
- 'VS156' => 0xE018B, # VARIATION SELECTOR-156
- 'VS157' => 0xE018C, # VARIATION SELECTOR-157
- 'VS158' => 0xE018D, # VARIATION SELECTOR-158
- 'VS159' => 0xE018E, # VARIATION SELECTOR-159
- 'VS160' => 0xE018F, # VARIATION SELECTOR-160
- 'VS161' => 0xE0190, # VARIATION SELECTOR-161
- 'VS162' => 0xE0191, # VARIATION SELECTOR-162
- 'VS163' => 0xE0192, # VARIATION SELECTOR-163
- 'VS164' => 0xE0193, # VARIATION SELECTOR-164
- 'VS165' => 0xE0194, # VARIATION SELECTOR-165
- 'VS166' => 0xE0195, # VARIATION SELECTOR-166
- 'VS167' => 0xE0196, # VARIATION SELECTOR-167
- 'VS168' => 0xE0197, # VARIATION SELECTOR-168
- 'VS169' => 0xE0198, # VARIATION SELECTOR-169
- 'VS170' => 0xE0199, # VARIATION SELECTOR-170
- 'VS171' => 0xE019A, # VARIATION SELECTOR-171
- 'VS172' => 0xE019B, # VARIATION SELECTOR-172
- 'VS173' => 0xE019C, # VARIATION SELECTOR-173
- 'VS174' => 0xE019D, # VARIATION SELECTOR-174
- 'VS175' => 0xE019E, # VARIATION SELECTOR-175
- 'VS176' => 0xE019F, # VARIATION SELECTOR-176
- 'VS177' => 0xE01A0, # VARIATION SELECTOR-177
- 'VS178' => 0xE01A1, # VARIATION SELECTOR-178
- 'VS179' => 0xE01A2, # VARIATION SELECTOR-179
- 'VS180' => 0xE01A3, # VARIATION SELECTOR-180
- 'VS181' => 0xE01A4, # VARIATION SELECTOR-181
- 'VS182' => 0xE01A5, # VARIATION SELECTOR-182
- 'VS183' => 0xE01A6, # VARIATION SELECTOR-183
- 'VS184' => 0xE01A7, # VARIATION SELECTOR-184
- 'VS185' => 0xE01A8, # VARIATION SELECTOR-185
- 'VS186' => 0xE01A9, # VARIATION SELECTOR-186
- 'VS187' => 0xE01AA, # VARIATION SELECTOR-187
- 'VS188' => 0xE01AB, # VARIATION SELECTOR-188
- 'VS189' => 0xE01AC, # VARIATION SELECTOR-189
- 'VS190' => 0xE01AD, # VARIATION SELECTOR-190
- 'VS191' => 0xE01AE, # VARIATION SELECTOR-191
- 'VS192' => 0xE01AF, # VARIATION SELECTOR-192
- 'VS193' => 0xE01B0, # VARIATION SELECTOR-193
- 'VS194' => 0xE01B1, # VARIATION SELECTOR-194
- 'VS195' => 0xE01B2, # VARIATION SELECTOR-195
- 'VS196' => 0xE01B3, # VARIATION SELECTOR-196
- 'VS197' => 0xE01B4, # VARIATION SELECTOR-197
- 'VS198' => 0xE01B5, # VARIATION SELECTOR-198
- 'VS199' => 0xE01B6, # VARIATION SELECTOR-199
- 'VS200' => 0xE01B7, # VARIATION SELECTOR-200
- 'VS201' => 0xE01B8, # VARIATION SELECTOR-201
- 'VS202' => 0xE01B9, # VARIATION SELECTOR-202
- 'VS203' => 0xE01BA, # VARIATION SELECTOR-203
- 'VS204' => 0xE01BB, # VARIATION SELECTOR-204
- 'VS205' => 0xE01BC, # VARIATION SELECTOR-205
- 'VS206' => 0xE01BD, # VARIATION SELECTOR-206
- 'VS207' => 0xE01BE, # VARIATION SELECTOR-207
- 'VS208' => 0xE01BF, # VARIATION SELECTOR-208
- 'VS209' => 0xE01C0, # VARIATION SELECTOR-209
- 'VS210' => 0xE01C1, # VARIATION SELECTOR-210
- 'VS211' => 0xE01C2, # VARIATION SELECTOR-211
- 'VS212' => 0xE01C3, # VARIATION SELECTOR-212
- 'VS213' => 0xE01C4, # VARIATION SELECTOR-213
- 'VS214' => 0xE01C5, # VARIATION SELECTOR-214
- 'VS215' => 0xE01C6, # VARIATION SELECTOR-215
- 'VS216' => 0xE01C7, # VARIATION SELECTOR-216
- 'VS217' => 0xE01C8, # VARIATION SELECTOR-217
- 'VS218' => 0xE01C9, # VARIATION SELECTOR-218
- 'VS219' => 0xE01CA, # VARIATION SELECTOR-219
- 'VS220' => 0xE01CB, # VARIATION SELECTOR-220
- 'VS221' => 0xE01CC, # VARIATION SELECTOR-221
- 'VS222' => 0xE01CD, # VARIATION SELECTOR-222
- 'VS223' => 0xE01CE, # VARIATION SELECTOR-223
- 'VS224' => 0xE01CF, # VARIATION SELECTOR-224
- 'VS225' => 0xE01D0, # VARIATION SELECTOR-225
- 'VS226' => 0xE01D1, # VARIATION SELECTOR-226
- 'VS227' => 0xE01D2, # VARIATION SELECTOR-227
- 'VS228' => 0xE01D3, # VARIATION SELECTOR-228
- 'VS229' => 0xE01D4, # VARIATION SELECTOR-229
- 'VS230' => 0xE01D5, # VARIATION SELECTOR-230
- 'VS231' => 0xE01D6, # VARIATION SELECTOR-231
- 'VS232' => 0xE01D7, # VARIATION SELECTOR-232
- 'VS233' => 0xE01D8, # VARIATION SELECTOR-233
- 'VS234' => 0xE01D9, # VARIATION SELECTOR-234
- 'VS235' => 0xE01DA, # VARIATION SELECTOR-235
- 'VS236' => 0xE01DB, # VARIATION SELECTOR-236
- 'VS237' => 0xE01DC, # VARIATION SELECTOR-237
- 'VS238' => 0xE01DD, # VARIATION SELECTOR-238
- 'VS239' => 0xE01DE, # VARIATION SELECTOR-239
- 'VS240' => 0xE01DF, # VARIATION SELECTOR-240
- 'VS241' => 0xE01E0, # VARIATION SELECTOR-241
- 'VS242' => 0xE01E1, # VARIATION SELECTOR-242
- 'VS243' => 0xE01E2, # VARIATION SELECTOR-243
- 'VS244' => 0xE01E3, # VARIATION SELECTOR-244
- 'VS245' => 0xE01E4, # VARIATION SELECTOR-245
- 'VS246' => 0xE01E5, # VARIATION SELECTOR-246
- 'VS247' => 0xE01E6, # VARIATION SELECTOR-247
- 'VS248' => 0xE01E7, # VARIATION SELECTOR-248
- 'VS249' => 0xE01E8, # VARIATION SELECTOR-249
- 'VS250' => 0xE01E9, # VARIATION SELECTOR-250
- 'VS251' => 0xE01EA, # VARIATION SELECTOR-251
- 'VS252' => 0xE01EB, # VARIATION SELECTOR-252
- 'VS253' => 0xE01EC, # VARIATION SELECTOR-253
- 'VS254' => 0xE01ED, # VARIATION SELECTOR-254
- 'VS255' => 0xE01EE, # VARIATION SELECTOR-255
- 'VS256' => 0xE01EF, # VARIATION SELECTOR-256
- 'WJ' => 0x2060, # WORD JOINER
- 'ZWJ' => 0x200D, # ZERO WIDTH JOINER
- 'ZWNJ' => 0x200C, # ZERO WIDTH NON-JOINER
- 'ZWSP' => 0x200B, # ZERO WIDTH SPACE
+ 'BOM' => pack("U", 0xFEFF), # BYTE ORDER MARK
+ 'BYTE ORDER MARK'=> pack("U", 0xFEFF),
+ 'CGJ' => pack("U", 0x034F), # COMBINING GRAPHEME JOINER
+ 'FVS1' => pack("U", 0x180B), # MONGOLIAN FREE VARIATION SELECTOR ONE
+ 'FVS2' => pack("U", 0x180C), # MONGOLIAN FREE VARIATION SELECTOR TWO
+ 'FVS3' => pack("U", 0x180D), # MONGOLIAN FREE VARIATION SELECTOR THREE
+ 'LRE' => pack("U", 0x202A), # LEFT-TO-RIGHT EMBEDDING
+ 'LRM' => pack("U", 0x200E), # LEFT-TO-RIGHT MARK
+ 'LRO' => pack("U", 0x202D), # LEFT-TO-RIGHT OVERRIDE
+ 'MMSP' => pack("U", 0x205F), # MEDIUM MATHEMATICAL SPACE
+ 'MVS' => pack("U", 0x180E), # MONGOLIAN VOWEL SEPARATOR
+ 'NBSP' => pack("U", 0x00A0), # NO-BREAK SPACE
+ 'NNBSP' => pack("U", 0x202F), # NARROW NO-BREAK SPACE
+ 'PDF' => pack("U", 0x202C), # POP DIRECTIONAL FORMATTING
+ 'RLE' => pack("U", 0x202B), # RIGHT-TO-LEFT EMBEDDING
+ 'RLM' => pack("U", 0x200F), # RIGHT-TO-LEFT MARK
+ 'RLO' => pack("U", 0x202E), # RIGHT-TO-LEFT OVERRIDE
+ 'SHY' => pack("U", 0x00AD), # SOFT HYPHEN
+ 'VS1' => pack("U", 0xFE00), # VARIATION SELECTOR-1
+ 'VS2' => pack("U", 0xFE01), # VARIATION SELECTOR-2
+ 'VS3' => pack("U", 0xFE02), # VARIATION SELECTOR-3
+ 'VS4' => pack("U", 0xFE03), # VARIATION SELECTOR-4
+ 'VS5' => pack("U", 0xFE04), # VARIATION SELECTOR-5
+ 'VS6' => pack("U", 0xFE05), # VARIATION SELECTOR-6
+ 'VS7' => pack("U", 0xFE06), # VARIATION SELECTOR-7
+ 'VS8' => pack("U", 0xFE07), # VARIATION SELECTOR-8
+ 'VS9' => pack("U", 0xFE08), # VARIATION SELECTOR-9
+ 'VS10' => pack("U", 0xFE09), # VARIATION SELECTOR-10
+ 'VS11' => pack("U", 0xFE0A), # VARIATION SELECTOR-11
+ 'VS12' => pack("U", 0xFE0B), # VARIATION SELECTOR-12
+ 'VS13' => pack("U", 0xFE0C), # VARIATION SELECTOR-13
+ 'VS14' => pack("U", 0xFE0D), # VARIATION SELECTOR-14
+ 'VS15' => pack("U", 0xFE0E), # VARIATION SELECTOR-15
+ 'VS16' => pack("U", 0xFE0F), # VARIATION SELECTOR-16
+ 'VS17' => pack("U", 0xE0100), # VARIATION SELECTOR-17
+ 'VS18' => pack("U", 0xE0101), # VARIATION SELECTOR-18
+ 'VS19' => pack("U", 0xE0102), # VARIATION SELECTOR-19
+ 'VS20' => pack("U", 0xE0103), # VARIATION SELECTOR-20
+ 'VS21' => pack("U", 0xE0104), # VARIATION SELECTOR-21
+ 'VS22' => pack("U", 0xE0105), # VARIATION SELECTOR-22
+ 'VS23' => pack("U", 0xE0106), # VARIATION SELECTOR-23
+ 'VS24' => pack("U", 0xE0107), # VARIATION SELECTOR-24
+ 'VS25' => pack("U", 0xE0108), # VARIATION SELECTOR-25
+ 'VS26' => pack("U", 0xE0109), # VARIATION SELECTOR-26
+ 'VS27' => pack("U", 0xE010A), # VARIATION SELECTOR-27
+ 'VS28' => pack("U", 0xE010B), # VARIATION SELECTOR-28
+ 'VS29' => pack("U", 0xE010C), # VARIATION SELECTOR-29
+ 'VS30' => pack("U", 0xE010D), # VARIATION SELECTOR-30
+ 'VS31' => pack("U", 0xE010E), # VARIATION SELECTOR-31
+ 'VS32' => pack("U", 0xE010F), # VARIATION SELECTOR-32
+ 'VS33' => pack("U", 0xE0110), # VARIATION SELECTOR-33
+ 'VS34' => pack("U", 0xE0111), # VARIATION SELECTOR-34
+ 'VS35' => pack("U", 0xE0112), # VARIATION SELECTOR-35
+ 'VS36' => pack("U", 0xE0113), # VARIATION SELECTOR-36
+ 'VS37' => pack("U", 0xE0114), # VARIATION SELECTOR-37
+ 'VS38' => pack("U", 0xE0115), # VARIATION SELECTOR-38
+ 'VS39' => pack("U", 0xE0116), # VARIATION SELECTOR-39
+ 'VS40' => pack("U", 0xE0117), # VARIATION SELECTOR-40
+ 'VS41' => pack("U", 0xE0118), # VARIATION SELECTOR-41
+ 'VS42' => pack("U", 0xE0119), # VARIATION SELECTOR-42
+ 'VS43' => pack("U", 0xE011A), # VARIATION SELECTOR-43
+ 'VS44' => pack("U", 0xE011B), # VARIATION SELECTOR-44
+ 'VS45' => pack("U", 0xE011C), # VARIATION SELECTOR-45
+ 'VS46' => pack("U", 0xE011D), # VARIATION SELECTOR-46
+ 'VS47' => pack("U", 0xE011E), # VARIATION SELECTOR-47
+ 'VS48' => pack("U", 0xE011F), # VARIATION SELECTOR-48
+ 'VS49' => pack("U", 0xE0120), # VARIATION SELECTOR-49
+ 'VS50' => pack("U", 0xE0121), # VARIATION SELECTOR-50
+ 'VS51' => pack("U", 0xE0122), # VARIATION SELECTOR-51
+ 'VS52' => pack("U", 0xE0123), # VARIATION SELECTOR-52
+ 'VS53' => pack("U", 0xE0124), # VARIATION SELECTOR-53
+ 'VS54' => pack("U", 0xE0125), # VARIATION SELECTOR-54
+ 'VS55' => pack("U", 0xE0126), # VARIATION SELECTOR-55
+ 'VS56' => pack("U", 0xE0127), # VARIATION SELECTOR-56
+ 'VS57' => pack("U", 0xE0128), # VARIATION SELECTOR-57
+ 'VS58' => pack("U", 0xE0129), # VARIATION SELECTOR-58
+ 'VS59' => pack("U", 0xE012A), # VARIATION SELECTOR-59
+ 'VS60' => pack("U", 0xE012B), # VARIATION SELECTOR-60
+ 'VS61' => pack("U", 0xE012C), # VARIATION SELECTOR-61
+ 'VS62' => pack("U", 0xE012D), # VARIATION SELECTOR-62
+ 'VS63' => pack("U", 0xE012E), # VARIATION SELECTOR-63
+ 'VS64' => pack("U", 0xE012F), # VARIATION SELECTOR-64
+ 'VS65' => pack("U", 0xE0130), # VARIATION SELECTOR-65
+ 'VS66' => pack("U", 0xE0131), # VARIATION SELECTOR-66
+ 'VS67' => pack("U", 0xE0132), # VARIATION SELECTOR-67
+ 'VS68' => pack("U", 0xE0133), # VARIATION SELECTOR-68
+ 'VS69' => pack("U", 0xE0134), # VARIATION SELECTOR-69
+ 'VS70' => pack("U", 0xE0135), # VARIATION SELECTOR-70
+ 'VS71' => pack("U", 0xE0136), # VARIATION SELECTOR-71
+ 'VS72' => pack("U", 0xE0137), # VARIATION SELECTOR-72
+ 'VS73' => pack("U", 0xE0138), # VARIATION SELECTOR-73
+ 'VS74' => pack("U", 0xE0139), # VARIATION SELECTOR-74
+ 'VS75' => pack("U", 0xE013A), # VARIATION SELECTOR-75
+ 'VS76' => pack("U", 0xE013B), # VARIATION SELECTOR-76
+ 'VS77' => pack("U", 0xE013C), # VARIATION SELECTOR-77
+ 'VS78' => pack("U", 0xE013D), # VARIATION SELECTOR-78
+ 'VS79' => pack("U", 0xE013E), # VARIATION SELECTOR-79
+ 'VS80' => pack("U", 0xE013F), # VARIATION SELECTOR-80
+ 'VS81' => pack("U", 0xE0140), # VARIATION SELECTOR-81
+ 'VS82' => pack("U", 0xE0141), # VARIATION SELECTOR-82
+ 'VS83' => pack("U", 0xE0142), # VARIATION SELECTOR-83
+ 'VS84' => pack("U", 0xE0143), # VARIATION SELECTOR-84
+ 'VS85' => pack("U", 0xE0144), # VARIATION SELECTOR-85
+ 'VS86' => pack("U", 0xE0145), # VARIATION SELECTOR-86
+ 'VS87' => pack("U", 0xE0146), # VARIATION SELECTOR-87
+ 'VS88' => pack("U", 0xE0147), # VARIATION SELECTOR-88
+ 'VS89' => pack("U", 0xE0148), # VARIATION SELECTOR-89
+ 'VS90' => pack("U", 0xE0149), # VARIATION SELECTOR-90
+ 'VS91' => pack("U", 0xE014A), # VARIATION SELECTOR-91
+ 'VS92' => pack("U", 0xE014B), # VARIATION SELECTOR-92
+ 'VS93' => pack("U", 0xE014C), # VARIATION SELECTOR-93
+ 'VS94' => pack("U", 0xE014D), # VARIATION SELECTOR-94
+ 'VS95' => pack("U", 0xE014E), # VARIATION SELECTOR-95
+ 'VS96' => pack("U", 0xE014F), # VARIATION SELECTOR-96
+ 'VS97' => pack("U", 0xE0150), # VARIATION SELECTOR-97
+ 'VS98' => pack("U", 0xE0151), # VARIATION SELECTOR-98
+ 'VS99' => pack("U", 0xE0152), # VARIATION SELECTOR-99
+ 'VS100' => pack("U", 0xE0153), # VARIATION SELECTOR-100
+ 'VS101' => pack("U", 0xE0154), # VARIATION SELECTOR-101
+ 'VS102' => pack("U", 0xE0155), # VARIATION SELECTOR-102
+ 'VS103' => pack("U", 0xE0156), # VARIATION SELECTOR-103
+ 'VS104' => pack("U", 0xE0157), # VARIATION SELECTOR-104
+ 'VS105' => pack("U", 0xE0158), # VARIATION SELECTOR-105
+ 'VS106' => pack("U", 0xE0159), # VARIATION SELECTOR-106
+ 'VS107' => pack("U", 0xE015A), # VARIATION SELECTOR-107
+ 'VS108' => pack("U", 0xE015B), # VARIATION SELECTOR-108
+ 'VS109' => pack("U", 0xE015C), # VARIATION SELECTOR-109
+ 'VS110' => pack("U", 0xE015D), # VARIATION SELECTOR-110
+ 'VS111' => pack("U", 0xE015E), # VARIATION SELECTOR-111
+ 'VS112' => pack("U", 0xE015F), # VARIATION SELECTOR-112
+ 'VS113' => pack("U", 0xE0160), # VARIATION SELECTOR-113
+ 'VS114' => pack("U", 0xE0161), # VARIATION SELECTOR-114
+ 'VS115' => pack("U", 0xE0162), # VARIATION SELECTOR-115
+ 'VS116' => pack("U", 0xE0163), # VARIATION SELECTOR-116
+ 'VS117' => pack("U", 0xE0164), # VARIATION SELECTOR-117
+ 'VS118' => pack("U", 0xE0165), # VARIATION SELECTOR-118
+ 'VS119' => pack("U", 0xE0166), # VARIATION SELECTOR-119
+ 'VS120' => pack("U", 0xE0167), # VARIATION SELECTOR-120
+ 'VS121' => pack("U", 0xE0168), # VARIATION SELECTOR-121
+ 'VS122' => pack("U", 0xE0169), # VARIATION SELECTOR-122
+ 'VS123' => pack("U", 0xE016A), # VARIATION SELECTOR-123
+ 'VS124' => pack("U", 0xE016B), # VARIATION SELECTOR-124
+ 'VS125' => pack("U", 0xE016C), # VARIATION SELECTOR-125
+ 'VS126' => pack("U", 0xE016D), # VARIATION SELECTOR-126
+ 'VS127' => pack("U", 0xE016E), # VARIATION SELECTOR-127
+ 'VS128' => pack("U", 0xE016F), # VARIATION SELECTOR-128
+ 'VS129' => pack("U", 0xE0170), # VARIATION SELECTOR-129
+ 'VS130' => pack("U", 0xE0171), # VARIATION SELECTOR-130
+ 'VS131' => pack("U", 0xE0172), # VARIATION SELECTOR-131
+ 'VS132' => pack("U", 0xE0173), # VARIATION SELECTOR-132
+ 'VS133' => pack("U", 0xE0174), # VARIATION SELECTOR-133
+ 'VS134' => pack("U", 0xE0175), # VARIATION SELECTOR-134
+ 'VS135' => pack("U", 0xE0176), # VARIATION SELECTOR-135
+ 'VS136' => pack("U", 0xE0177), # VARIATION SELECTOR-136
+ 'VS137' => pack("U", 0xE0178), # VARIATION SELECTOR-137
+ 'VS138' => pack("U", 0xE0179), # VARIATION SELECTOR-138
+ 'VS139' => pack("U", 0xE017A), # VARIATION SELECTOR-139
+ 'VS140' => pack("U", 0xE017B), # VARIATION SELECTOR-140
+ 'VS141' => pack("U", 0xE017C), # VARIATION SELECTOR-141
+ 'VS142' => pack("U", 0xE017D), # VARIATION SELECTOR-142
+ 'VS143' => pack("U", 0xE017E), # VARIATION SELECTOR-143
+ 'VS144' => pack("U", 0xE017F), # VARIATION SELECTOR-144
+ 'VS145' => pack("U", 0xE0180), # VARIATION SELECTOR-145
+ 'VS146' => pack("U", 0xE0181), # VARIATION SELECTOR-146
+ 'VS147' => pack("U", 0xE0182), # VARIATION SELECTOR-147
+ 'VS148' => pack("U", 0xE0183), # VARIATION SELECTOR-148
+ 'VS149' => pack("U", 0xE0184), # VARIATION SELECTOR-149
+ 'VS150' => pack("U", 0xE0185), # VARIATION SELECTOR-150
+ 'VS151' => pack("U", 0xE0186), # VARIATION SELECTOR-151
+ 'VS152' => pack("U", 0xE0187), # VARIATION SELECTOR-152
+ 'VS153' => pack("U", 0xE0188), # VARIATION SELECTOR-153
+ 'VS154' => pack("U", 0xE0189), # VARIATION SELECTOR-154
+ 'VS155' => pack("U", 0xE018A), # VARIATION SELECTOR-155
+ 'VS156' => pack("U", 0xE018B), # VARIATION SELECTOR-156
+ 'VS157' => pack("U", 0xE018C), # VARIATION SELECTOR-157
+ 'VS158' => pack("U", 0xE018D), # VARIATION SELECTOR-158
+ 'VS159' => pack("U", 0xE018E), # VARIATION SELECTOR-159
+ 'VS160' => pack("U", 0xE018F), # VARIATION SELECTOR-160
+ 'VS161' => pack("U", 0xE0190), # VARIATION SELECTOR-161
+ 'VS162' => pack("U", 0xE0191), # VARIATION SELECTOR-162
+ 'VS163' => pack("U", 0xE0192), # VARIATION SELECTOR-163
+ 'VS164' => pack("U", 0xE0193), # VARIATION SELECTOR-164
+ 'VS165' => pack("U", 0xE0194), # VARIATION SELECTOR-165
+ 'VS166' => pack("U", 0xE0195), # VARIATION SELECTOR-166
+ 'VS167' => pack("U", 0xE0196), # VARIATION SELECTOR-167
+ 'VS168' => pack("U", 0xE0197), # VARIATION SELECTOR-168
+ 'VS169' => pack("U", 0xE0198), # VARIATION SELECTOR-169
+ 'VS170' => pack("U", 0xE0199), # VARIATION SELECTOR-170
+ 'VS171' => pack("U", 0xE019A), # VARIATION SELECTOR-171
+ 'VS172' => pack("U", 0xE019B), # VARIATION SELECTOR-172
+ 'VS173' => pack("U", 0xE019C), # VARIATION SELECTOR-173
+ 'VS174' => pack("U", 0xE019D), # VARIATION SELECTOR-174
+ 'VS175' => pack("U", 0xE019E), # VARIATION SELECTOR-175
+ 'VS176' => pack("U", 0xE019F), # VARIATION SELECTOR-176
+ 'VS177' => pack("U", 0xE01A0), # VARIATION SELECTOR-177
+ 'VS178' => pack("U", 0xE01A1), # VARIATION SELECTOR-178
+ 'VS179' => pack("U", 0xE01A2), # VARIATION SELECTOR-179
+ 'VS180' => pack("U", 0xE01A3), # VARIATION SELECTOR-180
+ 'VS181' => pack("U", 0xE01A4), # VARIATION SELECTOR-181
+ 'VS182' => pack("U", 0xE01A5), # VARIATION SELECTOR-182
+ 'VS183' => pack("U", 0xE01A6), # VARIATION SELECTOR-183
+ 'VS184' => pack("U", 0xE01A7), # VARIATION SELECTOR-184
+ 'VS185' => pack("U", 0xE01A8), # VARIATION SELECTOR-185
+ 'VS186' => pack("U", 0xE01A9), # VARIATION SELECTOR-186
+ 'VS187' => pack("U", 0xE01AA), # VARIATION SELECTOR-187
+ 'VS188' => pack("U", 0xE01AB), # VARIATION SELECTOR-188
+ 'VS189' => pack("U", 0xE01AC), # VARIATION SELECTOR-189
+ 'VS190' => pack("U", 0xE01AD), # VARIATION SELECTOR-190
+ 'VS191' => pack("U", 0xE01AE), # VARIATION SELECTOR-191
+ 'VS192' => pack("U", 0xE01AF), # VARIATION SELECTOR-192
+ 'VS193' => pack("U", 0xE01B0), # VARIATION SELECTOR-193
+ 'VS194' => pack("U", 0xE01B1), # VARIATION SELECTOR-194
+ 'VS195' => pack("U", 0xE01B2), # VARIATION SELECTOR-195
+ 'VS196' => pack("U", 0xE01B3), # VARIATION SELECTOR-196
+ 'VS197' => pack("U", 0xE01B4), # VARIATION SELECTOR-197
+ 'VS198' => pack("U", 0xE01B5), # VARIATION SELECTOR-198
+ 'VS199' => pack("U", 0xE01B6), # VARIATION SELECTOR-199
+ 'VS200' => pack("U", 0xE01B7), # VARIATION SELECTOR-200
+ 'VS201' => pack("U", 0xE01B8), # VARIATION SELECTOR-201
+ 'VS202' => pack("U", 0xE01B9), # VARIATION SELECTOR-202
+ 'VS203' => pack("U", 0xE01BA), # VARIATION SELECTOR-203
+ 'VS204' => pack("U", 0xE01BB), # VARIATION SELECTOR-204
+ 'VS205' => pack("U", 0xE01BC), # VARIATION SELECTOR-205
+ 'VS206' => pack("U", 0xE01BD), # VARIATION SELECTOR-206
+ 'VS207' => pack("U", 0xE01BE), # VARIATION SELECTOR-207
+ 'VS208' => pack("U", 0xE01BF), # VARIATION SELECTOR-208
+ 'VS209' => pack("U", 0xE01C0), # VARIATION SELECTOR-209
+ 'VS210' => pack("U", 0xE01C1), # VARIATION SELECTOR-210
+ 'VS211' => pack("U", 0xE01C2), # VARIATION SELECTOR-211
+ 'VS212' => pack("U", 0xE01C3), # VARIATION SELECTOR-212
+ 'VS213' => pack("U", 0xE01C4), # VARIATION SELECTOR-213
+ 'VS214' => pack("U", 0xE01C5), # VARIATION SELECTOR-214
+ 'VS215' => pack("U", 0xE01C6), # VARIATION SELECTOR-215
+ 'VS216' => pack("U", 0xE01C7), # VARIATION SELECTOR-216
+ 'VS217' => pack("U", 0xE01C8), # VARIATION SELECTOR-217
+ 'VS218' => pack("U", 0xE01C9), # VARIATION SELECTOR-218
+ 'VS219' => pack("U", 0xE01CA), # VARIATION SELECTOR-219
+ 'VS220' => pack("U", 0xE01CB), # VARIATION SELECTOR-220
+ 'VS221' => pack("U", 0xE01CC), # VARIATION SELECTOR-221
+ 'VS222' => pack("U", 0xE01CD), # VARIATION SELECTOR-222
+ 'VS223' => pack("U", 0xE01CE), # VARIATION SELECTOR-223
+ 'VS224' => pack("U", 0xE01CF), # VARIATION SELECTOR-224
+ 'VS225' => pack("U", 0xE01D0), # VARIATION SELECTOR-225
+ 'VS226' => pack("U", 0xE01D1), # VARIATION SELECTOR-226
+ 'VS227' => pack("U", 0xE01D2), # VARIATION SELECTOR-227
+ 'VS228' => pack("U", 0xE01D3), # VARIATION SELECTOR-228
+ 'VS229' => pack("U", 0xE01D4), # VARIATION SELECTOR-229
+ 'VS230' => pack("U", 0xE01D5), # VARIATION SELECTOR-230
+ 'VS231' => pack("U", 0xE01D6), # VARIATION SELECTOR-231
+ 'VS232' => pack("U", 0xE01D7), # VARIATION SELECTOR-232
+ 'VS233' => pack("U", 0xE01D8), # VARIATION SELECTOR-233
+ 'VS234' => pack("U", 0xE01D9), # VARIATION SELECTOR-234
+ 'VS235' => pack("U", 0xE01DA), # VARIATION SELECTOR-235
+ 'VS236' => pack("U", 0xE01DB), # VARIATION SELECTOR-236
+ 'VS237' => pack("U", 0xE01DC), # VARIATION SELECTOR-237
+ 'VS238' => pack("U", 0xE01DD), # VARIATION SELECTOR-238
+ 'VS239' => pack("U", 0xE01DE), # VARIATION SELECTOR-239
+ 'VS240' => pack("U", 0xE01DF), # VARIATION SELECTOR-240
+ 'VS241' => pack("U", 0xE01E0), # VARIATION SELECTOR-241
+ 'VS242' => pack("U", 0xE01E1), # VARIATION SELECTOR-242
+ 'VS243' => pack("U", 0xE01E2), # VARIATION SELECTOR-243
+ 'VS244' => pack("U", 0xE01E3), # VARIATION SELECTOR-244
+ 'VS245' => pack("U", 0xE01E4), # VARIATION SELECTOR-245
+ 'VS246' => pack("U", 0xE01E5), # VARIATION SELECTOR-246
+ 'VS247' => pack("U", 0xE01E6), # VARIATION SELECTOR-247
+ 'VS248' => pack("U", 0xE01E7), # VARIATION SELECTOR-248
+ 'VS249' => pack("U", 0xE01E8), # VARIATION SELECTOR-249
+ 'VS250' => pack("U", 0xE01E9), # VARIATION SELECTOR-250
+ 'VS251' => pack("U", 0xE01EA), # VARIATION SELECTOR-251
+ 'VS252' => pack("U", 0xE01EB), # VARIATION SELECTOR-252
+ 'VS253' => pack("U", 0xE01EC), # VARIATION SELECTOR-253
+ 'VS254' => pack("U", 0xE01ED), # VARIATION SELECTOR-254
+ 'VS255' => pack("U", 0xE01EE), # VARIATION SELECTOR-255
+ 'VS256' => pack("U", 0xE01EF), # VARIATION SELECTOR-256
+ 'WJ' => pack("U", 0x2060), # WORD JOINER
+ 'ZWJ' => pack("U", 0x200D), # ZERO WIDTH JOINER
+ 'ZWNJ' => pack("U", 0x200C), # ZERO WIDTH NON-JOINER
+ 'ZWSP' => pack("U", 0x200B), # ZERO WIDTH SPACE
);
my %deprecated_aliases = (
# Pre-3.2 compatibility (only for the first 256 characters).
# Use of these gives deprecated message.
- 'HORIZONTAL TABULATION' => 0x09, # CHARACTER TABULATION
- 'VERTICAL TABULATION' => 0x0B, # LINE TABULATION
- 'FILE SEPARATOR' => 0x1C, # INFORMATION SEPARATOR FOUR
- 'GROUP SEPARATOR' => 0x1D, # INFORMATION SEPARATOR THREE
- 'RECORD SEPARATOR' => 0x1E, # INFORMATION SEPARATOR TWO
- 'UNIT SEPARATOR' => 0x1F, # INFORMATION SEPARATOR ONE
- 'HORIZONTAL TABULATION SET' => 0x88, # CHARACTER TABULATION SET
- 'HORIZONTAL TABULATION WITH JUSTIFICATION' => 0x89, # CHARACTER TABULATION WITH JUSTIFICATION
- 'PARTIAL LINE DOWN' => 0x8B, # PARTIAL LINE FORWARD
- 'PARTIAL LINE UP' => 0x8C, # PARTIAL LINE BACKWARD
- 'VERTICAL TABULATION SET' => 0x8A, # LINE TABULATION SET
- 'REVERSE INDEX' => 0x8D, # REVERSE LINE FEED
+ 'HORIZONTAL TABULATION' => pack("U", 0x09), # CHARACTER TABULATION
+ 'VERTICAL TABULATION' => pack("U", 0x0B), # LINE TABULATION
+ 'FILE SEPARATOR' => pack("U", 0x1C), # INFORMATION SEPARATOR FOUR
+ 'GROUP SEPARATOR' => pack("U", 0x1D), # INFORMATION SEPARATOR THREE
+ 'RECORD SEPARATOR' => pack("U", 0x1E), # INFORMATION SEPARATOR TWO
+ 'UNIT SEPARATOR' => pack("U", 0x1F), # INFORMATION SEPARATOR ONE
+ 'HORIZONTAL TABULATION SET' => pack("U", 0x88), # CHARACTER TABULATION SET
+ 'HORIZONTAL TABULATION WITH JUSTIFICATION' => pack("U", 0x89), # CHARACTER TABULATION WITH JUSTIFICATION
+ 'PARTIAL LINE DOWN' => pack("U", 0x8B), # PARTIAL LINE FORWARD
+ 'PARTIAL LINE UP' => pack("U", 0x8C), # PARTIAL LINE BACKWARD
+ 'VERTICAL TABULATION SET' => pack("U", 0x8A), # LINE TABULATION SET
+ 'REVERSE INDEX' => pack("U", 0x8D), # REVERSE LINE FEED
);
@@ -461,7 +467,8 @@ sub alias (@) # Set up a single alias
$value = CORE::hex $1;
}
if ($value =~ $decimal_qr) {
- $^H{charnames_ord_aliases}{$name} = $value;
+ no warnings 'utf8'; # Allow even illegal characters
+ $^H{charnames_ord_aliases}{$name} = pack("U", $value);
# Use a canonical form.
$^H{charnames_inverse_ords}{sprintf("%05X", $value)} = $name;
@@ -475,8 +482,15 @@ sub alias (@) # Set up a single alias
} # alias
sub not_legal_use_bytes_msg {
- my ($name, $ord) = @_;
- return sprintf("Character 0x%04x with name '$name' is above 0xFF with 'use bytes' in effect", $ord);
+ my ($name, $utf8) = @_;
+ my $return;
+
+ if (length($utf8) == 1) {
+ $return = sprintf("Character 0x%04x with name '%s' is", ord $utf8, $name);
+ } else {
+ $return = sprintf("String with name '%s' (and ordinals %s) contains character(s)", $name, join(" ", map { sprintf "0x%04X", ord $_ } split(//, $utf8)));
+ }
+ return $return . " above 0xFF with 'use bytes' in effect";
}
sub alias_file ($) # Reads a file containing alias definitions
@@ -513,21 +527,28 @@ my %dummy_H = (
);
-sub lookup_name ($;$) {
+sub lookup_name ($$$) {
+ my ($name, $wants_ord, $runtime) = @_;
- # Finds the ordinal of a character name, first in the aliases, then in
- # the large table. If not found, returns undef if runtime; if
- # compile, complains and returns the Unicode replacement character.
+ # Lookup the name or sequence $name in the tables. If $wants_ord is false,
+ # returns the string equivalent of $name; if true, returns the ordinal value
+ # instead, but in this case $name must not be a sequence; otherwise undef is
+ # returned and a warning raised. $runtime is 0 if compiletime, otherwise
+ # gives the number of stack frames to go back to get the application caller
+ # info.
+ # If $name is not found, returns undef in runtime with no warning; and in
+ # compiletime, the Unicode replacement character, with a warning.
- my $runtime = (@_ > 1); # compile vs run time
-
- my ($name, $hints_ref) = @_;
+ # It looks first in the aliases, then in the large table of official Unicode
+ # names.
my $utf8; # The string result
my $save_input;
if ($runtime) {
+ my $hints_ref = (caller($runtime))[10];
+
# If we didn't import anything (which happens with 'use charnames ()',
# substitute a dummy structure.
$hints_ref = \%dummy_H if ! defined $hints_ref
@@ -562,7 +583,7 @@ sub lookup_name ($;$) {
}
elsif (exists $deprecated_aliases{$name}) {
require warnings;
- warnings::warnif('deprecated', "Unicode character name \"$name\" is deprecated, use \"" . viacode($deprecated_aliases{$name}) . "\" instead");
+ warnings::warnif('deprecated', "Unicode character name \"$name\" is deprecated, use \"" . viacode(ord $deprecated_aliases{$name}) . "\" instead");
$utf8 = $deprecated_aliases{$name};
}
@@ -579,6 +600,8 @@ sub lookup_name ($;$) {
## Suck in the code/name list as a big string.
## Lines look like:
## "00052\tLATIN CAPITAL LETTER R\n"
+ # or
+ # "0052 0303\tLATIN CAPITAL LETTER R WITH TILDE\n"
$txt = do "unicore/Name.pl" unless $txt;
## @off will hold the index into the code/name string of the start and
@@ -597,7 +620,10 @@ sub lookup_name ($;$) {
# Algorithmically determinables are not placed in the cache (that
# $found_full_in_table indicates) because that uses up memory,
# and finding these again is fast.
- if (! defined ($utf8 = name_to_code_point_special($name))) {
+ if (defined (my $ord = name_to_code_point_special($name))) {
+ $utf8 = pack("U", $ord);
+ }
+ else {
# Not algorthmically determinable; look up in the table.
if ($txt =~ /\t\Q$name\E$/m) {
@@ -632,7 +658,7 @@ sub lookup_name ($;$) {
# May have zapped input name, get it again.
$name = (defined $save_input) ? $save_input : $_[0];
carp "Unknown charname '$name'";
- return 0xFFFD;
+ return ($wants_ord) ? 0xFFFD : pack("U", 0xFFFD);
}
@off = ($-[0] + 1, $+[0]); # The 1 is for the tab
@@ -640,9 +666,28 @@ sub lookup_name ($;$) {
if (! defined $utf8) {
- # Now know where in the string the name starts.
- # The code, 5 hex digits long (and a tab), is before that.
- $utf8 = CORE::hex substr($txt, $off[0] - 6, 5);
+ # Here, we haven't set up the output, but we know where in the string
+ # the name starts. The string is set up so that for single characters
+ # (and not named sequences), the name is preceeded immediately by a
+ # tab and 5 hex digits for its code, with a \n before those. Named
+ # sequences won't have the 7th preceeding character be a \n.
+ # (Actually, for the very first entry in the table this isn't strictly
+ # true: subtracting 7 will yield -1, and the substr below will
+ # therefore yield the very last character in the table, which should
+ # also be a \n, so the statement works anyway.)
+ if (substr($txt, $off[0] - 7, 1) eq "\n") {
+ $utf8 = pack("U", CORE::hex substr($txt, $off[0] - 6, 5));
+ }
+ else {
+
+ # Here, is a named sequence. Need to go looking for the beginning,
+ # which is just after the \n from the previous entry in the table.
+ # The +1 skips past that newline, or, if the rindex() fails, to put
+ # us to an offset of zero.
+ my $charstart = rindex($txt, "\n", $off[0] - 7) + 1;
+ $utf8 = pack("U*", map { CORE::hex }
+ split " ", substr($txt, $charstart, $off[0] - $charstart - 1));
+ }
}
# Cache the input so as to not have to search the large table
@@ -651,32 +696,59 @@ sub lookup_name ($;$) {
}
}
- return $utf8 if $runtime || $utf8 <= 255 || ! ($^H & $bytes::hint_bits);
- # Here is compile time, "use bytes" is in effect, and the character
- # won't fit in a byte
- # Prefer any official name over the input one.
+ # Here, have the utf8. If the return is to be an ord, must be any single
+ # character.
+ if ($wants_ord) {
+ return ord($utf8) if length $utf8 == 1;
+ }
+ else {
+
+ # Here, wants string output. If utf8 is acceptable, just return what
+ # we've got; otherwise attempt to convert it to non-utf8 and return that.
+ my $in_bytes = ($runtime)
+ ? (caller $runtime)[8] & $bytes::hint_bits
+ : $^H & $bytes::hint_bits;
+ return $utf8 if (! $in_bytes || utf8::downgrade($utf8, 1)) # The 1 arg
+ # means don't die on failure
+ }
+
+ # Here, there is an error: either there are too many characters, or the
+ # result string needs to be non-utf8, and at least one character requires
+ # utf8. Prefer any official name over the input one for the error message.
if (@off) {
$name = substr($txt, $off[0], $off[1] - $off[0]) if @off;
}
else {
$name = (defined $save_input) ? $save_input : $_[0];
}
- croak not_legal_use_bytes_msg($name, $utf8);
+
+ if ($wants_ord) {
+ # Only way to get here in this case is if result too long. Message
+ # assumes that our only caller that requires single char result is
+ # vianame.
+ carp "charnames::vianame() doesn't handle named sequences ($name). Use charnames::string_vianame() instead";
+ return;
+ }
+
+ # Only other possible failure here is from use bytes.
+ if ($runtime) {
+ carp not_legal_use_bytes_msg($name, $utf8);
+ return;
+ } else {
+ croak not_legal_use_bytes_msg($name, $utf8);
+ }
+
} # lookup_name
sub charnames {
- my $name = shift;
# For \N{...}. Looks up the character name and returns the string
# representation of it.
- my $ord = lookup_name($name);
- return if ! defined $ord;
- return chr $ord if $^H & $bytes::hint_bits;
-
- no warnings 'utf8'; # allow even illegal characters
- return pack "U", $ord;
+ # The first 0 arg means wants a string returned; the second that we are in
+ # compile time
+ return lookup_name($_[0], 0, 0);
}
sub import
@@ -846,29 +918,62 @@ sub vianame
if ($arg =~ /^U\+([0-9a-fA-F]+)$/) {
- # khw claims that this is bad. The function should return either a
- # an ord or a chr for all inputs; not be bipolar.
+ # khw claims that this is poor interface design. The function should
+ # return either a an ord or a chr for all inputs; not be bipolar. But
+ # can't change it because of backward compatibility. New code can use
+ # string_vianame() instead.
my $ord = CORE::hex $1;
return chr $ord if $ord <= 255 || ! ((caller 0)[8] & $bytes::hint_bits);
- carp not_legal_use_bytes_msg($arg, $ord);
+ carp not_legal_use_bytes_msg($arg, chr $ord);
return;
}
- return lookup_name($arg, (caller(0))[10]);
+ # The first 1 arg means wants an ord returned; the second that we are in
+ # runtime, and this is the first level routine called from the user
+ return lookup_name($arg, 1, 1);
} # vianame
+sub string_vianame {
+
+ # Looks up the character name and returns its string representation if
+ # found, undef otherwise.
+
+ if (@_ != 1) {
+ carp "charnames::string_vianame() expects one name argument";
+ return;
+ }
+
+ my $arg = shift;
+
+ if ($arg =~ /^U\+([0-9a-fA-F]+)$/) {
+
+ my $ord = CORE::hex $1;
+ return chr $ord if $ord <= 255 || ! ((caller 0)[8] & $bytes::hint_bits);
+
+ carp not_legal_use_bytes_msg($arg, chr $ord);
+ return;
+ }
+
+ # The 0 arg means wants a string returned; the 1 arg means that we are in
+ # runtime, and this is the first level routine called from the user
+ return lookup_name($arg, 0, 1);
+} # string_vianame
+
+
1;
__END__
=head1 NAME
-charnames - access to Unicode character names; define character names for C<\N{named}> string literal escapes
+charnames - access to Unicode character names and named character sequences; also define character names
=head1 SYNOPSIS
use charnames ':full';
print "\N{GREEK SMALL LETTER SIGMA} is called sigma.\n";
+ print "\N{LATIN CAPITAL LETTER E WITH VERTICAL LINE BELOW}",
+ " is an officially named sequence of two Unicode characters\n";
use charnames ':short';
print "\N{greek:Sigma} is an upper-case sigma.\n";
@@ -887,18 +992,41 @@ charnames - access to Unicode character names; define character names for C<\N{n
print charnames::viacode(0x1234); # prints "ETHIOPIC SYLLABLE SEE"
printf "%04X", charnames::vianame("GOTHIC LETTER AHSA"); # prints
# "10330"
+ print charnames::vianame("LATIN CAPITAL LETTER A"); # prints 65 on
+ # ASCII platforms;
+ # 193 on EBCDIC
+ print charnames::string_vianame("LATIN CAPITAL LETTER A"); # prints "A"
=head1 DESCRIPTION
Pragma C<use charnames> is used to gain access to the names of the
-Unicode characters, and to allow you to define your own character names.
+Unicode characters and named character sequences, and to allow you to define
+your own character and character sequence names.
+
+All forms of the pragma enable use of the following 3 functions:
+
+=over
+
+=item *
+
+L</charnames::string_vianame(I<name>)> for run-time lookup of a
+either a character name or a named character sequence, returning its string
+representation
+
+=item *
+
+L</charnames::vianame(I<name>)> for run-time lookup of a
+character name (but not a named character sequence) to get its ordinal value
+(code point)
-All forms of the pragma enable use of the
-L</charnames::vianame(I<name>)> function for run-time lookup of a
-character name to get its ordinal (code point), and the inverse
-function, L</charnames::viacode(I<code>)>.
+=item *
-Forms other than C<S<"use charnames ();">> enable the use of of
+L</charnames::viacode(I<code>)> for run-time lookup of a code point to get its
+Unicode name.
+
+=back
+
+All forms other than C<S<"use charnames ();">> also enable the use of
C<\N{I<CHARNAME>}> sequences to compile a Unicode character into a
string, based on its name.
@@ -938,7 +1066,8 @@ is ignored.
Note that C<\N{...}> is compile-time; it's a special form of string
constant used inside double-quotish strings; this means that you cannot
use variables inside the C<\N{...}>. If you want similar run-time
-functionality, use L<charnames::vianame()|/charnames::vianame(I<name>)>.
+functionality, use
+L<charnames::string_vianame()|/charnames::string_vianame(I<name>)>.
For the C0 and C1 control characters (U+0000..U+001F, U+0080..U+009F)
there are no official Unicode names but you can use instead the ISO 6429
@@ -1151,31 +1280,33 @@ non-decimal hex digits; otherwise it will be interpreted as decimal.
Notice that the name returned for of U+FEFF is "ZERO WIDTH NO-BREAK
SPACE", not "BYTE ORDER MARK".
-=head1 charnames::vianame(I<name>)
+=head1 charnames::string_vianame(I<name>)
-Returns the code point indicated by the name.
-For example,
+This is a runtime equivalent to C<\N{...}>. I<name> can be any expression
+that evaluates to a name accepted by C<\N{...}> under the L<C<:full>
+option|/DESCRIPTION> to C<charnames>. In addition, any other options for the
+controlling C<"use charnames"> in the same scope apply, like any L<script
+list, C<:short> option|/DESCRIPTION>, or L<custom aliases|/CUSTOM ALIASES> you
+may have defined.
- printf "%04X", charnames::vianame("FOUR TEARDROP-SPOKED ASTERISK");
+The only difference is that if the input name is unknown, C<string_vianame>
+returns C<undef> instead of the REPLACEMENT CHARACTER and does not raise a
+warning message.
-prints "2722".
+=head1 charnames::vianame(I<name>)
+
+This is similar to C<string_vianame>. The main difference is that under most
+circumstances (see L</BUGS> for the others), vianame returns an ordinal code
+point, whereas C<string_vianame> returns a string. For example,
-C<vianame> takes the identical inputs that C<\N{...}> does under the
-L<C<:full> option|/DESCRIPTION> to C<charnames>. In addition, any other
-options for the controlling C<"use charnames"> in the same scope apply,
-like any L<script list, C<:short> option|/DESCRIPTION>, or L<custom
-aliases|/CUSTOM ALIASES> you may have defined.
+ printf "U+%04X", charnames::vianame("FOUR TEARDROP-SPOKED ASTERISK");
-There are just a few differences. The main one is that under
-most (see L</BUGS> for the others) circumstances, vianame returns
-an ord, whereas C<\\N{...}> is seamlessly placed as a chr into the
-string in which it appears. This leads to a second difference.
-Since an ord is returned, it can be that of any character, even one
-that isn't legal under the C<S<use bytes>> pragma.
+prints "U+2722".
-The final difference is that if the input name is unknown C<vianame>
-returns C<undef> instead of the REPLACEMENT CHARACTER, and it does not
-raise a warning message.
+This leads to the other two differences. Since a single code point is
+returned, the function can't handle named character sequences, as these are
+composed of multiple characters. And, the code point can be that of any
+character, even ones that aren't legal under the C<S<use bytes>> pragma,
=head1 CUSTOM TRANSLATORS
@@ -1221,11 +1352,6 @@ Names must be ASCII characters only, which means that you are out of luck if
you want to create aliases in a language where some or all the characters of
the desired aliases are non-ASCII.
-Unicode standard named sequences are not recognized, such as
-C<LATIN CAPITAL LETTER A WITH MACRON AND GRAVE>
-(which should mean C<LATIN CAPITAL LETTER A WITH MACRON> with an additional
-C<COMBINING GRAVE ACCENT>).
-
Since evaluation of the translation function (see L</CUSTOM
TRANSLATORS>) happens in the middle of compilation (of a string
literal), the translation function should not do any C<eval>s or