Convert Special Characters for RTF
Can someone please assist me with converting special characters to something that can be correctly represented in an RTF file?
I am taking text stored in a string on the iPad and outputting it as an RTF file using NSASCIIStringEncoding. So far so good. What I've neglected to do successfully, is take into account special characters (e.g. tilde, umlaut, accent, etc.) . Sorry RoW!
The most universal RTF format seems to want 8-bit text encoding with code page escape (two hexadecimal digits following a backslash). So n with tilde (ñ) would be \'f1.
The only solution that occurs to me is to convert to NSUTF8StringEncoding and then use stringByReplacingOccurrencesOfString, but there are a lot characters and it seems tedious to have to replace every one of them manually. Is th开发者_如何学编程ere a more efficient way that is escaping me? (pun intended) :)
Thanks for any suggestions.
@falconcreek's answer saved me lots of time writing code to coping with a wider range of cases, including, say, Chinese characters (as requested by DenVog). In particular, it's important to check for: "\", "{" and "}" as these are used by the RTF format. (See How to output unicode string to RTF (using C#), for example.) The following category on NSString copes with a string such as:
The quick \ slow {brown} fox “slurped” lazily on his π-latté, while Faye Wong (王菲) played in the background.
@interface NSString (TR)
- (NSString *)stringFormattedRTF;
@end
@implementation NSString (TR)
#define backslash 0x5C
#define openCurlyBrace 0x7B
#define closeCurlyBrace 0x7D
- (NSString *)stringFormattedRTF;
{
NSMutableString *result = [NSMutableString string];
for (int index = 0; index < [self length]; index++)
{
unichar unicodeCharacter = [self characterAtIndex: index];
if (unicodeCharacter == backslash || unicodeCharacter == openCurlyBrace || unicodeCharacter == closeCurlyBrace)
{
[result appendFormat: @"\\%c", unicodeCharacter];
}
else if (unicodeCharacter > 127)
{
[result appendFormat:@"\\uc0\\u%u ", unicodeCharacter];
}
else
{
[result appendFormat:@"%c", unicodeCharacter];
}
}
return result;
}
Side note: Microsoft provide 1.9.1 RTF spec, which is really helpful if you want to output RTF. Wikipedia says (as of May 2012) this the most recent version. Google tends to kick up a much older RTF specs.
Check the value of characterAtIndex:
if it is > 127, it is not ASCII, so escape the character.
Something like the following
- (NSString *)stringFormattedRTF:(NSString *)inputString
{
NSMutableString *result = [NSMutableString string];
for ( int index = 0; index < [inputString length]; index++ ) {
NSString *temp = [inputString substringWithRange:NSMakeRange( index, 1 )];
unichar tempchar = [inputString characterAtIndex:index];
if ( tempchar > 127) {
[result appendFormat:@"\\\'%02x", tempchar];
} else {
[result appendString:temp];
}
}
return result;
}
精彩评论