This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Sync with Unicode::Normalize 0.25
[perl5.git] / ext / Unicode / Normalize / Normalize.pm
1 package Unicode::Normalize;
2
3 BEGIN {
4     unless ("A" eq pack('U', 0x41)) {
5         die "Unicode::Normalize cannot stringify a Unicode code point\n";
6     }
7 }
8
9 use 5.006;
10 use strict;
11 use warnings;
12 use Carp;
13
14 our $VERSION = '0.25';
15 our $PACKAGE = __PACKAGE__;
16
17 require Exporter;
18 require DynaLoader;
19
20 our @ISA = qw(Exporter DynaLoader);
21 our @EXPORT = qw( NFC NFD NFKC NFKD );
22 our @EXPORT_OK = qw(
23     normalize decompose reorder compose
24     checkNFD checkNFKD checkNFC checkNFKC check
25     getCanon getCompat getComposite getCombinClass
26     isExclusion isSingleton isNonStDecomp isComp2nd isComp_Ex
27     isNFD_NO isNFC_NO isNFC_MAYBE isNFKD_NO isNFKC_NO isNFKC_MAYBE
28     FCD checkFCD FCC checkFCC composeContiguous
29     splitOnLastStarter
30 );
31 our %EXPORT_TAGS = (
32     all       => [ @EXPORT, @EXPORT_OK ],
33     normalize => [ @EXPORT, qw/normalize decompose reorder compose/ ],
34     check     => [ qw/checkNFD checkNFKD checkNFC checkNFKC check/ ],
35     fast      => [ qw/FCD checkFCD FCC checkFCC composeContiguous/ ],
36 );
37
38 ######
39
40 bootstrap Unicode::Normalize $VERSION;
41
42 ######
43
44 sub pack_U {
45     return pack('U*', @_);
46 }
47
48 sub unpack_U {
49     return unpack('U*', pack('U*').shift);
50 }
51
52
53 ##
54 ## normalization forms
55 ##
56
57 use constant COMPAT => 1;
58
59 sub NFD  ($) { reorder(decompose($_[0])) }
60 sub NFKD ($) { reorder(decompose($_[0], COMPAT)) }
61 sub NFC  ($) { compose(reorder(decompose($_[0]))) }
62 sub NFKC ($) { compose(reorder(decompose($_[0], COMPAT))) }
63
64 sub FCD ($) {
65     my $str = shift;
66     return checkFCD($str) ? $str : NFD($str);
67 }
68 sub FCC ($) { composeContiguous(reorder(decompose($_[0]))) }
69
70 our %formNorm = (
71     NFC  => \&NFC,      C  => \&NFC,
72     NFD  => \&NFD,      D  => \&NFD,
73     NFKC => \&NFKC,     KC => \&NFKC,
74     NFKD => \&NFKD,     KD => \&NFKD,
75     FCD  => \&FCD,      FCC => \&FCC,
76 );
77
78 sub normalize($$)
79 {
80     my $form = shift;
81     my $str = shift;
82     return exists $formNorm{$form} 
83         ? $formNorm{$form}->($str)
84         : croak $PACKAGE."::normalize: invalid form name: $form";
85 }
86
87
88 ##
89 ## quick check
90 ##
91
92 our %formCheck = (
93     NFC  => \&checkNFC,         C  => \&checkNFC,
94     NFD  => \&checkNFD,         D  => \&checkNFD,
95     NFKC => \&checkNFKC,        KC => \&checkNFKC,
96     NFKD => \&checkNFKD,        KD => \&checkNFKD,
97     FCD  => \&checkFCD,         FCC => \&checkFCC,
98 );
99
100 sub check($$)
101 {
102     my $form = shift;
103     my $str = shift;
104     return exists $formCheck{$form} 
105         ? $formCheck{$form}->($str)
106         : croak $PACKAGE."::check: invalid form name: $form";
107 }
108
109 1;
110 __END__
111
112 =head1 NAME
113
114 Unicode::Normalize - Unicode Normalization Forms
115
116 =head1 SYNOPSIS
117
118   use Unicode::Normalize;
119
120   $NFD_string  = NFD($string);  # Normalization Form D
121   $NFC_string  = NFC($string);  # Normalization Form C
122   $NFKD_string = NFKD($string); # Normalization Form KD
123   $NFKC_string = NFKC($string); # Normalization Form KC
124
125    or
126
127   use Unicode::Normalize 'normalize';
128
129   $NFD_string  = normalize('D',  $string);  # Normalization Form D
130   $NFC_string  = normalize('C',  $string);  # Normalization Form C
131   $NFKD_string = normalize('KD', $string);  # Normalization Form KD
132   $NFKC_string = normalize('KC', $string);  # Normalization Form KC
133
134 =head1 DESCRIPTION
135
136 Parameters:
137
138 C<$string> is used as a string under character semantics
139 (see F<perlunicode>).
140
141 C<$codepoint> should be an unsigned integer
142 representing a Unicode code point.
143
144 Note: Between XS edition and pure Perl edition,
145 interpretation of C<$codepoint> as a decimal number has incompatibility.
146 XS converts C<$codepoint> to an unsigned integer, but pure Perl does not.
147 Do not use a floating point nor a negative sign in C<$codepoint>.
148
149 =head2 Normalization Forms
150
151 =over 4
152
153 =item C<$NFD_string = NFD($string)>
154
155 returns the Normalization Form D (formed by canonical decomposition).
156
157 =item C<$NFC_string = NFC($string)>
158
159 returns the Normalization Form C (formed by canonical decomposition
160 followed by canonical composition).
161
162 =item C<$NFKD_string = NFKD($string)>
163
164 returns the Normalization Form KD (formed by compatibility decomposition).
165
166 =item C<$NFKC_string = NFKC($string)>
167
168 returns the Normalization Form KC (formed by compatibility decomposition
169 followed by B<canonical> composition).
170
171 =item C<$FCD_string = FCD($string)>
172
173 If the given string is in FCD ("Fast C or D" form; cf. UTN #5),
174 returns it without modification; otherwise returns an FCD string.
175
176 Note: FCD is not always unique, then plural forms may be equivalent
177 each other. C<FCD()> will return one of these equivalent forms.
178
179 =item C<$FCC_string = FCC($string)>
180
181 returns the FCC form ("Fast C Contiguous"; cf. UTN #5).
182
183 Note: FCD is unique, as well as four normalization forms (NF*).
184
185 =item C<$normalized_string = normalize($form_name, $string)>
186
187 As C<$form_name>, one of the following names must be given.
188
189   'C'  or 'NFC'  for Normalization Form C  (UAX #15)
190   'D'  or 'NFD'  for Normalization Form D  (UAX #15)
191   'KC' or 'NFKC' for Normalization Form KC (UAX #15)
192   'KD' or 'NFKD' for Normalization Form KD (UAX #15)
193
194   'FCD'          for "Fast C or D" Form  (UTN #5)
195   'FCC'          for "Fast C Contiguous" (UTN #5)
196
197 =back
198
199 =head2 Decomposition and Composition
200
201 =over 4
202
203 =item C<$decomposed_string = decompose($string)>
204
205 =item C<$decomposed_string = decompose($string, $useCompatMapping)>
206
207 Decomposes the specified string and returns the result.
208
209 If the second parameter (a boolean) is omitted or false, decomposes it
210 using the Canonical Decomposition Mapping.
211 If true, decomposes it using the Compatibility Decomposition Mapping.
212
213 The string returned is not always in NFD/NFKD.
214 Reordering may be required.
215
216     $NFD_string  = reorder(decompose($string));       # eq. to NFD()
217     $NFKD_string = reorder(decompose($string, TRUE)); # eq. to NFKD()
218
219 =item C<$reordered_string  = reorder($string)>
220
221 Reorders the combining characters and the like in the canonical ordering
222 and returns the result.
223
224 E.g., when you have a list of NFD/NFKD strings,
225 you can get the concatenated NFD/NFKD string from them, saying
226
227     $concat_NFD  = reorder(join '', @NFD_strings);
228     $concat_NFKD = reorder(join '', @NFKD_strings);
229
230 =item C<$composed_string   = compose($string)>
231
232 Returns the string where composable pairs are composed.
233
234 E.g., when you have a NFD/NFKD string,
235 you can get its NFC/NFKC string, saying
236
237     $NFC_string  = compose($NFD_string);
238     $NFKC_string = compose($NFKD_string);
239
240 =back
241
242 =head2 Quick Check
243
244 (see Annex 8, UAX #15; and F<DerivedNormalizationProps.txt>)
245
246 The following functions check whether the string is in that normalization form.
247
248 The result returned will be:
249
250     YES     The string is in that normalization form.
251     NO      The string is not in that normalization form.
252     MAYBE   Dubious. Maybe yes, maybe no.
253
254 =over 4
255
256 =item C<$result = checkNFD($string)>
257
258 returns C<YES> (C<1>) or C<NO> (C<empty string>).
259
260 =item C<$result = checkNFC($string)>
261
262 returns C<YES> (C<1>), C<NO> (C<empty string>), or C<MAYBE> (C<undef>).
263
264 =item C<$result = checkNFKD($string)>
265
266 returns C<YES> (C<1>) or C<NO> (C<empty string>).
267
268 =item C<$result = checkNFKC($string)>
269
270 returns C<YES> (C<1>), C<NO> (C<empty string>), or C<MAYBE> (C<undef>).
271
272 =item C<$result = checkFCD($string)>
273
274 returns C<YES> (C<1>) or C<NO> (C<empty string>).
275
276 =item C<$result = checkFCC($string)>
277
278 returns C<YES> (C<1>), C<NO> (C<empty string>), or C<MAYBE> (C<undef>).
279
280 If a string is not in C<FCD>, it must not be in <FCC>.
281 So C<checkFCC($not_FCD_string)> should return C<NO>.
282
283 =item C<$result = check($form_name, $string)>
284
285 returns C<YES> (C<1>), C<NO> (C<empty string>), or C<MAYBE> (C<undef>).
286
287 C<$form_name> is alike to that for C<normalize()>.
288
289 =back
290
291 B<Note>
292
293 In the cases of NFD, NFKD, and FCD, the answer must be
294 either C<YES> or C<NO>. The answer C<MAYBE> may be returned
295 in the cases of NFC, NFKC, and FCC.
296
297 A C<MAYBE> string should contain at least one combining character
298 or the like. For example, C<COMBINING ACUTE ACCENT> has
299 the MAYBE_NFC/MAYBE_NFKC property.
300
301 Both C<checkNFC("A\N{COMBINING ACUTE ACCENT}")>
302 and C<checkNFC("B\N{COMBINING ACUTE ACCENT}")> will return C<MAYBE>.
303 C<"A\N{COMBINING ACUTE ACCENT}"> is not in NFC
304 (its NFC is C<"\N{LATIN CAPITAL LETTER A WITH ACUTE}">),
305 while C<"B\N{COMBINING ACUTE ACCENT}"> is in NFC.
306
307 If you want to check exactly, compare the string with its NFC/NFKC/FCC;
308 i.e.,
309
310     $string eq NFC($string)    # thorough than checkNFC($string)
311     $string eq NFKC($string)   # thorough than checkNFKC($string)
312     $string eq FCC($string)    # thorough than checkFCC($string)
313
314 =head2 Character Data
315
316 These functions are interface of character data used internally.
317 If you want only to get Unicode normalization forms, you don't need
318 call them yourself.
319
320 =over 4
321
322 =item C<$canonical_decomposed = getCanon($codepoint)>
323
324 If the character of the specified codepoint is canonically
325 decomposable (including Hangul Syllables),
326 returns the B<completely decomposed> string canonically equivalent to it.
327
328 If it is not decomposable, returns C<undef>.
329
330 =item C<$compatibility_decomposed = getCompat($codepoint)>
331
332 If the character of the specified codepoint is compatibility
333 decomposable (including Hangul Syllables),
334 returns the B<completely decomposed> string compatibility equivalent to it.
335
336 If it is not decomposable, returns C<undef>.
337
338 =item C<$codepoint_composite = getComposite($codepoint_here, $codepoint_next)>
339
340 If two characters here and next (as codepoints) are composable
341 (including Hangul Jamo/Syllables and Composition Exclusions),
342 returns the codepoint of the composite.
343
344 If they are not composable, returns C<undef>.
345
346 =item C<$combining_class = getCombinClass($codepoint)>
347
348 Returns the combining class of the character as an integer.
349
350 =item C<$is_exclusion = isExclusion($codepoint)>
351
352 Returns a boolean whether the character of the specified codepoint
353 is a composition exclusion.
354
355 =item C<$is_singleton = isSingleton($codepoint)>
356
357 Returns a boolean whether the character of the specified codepoint is
358 a singleton.
359
360 =item C<$is_non_starter_decomposition = isNonStDecomp($codepoint)>
361
362 Returns a boolean whether the canonical decomposition
363 of the character of the specified codepoint
364 is a Non-Starter Decomposition.
365
366 =item C<$may_be_composed_with_prev_char = isComp2nd($codepoint)>
367
368 Returns a boolean whether the character of the specified codepoint
369 may be composed with the previous one in a certain composition
370 (including Hangul Compositions, but excluding
371 Composition Exclusions and Non-Starter Decompositions).
372
373 =back
374
375 =head2 EXPORT
376
377 C<NFC>, C<NFD>, C<NFKC>, C<NFKD>: by default.
378
379 C<normalize> and other some functions: on request.
380
381 =head1 AUTHOR
382
383 SADAHIRO Tomoyuki, <SADAHIRO@cpan.org>
384
385   http://homepage1.nifty.com/nomenclator/perl/
386
387   Copyright(C) 2001-2003, SADAHIRO Tomoyuki. Japan. All rights reserved.
388
389   This module is free software; you can redistribute it
390   and/or modify it under the same terms as Perl itself.
391
392 =head1 SEE ALSO
393
394 =over 4
395
396 =item http://www.unicode.org/unicode/reports/tr15/
397
398 Unicode Normalization Forms - UAX #15
399
400 =item http://www.unicode.org/Public/UNIDATA/DerivedNormalizationProps.txt
401
402 Derived Normalization Properties
403
404 =item http://www.unicode.org/notes/tn5/
405
406 Canonical Equivalence in Applications - UTN #5
407
408 =back
409
410 =cut
411