<div dir="ltr"><div>Hi Addison,</div><div><br></div><div>Thank you for the link, the examples were very useful. And the more I look at them, I become increasingly convinced that the compatibility caseless match transform</div><div><br></div><div>NFKD(toCasefold(NFKD(toCasefold(NFD(X)))))</div><div><br></div><div>is unnecessary excessive.<br></div><div></div><div><br></div><div>The second (outer) casefold+normalization cycle can be avoided if we perform the initial NFKD normalization *before* the first casefold. Doing compatibility decomposition before the casefolding eliminates the problem with the U+3392 character illustrated in example 19. And since it's recommended to decompose before the initial casefold anyway (the Greek ypogegrammeni/iota issue), NFKD normalization as the first step also covers that case.</div><div><br></div><div>As a result, the transform is reduced from 3 normalizations + 2 casefolds to 2 normalizations and 1 casefold:</div><div><br></div><div>NFKD(toCasefold(NFKD(toCasefold(NFD(X))))) --> NFC(toCasefold(NFKD(X)))</div><div><br></div><div>Am I missing any non-trivial cases? For the examples on the mentioned page, as well as for the other "problematic" cases I've seen in other places, this lighter transform produces the same output as the more expensive one from the standard.<br></div><div></div><div><div><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr">Kind regards,<br>Yuri</div></div></div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Mar 12, 2024 at 5:44 PM Addison Phillips <<a href="mailto:addisoni18n@gmail.com" target="_blank">addisoni18n@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div lang="EN-US"><div><p class="MsoNormal"><span style="font-size:11pt">Hi Yuri,<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11pt">The part of the W3C “Character Model” called “String Matching for the Web” illustrates the case in this section:<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11pt"><a href="https://www.w3.org/TR/charmod-norm/#normalizationAndCasefold" target="_blank">https://www.w3.org/TR/charmod-norm/#normalizationAndCasefold</a><u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11pt">You might find the rest of the document useful in your work as well.<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11pt">Best regards,<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11pt">Addison<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11pt">Addison Phillips<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11pt">Chair (W3C Internationalization WG)<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11pt">Internationalization is not a feature.<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11pt">It is an architecture.<u></u><u></u></span></p><p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p><p class="MsoNormal"><span style="font-size:11pt"><u></u> <u></u></span></p><div style="border-width:1pt medium medium;border-style:solid none none;border-color:rgb(225,225,225) currentcolor currentcolor;padding:3pt 0in 0in"><p class="MsoNormal"><b><span style="font-size:11pt;font-family:"Calibri",sans-serif">From:</span></b><span style="font-size:11pt;font-family:"Calibri",sans-serif"> Unicode <<a href="mailto:unicode-bounces@corp.unicode.org" target="_blank">unicode-bounces@corp.unicode.org</a>> <b>On Behalf Of </b>Yuri Sukhov via Unicode<br><b>Sent:</b> Monday, March 11, 2024 5:06 PM<br><b>To:</b> <a href="mailto:unicode@corp.unicode.org" target="_blank">unicode@corp.unicode.org</a><br><b>Subject:</b> Identifier caseless matching without toNFKC_Casefold<u></u><u></u></span></p></div><p class="MsoNormal"><u></u> <u></u></p><div><div><p class="MsoNormal">Hi,<u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">I'm implementing a caseless matching for strings used as identifiers. I'm aware that NFKC_Casefold mapping and related toNFKC_Casefold() string transform are designed for such scenario. Unfortunately, the language and libraries I'm using do not implement toNFKC_Casefold(), so I'm looking for an alternative approach.<u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">My use case does not seem to require the removal of default-ignorables, for now I'm only concerned with the case and compatibility variations. It looks like the definition of the compatibility caseless match is what I need:<u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">A string X is a compatibility caseless match for a string Y if and only if: NFKD(toCasefold(NFKD(toCasefold(NFD(X))))) = NFKD(toCasefold(NFKD(toCasefold(NFD(Y))))<u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">However, I can't seem to find the case where that extra cycle of folding/normalization makes the difference. It seems to me that the same result - compatibility caseless match - can be achieved with a simpler approach:<u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">NFC(toCasefold(NFKD(X))) <u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">Basically, I think about it as 1) removing the compatibility variations by normalizing with decomposition, 2) then removing the case differences from this decomposed sequence, 3) and finally storing a folded string in a potentially shorter NFC form.<u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">It looks like it checks all the boxes, and my - likely naive - testing shows that<u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">NFC(toCasefold(NFKD(X))) = NFKD(toCasefold(NFKD(toCasefold(NFD(X)))))<u></u><u></u></p></div><div><p class="MsoNormal"><u></u> <u></u></p></div><div><p class="MsoNormal">I'm sure I'm missing something, and would appreciate an explanation why/when this won't work.<u></u><u></u></p></div><div><p class="MsoNormal"><br>Yuri<u></u><u></u></p></div></div></div></div></div></blockquote></div>