1 package Unicode::Normalize;
4 unless ("A" eq pack('U', 0x41)) {
5 die "Unicode::Normalize cannot stringify a Unicode code point\n";
16 our $VERSION = '1.06';
17 our $PACKAGE = __PACKAGE__;
19 our @EXPORT = qw( NFC NFD NFKC NFKD );
21 normalize decompose reorder compose
22 checkNFD checkNFKD checkNFC checkNFKC check
23 getCanon getCompat getComposite getCombinClass
24 isExclusion isSingleton isNonStDecomp isComp2nd isComp_Ex
25 isNFD_NO isNFC_NO isNFC_MAYBE isNFKD_NO isNFKC_NO isNFKC_MAYBE
26 FCD checkFCD FCC checkFCC composeContiguous splitOnLastStarter
27 normalize_partial NFC_partial NFD_partial NFKC_partial NFKD_partial
30 all => [ @EXPORT, @EXPORT_OK ],
31 normalize => [ @EXPORT, qw/normalize decompose reorder compose/ ],
32 check => [ qw/checkNFD checkNFKD checkNFC checkNFKC check/ ],
33 fast => [ qw/FCD checkFCD FCC checkFCC composeContiguous/ ],
41 return pack('U*', @_);
45 return unpack('U*', shift(@_).pack('U*'));
50 ##### The above part is common to XS and PP #####
52 our @ISA = qw(Exporter DynaLoader);
54 bootstrap Unicode::Normalize $VERSION;
56 ##### The below part is common to XS and PP #####
64 return checkFCD($str) ? $str : NFD($str);
68 NFC => \&NFC, C => \&NFC,
69 NFD => \&NFD, D => \&NFD,
70 NFKC => \&NFKC, KC => \&NFKC,
71 NFKD => \&NFKD, KD => \&NFKD,
72 FCD => \&FCD, FCC => \&FCC,
79 if (exists $formNorm{$form}) {
80 return $formNorm{$form}->($str);
82 croak($PACKAGE."::normalize: invalid form name: $form");
89 sub normalize_partial ($$) {
90 if (exists $formNorm{$_[0]}) {
91 my $n = normalize($_[0], $_[1]);
92 my($p, $u) = splitOnLastStarter($n);
96 croak($PACKAGE."::normalize_partial: invalid form name: $_[0]");
99 sub NFD_partial ($) { return normalize_partial('NFD', $_[0]) }
100 sub NFC_partial ($) { return normalize_partial('NFC', $_[0]) }
101 sub NFKD_partial($) { return normalize_partial('NFKD',$_[0]) }
102 sub NFKC_partial($) { return normalize_partial('NFKC',$_[0]) }
109 NFC => \&checkNFC, C => \&checkNFC,
110 NFD => \&checkNFD, D => \&checkNFD,
111 NFKC => \&checkNFKC, KC => \&checkNFKC,
112 NFKD => \&checkNFKD, KD => \&checkNFKD,
113 FCD => \&checkFCD, FCC => \&checkFCC,
120 if (exists $formCheck{$form}) {
121 return $formCheck{$form}->($str);
123 croak($PACKAGE."::check: invalid form name: $form");
131 Unicode::Normalize - Unicode Normalization Forms
135 (1) using function names exported by default:
137 use Unicode::Normalize;
139 $NFD_string = NFD($string); # Normalization Form D
140 $NFC_string = NFC($string); # Normalization Form C
141 $NFKD_string = NFKD($string); # Normalization Form KD
142 $NFKC_string = NFKC($string); # Normalization Form KC
144 (2) using function names exported on request:
146 use Unicode::Normalize 'normalize';
148 $NFD_string = normalize('D', $string); # Normalization Form D
149 $NFC_string = normalize('C', $string); # Normalization Form C
150 $NFKD_string = normalize('KD', $string); # Normalization Form KD
151 $NFKC_string = normalize('KC', $string); # Normalization Form KC
157 C<$string> is used as a string under character semantics (see F<perlunicode>).
159 C<$code_point> should be an unsigned integer representing a Unicode code point.
161 Note: Between XSUB and pure Perl, there is an incompatibility
162 about the interpretation of C<$code_point> as a decimal number.
163 XSUB converts C<$code_point> to an unsigned integer, but pure Perl does not.
164 Do not use a floating point nor a negative sign in C<$code_point>.
166 =head2 Normalization Forms
170 =item C<$NFD_string = NFD($string)>
172 It returns the Normalization Form D (formed by canonical decomposition).
174 =item C<$NFC_string = NFC($string)>
176 It returns the Normalization Form C (formed by canonical decomposition
177 followed by canonical composition).
179 =item C<$NFKD_string = NFKD($string)>
181 It returns the Normalization Form KD (formed by compatibility decomposition).
183 =item C<$NFKC_string = NFKC($string)>
185 It returns the Normalization Form KC (formed by compatibility decomposition
186 followed by B<canonical> composition).
188 =item C<$FCD_string = FCD($string)>
190 If the given string is in FCD ("Fast C or D" form; cf. UTN #5),
191 it returns the string without modification; otherwise it returns an FCD string.
193 Note: FCD is not always unique, then plural forms may be equivalent
194 each other. C<FCD()> will return one of these equivalent forms.
196 =item C<$FCC_string = FCC($string)>
198 It returns the FCC form ("Fast C Contiguous"; cf. UTN #5).
200 Note: FCC is unique, as well as four normalization forms (NF*).
202 =item C<$normalized_string = normalize($form_name, $string)>
204 It returns the normalization form of C<$form_name>.
206 As C<$form_name>, one of the following names must be given.
208 'C' or 'NFC' for Normalization Form C (UAX #15)
209 'D' or 'NFD' for Normalization Form D (UAX #15)
210 'KC' or 'NFKC' for Normalization Form KC (UAX #15)
211 'KD' or 'NFKD' for Normalization Form KD (UAX #15)
213 'FCD' for "Fast C or D" Form (UTN #5)
214 'FCC' for "Fast C Contiguous" (UTN #5)
218 =head2 Decomposition and Composition
222 =item C<$decomposed_string = decompose($string [, $useCompatMapping])>
224 It returns the concatenation of the decomposition of each character
227 If the second parameter (a boolean) is omitted or false,
228 the decomposition is canonical decomposition;
229 if the second parameter (a boolean) is true,
230 the decomposition is compatibility decomposition.
232 The string returned is not always in NFD/NFKD. Reordering may be required.
234 $NFD_string = reorder(decompose($string)); # eq. to NFD()
235 $NFKD_string = reorder(decompose($string, TRUE)); # eq. to NFKD()
237 =item C<$reordered_string = reorder($string)>
239 It returns the result of reordering the combining characters
240 according to Canonical Ordering Behavior.
242 For example, when you have a list of NFD/NFKD strings,
243 you can get the concatenated NFD/NFKD string from them, by saying
245 $concat_NFD = reorder(join '', @NFD_strings);
246 $concat_NFKD = reorder(join '', @NFKD_strings);
248 =item C<$composed_string = compose($string)>
250 It returns the result of canonical composition
251 without applying any decomposition.
253 For example, when you have a NFD/NFKD string,
254 you can get its NFC/NFKC string, by saying
256 $NFC_string = compose($NFD_string);
257 $NFKC_string = compose($NFKD_string);
259 =item C<($processed, $unprocessed) = splitOnLastStarter($normalized)>
261 It returns two strings: the first one, C<$processed>, is a part
262 before the last starter, and the second one, C<$unprocessed> is
263 another part after the first part. A starter is a character having
264 a combining class of zero (see UAX #15).
266 Note that C<$processed> may be empty (when C<$normalized> contains no
267 starter or starts with the last starter), and then C<$unprocessed>
268 should be equal to the entire C<$normalized>.
270 When you have a C<$normalized> string and an C<$unnormalized> string
271 following it, a simple concatenation is wrong:
273 $concat = $normalized . normalize($form, $unnormalized); # wrong!
275 Instead of it, do like this:
277 ($processed, $unprocessed) = splitOnLastStarter($normalized);
278 $concat = $processed . normalize($form, $unprocessed.$unnormalized);
280 C<splitOnLastStarter()> should be called with a pre-normalized parameter
281 C<$normalized>, that is in the same form as C<$form> you want.
283 If you have an array of C<@string> that should be concatenated and then
284 normalized, you can do like this:
288 foreach my $str (@string) {
290 my $n = normalize($form, $unproc);
291 my($p, $u) = splitOnLastStarter($n);
296 # instead of normalize($form, join('', @string))
298 =item C<$processed = normalize_partial($form, $unprocessed)>
300 A wrapper for the combination of C<normalize()> and C<splitOnLastStarter()>.
301 Note that C<$unprocessed> will be modified as a side-effect.
303 If you have an array of C<@string> that should be concatenated and then
304 normalized, you can do like this:
308 foreach my $str (@string) {
310 $result .= normalize_partial($form, $unproc);
313 # instead of normalize($form, join('', @string))
315 =item C<$processed = NFD_partial($unprocessed)>
317 It does like C<normalize_partial('NFD', $unprocessed)>.
318 Note that C<$unprocessed> will be modified as a side-effect.
320 =item C<$processed = NFC_partial($unprocessed)>
322 It does like C<normalize_partial('NFC', $unprocessed)>.
323 Note that C<$unprocessed> will be modified as a side-effect.
325 =item C<$processed = NFKD_partial($unprocessed)>
327 It does like C<normalize_partial('NFKD', $unprocessed)>.
328 Note that C<$unprocessed> will be modified as a side-effect.
330 =item C<$processed = NFKC_partial($unprocessed)>
332 It does like C<normalize_partial('NFKC', $unprocessed)>.
333 Note that C<$unprocessed> will be modified as a side-effect.
339 (see Annex 8, UAX #15; and F<DerivedNormalizationProps.txt>)
341 The following functions check whether the string is in that normalization form.
343 The result returned will be one of the following:
345 YES The string is in that normalization form.
346 NO The string is not in that normalization form.
347 MAYBE Dubious. Maybe yes, maybe no.
351 =item C<$result = checkNFD($string)>
353 It returns true (C<1>) if C<YES>; false (C<empty string>) if C<NO>.
355 =item C<$result = checkNFC($string)>
357 It returns true (C<1>) if C<YES>; false (C<empty string>) if C<NO>;
358 C<undef> if C<MAYBE>.
360 =item C<$result = checkNFKD($string)>
362 It returns true (C<1>) if C<YES>; false (C<empty string>) if C<NO>.
364 =item C<$result = checkNFKC($string)>
366 It returns true (C<1>) if C<YES>; false (C<empty string>) if C<NO>;
367 C<undef> if C<MAYBE>.
369 =item C<$result = checkFCD($string)>
371 It returns true (C<1>) if C<YES>; false (C<empty string>) if C<NO>.
373 =item C<$result = checkFCC($string)>
375 It returns true (C<1>) if C<YES>; false (C<empty string>) if C<NO>;
376 C<undef> if C<MAYBE>.
378 Note: If a string is not in FCD, it must not be in FCC.
379 So C<checkFCC($not_FCD_string)> should return C<NO>.
381 =item C<$result = check($form_name, $string)>
383 It returns true (C<1>) if C<YES>; false (C<empty string>) if C<NO>;
384 C<undef> if C<MAYBE>.
386 As C<$form_name>, one of the following names must be given.
388 'C' or 'NFC' for Normalization Form C (UAX #15)
389 'D' or 'NFD' for Normalization Form D (UAX #15)
390 'KC' or 'NFKC' for Normalization Form KC (UAX #15)
391 'KD' or 'NFKD' for Normalization Form KD (UAX #15)
393 'FCD' for "Fast C or D" Form (UTN #5)
394 'FCC' for "Fast C Contiguous" (UTN #5)
400 In the cases of NFD, NFKD, and FCD, the answer must be
401 either C<YES> or C<NO>. The answer C<MAYBE> may be returned
402 in the cases of NFC, NFKC, and FCC.
404 A C<MAYBE> string should contain at least one combining character
405 or the like. For example, C<COMBINING ACUTE ACCENT> has
406 the MAYBE_NFC/MAYBE_NFKC property.
408 Both C<checkNFC("A\N{COMBINING ACUTE ACCENT}")>
409 and C<checkNFC("B\N{COMBINING ACUTE ACCENT}")> will return C<MAYBE>.
410 C<"A\N{COMBINING ACUTE ACCENT}"> is not in NFC
411 (its NFC is C<"\N{LATIN CAPITAL LETTER A WITH ACUTE}">),
412 while C<"B\N{COMBINING ACUTE ACCENT}"> is in NFC.
414 If you want to check exactly, compare the string with its NFC/NFKC/FCC.
416 if ($string eq NFC($string)) {
417 # $string is exactly normalized in NFC;
419 # $string is not normalized in NFC;
422 if ($string eq NFKC($string)) {
423 # $string is exactly normalized in NFKC;
425 # $string is not normalized in NFKC;
428 =head2 Character Data
430 These functions are interface of character data used internally.
431 If you want only to get Unicode normalization forms, you don't need
436 =item C<$canonical_decomposition = getCanon($code_point)>
438 If the character is canonically decomposable (including Hangul Syllables),
439 it returns the (full) canonical decomposition as a string.
440 Otherwise it returns C<undef>.
442 B<Note:> According to the Unicode standard, the canonical decomposition
443 of the character that is not canonically decomposable is same as
444 the character itself.
446 =item C<$compatibility_decomposition = getCompat($code_point)>
448 If the character is compatibility decomposable (including Hangul Syllables),
449 it returns the (full) compatibility decomposition as a string.
450 Otherwise it returns C<undef>.
452 B<Note:> According to the Unicode standard, the compatibility decomposition
453 of the character that is not compatibility decomposable is same as
454 the character itself.
456 =item C<$code_point_composite = getComposite($code_point_here, $code_point_next)>
458 If two characters here and next (as code points) are composable
459 (including Hangul Jamo/Syllables and Composition Exclusions),
460 it returns the code point of the composite.
462 If they are not composable, it returns C<undef>.
464 =item C<$combining_class = getCombinClass($code_point)>
466 It returns the combining class (as an integer) of the character.
468 =item C<$may_be_composed_with_prev_char = isComp2nd($code_point)>
470 It returns a boolean whether the character of the specified codepoint
471 may be composed with the previous one in a certain composition
472 (including Hangul Compositions, but excluding
473 Composition Exclusions and Non-Starter Decompositions).
475 =item C<$is_exclusion = isExclusion($code_point)>
477 It returns a boolean whether the code point is a composition exclusion.
479 =item C<$is_singleton = isSingleton($code_point)>
481 It returns a boolean whether the code point is a singleton
483 =item C<$is_non_starter_decomposition = isNonStDecomp($code_point)>
485 It returns a boolean whether the code point has Non-Starter Decomposition.
487 =item C<$is_Full_Composition_Exclusion = isComp_Ex($code_point)>
489 It returns a boolean of the derived property Comp_Ex
490 (Full_Composition_Exclusion). This property is generated from
491 Composition Exclusions + Singletons + Non-Starter Decompositions.
493 =item C<$NFD_is_NO = isNFD_NO($code_point)>
495 It returns a boolean of the derived property NFD_NO
496 (NFD_Quick_Check=No).
498 =item C<$NFC_is_NO = isNFC_NO($code_point)>
500 It returns a boolean of the derived property NFC_NO
501 (NFC_Quick_Check=No).
503 =item C<$NFC_is_MAYBE = isNFC_MAYBE($code_point)>
505 It returns a boolean of the derived property NFC_MAYBE
506 (NFC_Quick_Check=Maybe).
508 =item C<$NFKD_is_NO = isNFKD_NO($code_point)>
510 It returns a boolean of the derived property NFKD_NO
511 (NFKD_Quick_Check=No).
513 =item C<$NFKC_is_NO = isNFKC_NO($code_point)>
515 It returns a boolean of the derived property NFKC_NO
516 (NFKC_Quick_Check=No).
518 =item C<$NFKC_is_MAYBE = isNFKC_MAYBE($code_point)>
520 It returns a boolean of the derived property NFKC_MAYBE
521 (NFKC_Quick_Check=Maybe).
527 C<NFC>, C<NFD>, C<NFKC>, C<NFKD>: by default.
529 C<normalize> and other some functions: on request.
535 =item Perl's version vs. Unicode version
537 Since this module refers to perl core's Unicode database in the directory
538 F</lib/unicore> (or formerly F</lib/unicode>), the Unicode version of
539 normalization implemented by this module depends on your perl's version.
541 perl's version implemented Unicode version
544 5.7.3 3.1.1 (normalization is same as 3.1.0)
547 5.8.4-5.8.6 4.0.1 (normalization is same as 4.0.0)
552 =item Correction of decomposition mapping
554 In older Unicode versions, a small number of characters (all of which are
555 CJK compatibility ideographs as far as they have been found) may have
556 an erroneous decomposition mapping (see F<NormalizationCorrections.txt>).
557 Anyhow, this module will neither refer to F<NormalizationCorrections.txt>
558 nor provide any specific version of normalization. Therefore this module
559 running on an older perl with an older Unicode database may use
560 the erroneous decomposition mapping blindly conforming to the Unicode database.
562 =item Revised definition of canonical composition
564 In Unicode 4.1.0, the definition D2 of canonical composition (which
565 affects NFC and NFKC) has been changed (see Public Review Issue #29
566 and recent UAX #15). This module has used the newer definition
567 since the version 0.07 (Oct 31, 2001).
568 This module will not support the normalization according to the older
569 definition, even if the Unicode version implemented by perl is
576 SADAHIRO Tomoyuki <SADAHIRO@cpan.org>
578 Copyright(C) 2001-2010, SADAHIRO Tomoyuki. Japan. All rights reserved.
580 This module is free software; you can redistribute it
581 and/or modify it under the same terms as Perl itself.
587 =item http://www.unicode.org/reports/tr15/
589 Unicode Normalization Forms - UAX #15
591 =item http://www.unicode.org/Public/UNIDATA/CompositionExclusions.txt
593 Composition Exclusion Table
595 =item http://www.unicode.org/Public/UNIDATA/DerivedNormalizationProps.txt
597 Derived Normalization Properties
599 =item http://www.unicode.org/Public/UNIDATA/NormalizationCorrections.txt
601 Normalization Corrections
603 =item http://www.unicode.org/review/pr-29.html
605 Public Review Issue #29: Normalization Issue
607 =item http://www.unicode.org/notes/tn5/
609 Canonical Equivalence in Applications - UTN #5