2 Copyright (C) 2000-2004 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
6 OGo is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 #include "NSString+German.h"
26 @implementation NSString(German)
28 - (BOOL)doesContainGermanUmlauts {
29 register unsigned i, len;
31 if ((len = [self length]) == 0)
34 for (i = 0; i < len; i++) {
35 switch ([self characterAtIndex:i]) {
36 case 252: /* ü */
37 case 220: /* Ü */
38 case 228: /* ä */
39 case 196: /* Ä */
40 case 246: /* ö */
41 case 214: /* Ö */
42 case 223: /* ß */
49 - (NSString *)stringByReplacingGermanUmlautsWithTwoCharsAndSzWith:(unichar)_c {
51 a^ => ae, o^ => oe, u^ => ue, A^ => Ae, O^ => Oe, O^ => Ue
52 s^ => sz or ss (_sz arg)
54 unsigned i, len, rlen;
58 if ((len = [self length]) == 0)
61 buf = calloc((len * 2) + 3, sizeof(unichar));
63 for (i = 0, rlen = 0; i < len; i++) {
67 c = [self characterAtIndex:i];
70 buf[rlen] = 'u'; rlen++;
71 buf[rlen] = 'e'; rlen++;
74 buf[rlen] = 'U'; rlen++;
75 buf[rlen] = 'e'; rlen++;
78 buf[rlen] = 'a'; rlen++;
79 buf[rlen] = 'e'; rlen++;
82 buf[rlen] = 'A'; rlen++;
83 buf[rlen] = 'e'; rlen++;
86 buf[rlen] = 'o'; rlen++;
87 buf[rlen] = 'e'; rlen++;
90 buf[rlen] = 'O'; rlen++;
91 buf[rlen] = 'e'; rlen++;
93 case 223: /* ss or sz */
95 buf[rlen] = 's'; rlen++;
96 buf[rlen] = _c; rlen++;
99 default: /* copy char and continue */
107 ? [[NSString alloc] initWithCharacters:buf length:rlen]
110 return [s autorelease];
112 - (NSString *)stringByReplacingGermanUmlautsWithTwoChars {
113 // default sz mapping is "ss" (like Hess ;-)
114 return [self stringByReplacingGermanUmlautsWithTwoCharsAndSzWith:'s'];
117 - (NSString *)stringByReplacingTwoCharEncodingsOfGermanUmlauts {
119 ae => a^, oe => o^, ue => u^, Ae => A^, Oe => O^, Ue => U^
123 unsigned i, len, rlen;
128 if ((len = [self length]) == 0)
131 return [[self copy] autorelease];
133 buf = calloc(len + 3, sizeof(unichar));
134 [self getCharacters:buf]; // Note: we can reuse that buffer!
136 for (i = 0, rlen = 0, didReplace = NO; i < len; i++) {
137 register unichar c, cn;
141 if ((i + 1) >= len) {
144 break; // end, found last char (so can't be a sequence)
149 if ((c=='a' || c=='A' || c=='u' || c=='U' || c=='o' || c=='O')&&cn=='e') {
150 /* an umlaut sequence */
152 case 'a': buf[rlen] = 228; break;
153 case 'A': buf[rlen] = 196; break;
154 case 'o': buf[rlen] = 246; break;
155 case 'O': buf[rlen] = 214; break;
156 case 'u': buf[rlen] = 252; break;
157 case 'U': buf[rlen] = 220; break;
160 i++; // skip sequence char
163 else if (c == 's' && (cn == 's' || cn == 'z')) {
167 i++; // skip sequence char
171 /* regular char, copy */
178 ? [[NSString alloc] initWithCharacters:buf length:rlen]
181 return [s autorelease];
184 - (NSArray *)germanUmlautVariantsOfString {
186 The ^ is used to signal the single character umlaut to avoid non-ASCII
189 Note: we can only do a limited set of transformations! Eg you can only
190 mix umlauts *OR* the "ue", "oe" variants!
192 Q: what about names which contain encoded umlauts *and* the same sequence
193 as a regular part of the name! For example "Neuendoerf".
195 string with umlauts (two variants, ss and sz):
204 string with umlaut workaround (three variants due to sz/ss):
217 if ((len = [self length]) == 0)
218 return [NSArray arrayWithObjects:@"", nil];
220 if ([self doesContainGermanUmlauts]) {
221 s1 = [self stringByReplacingGermanUmlautsWithTwoCharsAndSzWith:'s'];
222 s2 = [self stringByReplacingGermanUmlautsWithTwoCharsAndSzWith:'z'];
224 if ([s2 isEqualToString:s1] || [s2 isEqualToString:self])
226 if ([s1 isEqualToString:self])
229 return [NSArray arrayWithObjects:self, s1, s2, nil];
232 if (len < 2) // a sequence would have at least 2 chars
233 return [NSArray arrayWithObjects:self, nil];
235 s1 = [self stringByReplacingTwoCharEncodingsOfGermanUmlauts];
237 if ([self isEqualToString:s1])
238 /* nothing was replaced */
239 return [NSArray arrayWithObjects:self, nil];
241 return [NSArray arrayWithObjects:self, s1, nil];
244 @end /* NSString(German) */