diff --git a/AttributedLabel Example/Classes/BasicDemo/BasicDemoViewController.xib b/AttributedLabel Example/Classes/BasicDemo/BasicDemoViewController.xib
index 8d99974..ae4bdad 100644
--- a/AttributedLabel Example/Classes/BasicDemo/BasicDemoViewController.xib
+++ b/AttributedLabel Example/Classes/BasicDemo/BasicDemoViewController.xib
@@ -2,13 +2,13 @@
1536
- 12C60
- 2843
+ 12C3006
+ 2844
1187.34
625.00
IBProxyObject
@@ -261,7 +261,7 @@ cm5pYSAoKzEgNDA4LTk5Ni0xMDEwKSBuZXh0IHN1bmRheS4
7
NO
IBCocoaTouchFramework
- Some <b>basic</b> <font name="Courier" size="14">HTML</font> support is provided for <u>convenience</u> too. <font color="red">You can add your own parsers easily</font> by subclassing <font name="Courier" size="14">OHASMarkupParserBase</font> if needed.
+ Some <b>basic</b> <font name="Courier" size="14">HTML</font> support is provided for <u>convenience</u> too. <font color="red">You can add your own <a href="http://en.wikipedia.org/wiki/Parser">parsers</a> easily</font> by subclassing <font name="Courier" size="14">OHASMarkupParserBase</font> if needed.
YES
3
- 1929
+ 1930
diff --git a/AttributedLabel Example/Classes/CustomLinksDemo/CustomLinksViewController.m b/AttributedLabel Example/Classes/CustomLinksDemo/CustomLinksViewController.m
index 9ee0fb8..cb1f01f 100644
--- a/AttributedLabel Example/Classes/CustomLinksDemo/CustomLinksViewController.m
+++ b/AttributedLabel Example/Classes/CustomLinksDemo/CustomLinksViewController.m
@@ -68,13 +68,12 @@ -(void)fillDemoLabel
// now we only change the color of "FoodReporter"
[attrStr setTextColor:[UIColor colorWithRed:0.f green:0.f blue:0.5 alpha:1.f] range:[txt rangeOfString:@TXT_BOLD]];
[attrStr setTextBold:YES range:[txt rangeOfString:@TXT_BOLD]];
-
- /**(2)** Affect the NSAttributedString to the OHAttributedLabel *******/
- self.customLinkDemoLabel.attributedText = attrStr;
+
// and add a link to the "share your food!" text
- [self.customLinkDemoLabel addCustomLink:[NSURL URLWithString:@"http://www.foodreporter.net"] inRange:[txt rangeOfString:@TXT_LINK]];
+ [attrStr setLink:[NSURL URLWithString:@"http://www.foodreporter.net"] range:[txt rangeOfString:@TXT_LINK]];
- // "Hello World!" will be displayed in the label, justified, "Hello" in red and " World!" in gray.
+ /**(2)** Affect the NSAttributedString to the OHAttributedLabel *******/
+ self.customLinkDemoLabel.attributedText = attrStr;
}
-(IBAction)toggleBold:(UISwitch*)boldSwitch
@@ -88,9 +87,6 @@ -(IBAction)toggleBold:(UISwitch*)boldSwitch
[mas setTextBold:boldSwitch.on range:[plainText rangeOfString:@TXT_BOLD]];
// Affect back the attributed string to the label
self.customLinkDemoLabel.attributedText = mas;
-
- // Restore the link (as each time we change the attributedText we remove custom links to avoid inconsistencies
- [self.customLinkDemoLabel addCustomLink:[NSURL URLWithString:@"http://www.foodreporter.net"] inRange:[plainText rangeOfString:@TXT_LINK]];
#if ! __has_feature(objc_arc)
// Cleaning: balance the "mutableCopy" call with a "release"
@@ -111,16 +107,17 @@ -(void)configureMentionLabel
{
// Detect all "@xxx" mention-like strings using the "@\w+" regular expression
NSRegularExpression* userRegex = [NSRegularExpression regularExpressionWithPattern:@"@\\w+" options:0 error:nil];
+ NSMutableAttributedString* mas = [self.mentionDemoLabel.attributedText mutableCopy];
[userRegex enumerateMatchesInString:self.mentionDemoLabel.text options:0 range:NSMakeRange(0,self.mentionDemoLabel.text.length)
usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop)
{
// For each "@xxx" user mention found, add a custom link:
NSString* user = [[self.mentionDemoLabel.text substringWithRange:match.range] substringFromIndex:1]; // get the matched user name, removing the "@"
NSString* linkURLString = [NSString stringWithFormat:@"user:%@", user]; // build the "user:" link
- [self.mentionDemoLabel addCustomLink:[NSURL URLWithString:linkURLString] inRange:match.range]; // add it
+ [mas setLink:[NSURL URLWithString:linkURLString] range:match.range]; // add it
}];
-
- self.mentionDemoLabel.centerVertically = YES;
+ self.mentionDemoLabel.attributedText = mas;
+ self.mentionDemoLabel.centerVertically = YES;
}
diff --git a/AttributedLabel Example/Classes/UIAppearanceDemo/UIAppearanceDemoViewController.m b/AttributedLabel Example/Classes/UIAppearanceDemo/UIAppearanceDemoViewController.m
index c5f9f82..e4bd55d 100644
--- a/AttributedLabel Example/Classes/UIAppearanceDemo/UIAppearanceDemoViewController.m
+++ b/AttributedLabel Example/Classes/UIAppearanceDemo/UIAppearanceDemoViewController.m
@@ -21,7 +21,7 @@ - (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
- [self.sampleLabel addCustomLink:nil inRange:NSMakeRange(8,11)];
+ [self.sampleLabel addCustomLink:[NSURL URLWithString:@"#"] inRange:NSMakeRange(8,11)]; // Add fake link so we can see the UIAppearance effect
self.sampleLabel.centerVertically = YES;
}
diff --git a/OHAttributedLabel/Source/NSAttributedString+Attributes.h b/OHAttributedLabel/Source/NSAttributedString+Attributes.h
index 91c308c..a5e4425 100644
--- a/OHAttributedLabel/Source/NSAttributedString+Attributes.h
+++ b/OHAttributedLabel/Source/NSAttributedString+Attributes.h
@@ -29,6 +29,7 @@
#import
#import
+extern NSString* kOHLinkAttributeName;
/////////////////////////////////////////////////////////////////////////////////////
#pragma mark - NSAttributedString Additions
@@ -51,6 +52,8 @@
-(BOOL)textIsBoldAtIndex:(NSUInteger)index effectiveRange:(NSRangePointer)aRange;
-(CTTextAlignment)textAlignmentAtIndex:(NSUInteger)index effectiveRange:(NSRangePointer)aRange;
-(CTLineBreakMode)lineBreakModeAtIndex:(NSUInteger)index effectiveRange:(NSRangePointer)aRange;
+
+-(NSURL*)linkAtIndex:(NSUInteger)index effectiveRange:(NSRangePointer)aRange;
@end
@@ -74,6 +77,8 @@
-(void)setTextAlignment:(CTTextAlignment)alignment lineBreakMode:(CTLineBreakMode)lineBreakMode;
-(void)setTextAlignment:(CTTextAlignment)alignment lineBreakMode:(CTLineBreakMode)lineBreakMode range:(NSRange)range;
+
+-(void)setLink:(NSURL*)link range:(NSRange)range;
@end
diff --git a/OHAttributedLabel/Source/NSAttributedString+Attributes.m b/OHAttributedLabel/Source/NSAttributedString+Attributes.m
index af3bb86..7643030 100644
--- a/OHAttributedLabel/Source/NSAttributedString+Attributes.m
+++ b/OHAttributedLabel/Source/NSAttributedString+Attributes.m
@@ -35,6 +35,8 @@
#define MRC_AUTORELEASE(x) [(x) autorelease]
#endif
+NSString* kOHLinkAttributeName = @"NSLinkAttributeName"; // Use the same value as OSX, to be compatible in case Apple port this to iOS one day too
+
/////////////////////////////////////////////////////////////////////////////////////
#pragma mark - NSAttributedString Additions
@@ -130,6 +132,12 @@ -(CTLineBreakMode)lineBreakModeAtIndex:(NSUInteger)index effectiveRange:(NSRange
CTParagraphStyleGetValueForSpecifier(style, kCTParagraphStyleSpecifierLineBreakMode, sizeof(CTLineBreakMode), &lineBreakMode);
return lineBreakMode;
}
+
+-(NSURL*)linkAtIndex:(NSUInteger)index effectiveRange:(NSRangePointer)aRange
+{
+ return [self attribute:kOHLinkAttributeName atIndex:index effectiveRange:aRange];
+}
+
@end
@@ -265,6 +273,15 @@ -(void)setTextAlignment:(CTTextAlignment)alignment lineBreakMode:(CTLineBreakMod
CFRelease(aStyle);
}
+-(void)setLink:(NSURL*)link range:(NSRange)range
+{
+ [self removeAttribute:kOHLinkAttributeName range:range]; // Work around for Apple leak
+ if (link)
+ {
+ [self addAttribute:kOHLinkAttributeName value:(BRIDGE_CAST id)link range:range];
+ }
+}
+
@end
diff --git a/OHAttributedLabel/Source/OHAttributedLabel.m b/OHAttributedLabel/Source/OHAttributedLabel.m
index 9bd89db..92c158c 100755
--- a/OHAttributedLabel/Source/OHAttributedLabel.m
+++ b/OHAttributedLabel/Source/OHAttributedLabel.m
@@ -269,6 +269,18 @@ -(void)recomputeLinksInTextIfNeeded
}
};
+ // Links set by text attribute
+ [_attributedText enumerateAttribute:kOHLinkAttributeName inRange:NSMakeRange(0, [_attributedText length])
+ options:0 usingBlock:^(id value, NSRange range, BOOL *stop)
+ {
+ if (value)
+ {
+ NSTextCheckingResult* result = [NSTextCheckingResult linkCheckingResultWithRange:range URL:(BRIDGE_CAST NSURL*)value];
+ applyLinkStyle(result);
+ }
+ }];
+
+ // Automatically Detected Links
if (plainText && (self.automaticallyAddLinksForType > 0))
{
[_linksDetector enumerateMatchesInString:plainText options:0 range:NSMakeRange(0,[plainText length])
@@ -277,6 +289,8 @@ -(void)recomputeLinksInTextIfNeeded
applyLinkStyle(result);
}];
}
+
+ // Custom Links
[_customLinks enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop)
{
applyLinkStyle((NSTextCheckingResult*)obj);
@@ -298,8 +312,25 @@ -(NSTextCheckingResult*)linkAtCharacterIndex:(CFIndex)idx
@autoreleasepool
{
NSString* plainText = [_attributedText string];
- if (plainText && (self.automaticallyAddLinksForType > 0))
+
+ // Links set by text attribute
+ if (_attributedText)
+ {
+ [_attributedText enumerateAttribute:kOHLinkAttributeName inRange:NSMakeRange(0, [_attributedText length])
+ options:0 usingBlock:^(id value, NSRange range, BOOL *stop)
+ {
+ if (value && NSLocationInRange(idx, range))
+ {
+ NSTextCheckingResult* result = [NSTextCheckingResult linkCheckingResultWithRange:range URL:(BRIDGE_CAST NSURL*)value];
+ foundResult = MRC_RETAIN(result);
+ *stop = YES;
+ }
+ }];
+ }
+
+ if (!foundResult && plainText && (self.automaticallyAddLinksForType > 0))
{
+ // Automatically Detected Links
[_linksDetector enumerateMatchesInString:plainText options:0 range:NSMakeRange(0,[plainText length])
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
{
@@ -314,6 +345,7 @@ -(NSTextCheckingResult*)linkAtCharacterIndex:(CFIndex)idx
if (!foundResult)
{
+ // Custom Links
[_customLinks enumerateObjectsUsingBlock:^(id obj, NSUInteger aidx, BOOL *stop)
{
NSRange r = [(NSTextCheckingResult*)obj range];
diff --git a/OHAttributedLabel/TagParsers/OHASBasicHTMLParser.m b/OHAttributedLabel/TagParsers/OHASBasicHTMLParser.m
index c058ae3..11cc936 100644
--- a/OHAttributedLabel/TagParsers/OHASBasicHTMLParser.m
+++ b/OHAttributedLabel/TagParsers/OHASBasicHTMLParser.m
@@ -21,49 +21,79 @@ +(NSDictionary*)tagMappings
{
return [NSDictionary dictionaryWithObjectsAndKeys:
- ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match) {
+ ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match)
+ {
NSRange textRange = [match rangeAtIndex:1];
- NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
- if (textRange.length>0) [foundString setTextBold:YES range:NSMakeRange(0,textRange.length)];
- return MRC_AUTORELEASE(foundString);
- }, @"(.*?)",
+ if (textRange.length>0)
+ {
+ NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
+ [foundString setTextBold:YES range:NSMakeRange(0,textRange.length)];
+ return MRC_AUTORELEASE(foundString);
+ } else {
+ return nil;
+ }
+ }, @"(.+?)",
- ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match) {
+ ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match)
+ {
NSRange textRange = [match rangeAtIndex:1];
- NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
- if (textRange.length>0) [foundString setTextIsUnderlined:YES];
- return MRC_AUTORELEASE(foundString);
- }, @"(.*?)",
+ if (textRange.length>0)
+ {
+ NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
+ [foundString setTextIsUnderlined:YES];
+ return MRC_AUTORELEASE(foundString);
+ } else {
+ return nil;
+ }
+ }, @"(.+?)",
- ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match) {
- NSString* fontName = [str attributedSubstringFromRange:[match rangeAtIndex:2]].string;
- CGFloat fontSize = [str attributedSubstringFromRange:[match rangeAtIndex:4]].string.floatValue;
+ ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match)
+ {
+ NSRange fontNameRange = [match rangeAtIndex:2];
+ NSRange fontSizeRange = [match rangeAtIndex:4];
NSRange textRange = [match rangeAtIndex:5];
- NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
- if (textRange.length>0) [foundString setFontName:fontName size:fontSize];
- return MRC_AUTORELEASE(foundString);
- }, @"(.*?)",
+ if ((fontNameRange.length>0) && (fontSizeRange.length>0) && (textRange.length>0))
+ {
+ NSString* fontName = [str attributedSubstringFromRange:fontNameRange].string;
+ CGFloat fontSize = [str attributedSubstringFromRange:fontSizeRange].string.floatValue;
+ NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
+ [foundString setFontName:fontName size:fontSize];
+ return MRC_AUTORELEASE(foundString);
+ } else {
+ return nil;
+ }
+ }, @"(.+?)",
- ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match) {
- NSString* colorName = [str attributedSubstringFromRange:[match rangeAtIndex:2]].string;
- UIColor* color = UIColorFromString(colorName);
+ ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match)
+ {
+ NSRange colorRange = [match rangeAtIndex:2];
NSRange textRange = [match rangeAtIndex:3];
- NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
- if (textRange.length>0) [foundString setTextColor:color];
- return MRC_AUTORELEASE(foundString);
- }, @"(.*?)",
+ if ((colorRange.length>0) && (textRange.length>0))
+ {
+ NSString* colorName = [str attributedSubstringFromRange:colorRange].string;
+ UIColor* color = UIColorFromString(colorName);
+ NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
+ [foundString setTextColor:color];
+ return MRC_AUTORELEASE(foundString);
+ } else {
+ return nil;
+ }
+ }, @"(.+?)",
- /*
- // Disabled for now as there is no official CoreText attribute name to define links.
- // To be able to do this, we have implement a custom attribute ourselves and add support for it in OHAttributedLabel
- ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match) {
- NSString* link = [str attributedSubstringFromRange:[match rangeAtIndex:1]].string;
- NSRange textRange = [match rangeAtIndex:2];
- NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
- [foundString addAttribute:@"NSLinkAttributeName" value:link range:NSMakeRange(0,textRange.length)];
- return [foundString autorelease];
- }, @"(.*?)",
- */
+ ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match)
+ {
+ NSRange linkRange = [match rangeAtIndex:2];
+ NSRange textRange = [match rangeAtIndex:3];
+ if ((linkRange.length>0) && (textRange.length>0))
+ {
+ NSString* link = [str attributedSubstringFromRange:linkRange].string;
+ NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
+ [foundString setLink:[NSURL URLWithString:link] range:NSMakeRange(0,textRange.length)];
+ return [foundString autorelease];
+ } else {
+ return nil;
+ }
+ }, @"(.+?)",
nil];
}
diff --git a/OHAttributedLabel/TagParsers/OHASBasicMarkupParser.m b/OHAttributedLabel/TagParsers/OHASBasicMarkupParser.m
index ab90bb0..d53cff6 100644
--- a/OHAttributedLabel/TagParsers/OHASBasicMarkupParser.m
+++ b/OHAttributedLabel/TagParsers/OHASBasicMarkupParser.m
@@ -21,36 +21,76 @@ +(NSDictionary*)tagMappings
{
return [NSDictionary dictionaryWithObjectsAndKeys:
- ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match) {
+ ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match)
+ {
NSRange textRange = [match rangeAtIndex:1];
- NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
- if (textRange.length>0) [foundString setTextBold:YES range:NSMakeRange(0,textRange.length)];
- return MRC_AUTORELEASE(foundString);
- }, @"\\*(.*?)\\*",
+ if (textRange.length>0)
+ {
+ NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
+ [foundString setTextBold:YES range:NSMakeRange(0,textRange.length)];
+ return MRC_AUTORELEASE(foundString);
+ } else {
+ return nil;
+ }
+ }, @"\\*(.+?)\\*", /* "*xxx*" = xxx in bold */
- ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match) {
+ ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match)
+ {
NSRange textRange = [match rangeAtIndex:1];
- NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
- if (textRange.length>0) [foundString setTextIsUnderlined:YES];
- return MRC_AUTORELEASE(foundString);
- }, @"_(.*?)_",
+ if (textRange.length>0)
+ {
+ NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
+ [foundString setTextIsUnderlined:YES];
+ return MRC_AUTORELEASE(foundString);
+ } else {
+ return nil;
+ }
+ }, @"_(.+?)_", /* "_xxx_" = xxx in italics */
- ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match) {
+ ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match)
+ {
NSRange textRange = [match rangeAtIndex:1];
- NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
- CTFontRef font = [str fontAtIndex:textRange.location effectiveRange:NULL];
- if (textRange.length>0) [foundString setFontName:@"Courier" size:CTFontGetSize(font)];
- return MRC_AUTORELEASE(foundString);
- }, @"`(.*?)`",
+ if (textRange.length>0)
+ {
+ NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
+ CTFontRef font = [str fontAtIndex:textRange.location effectiveRange:NULL];
+ [foundString setFontName:@"Courier" size:CTFontGetSize(font)];
+ return MRC_AUTORELEASE(foundString);
+ } else {
+ return nil;
+ }
+ }, @"`(.+?)`", /* "`xxx`" = xxx in Courier font */
- ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match) {
- NSString* colorName = [str attributedSubstringFromRange:[match rangeAtIndex:1]].string;
- UIColor* color = UIColorFromString(colorName);
+ ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match)
+ {
+ NSRange colorRange = [match rangeAtIndex:1];
NSRange textRange = [match rangeAtIndex:2];
- NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
- if (textRange.length>0) [foundString setTextColor:color];
- return MRC_AUTORELEASE(foundString);
- }, @"\\{(.*?)\\|(.*?)\\}",
+ if ((colorRange.length>0) && (textRange.length>0))
+ {
+ NSString* colorName = [str attributedSubstringFromRange:colorRange].string;
+ UIColor* color = UIColorFromString(colorName);
+ NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
+ [foundString setTextColor:color];
+ return MRC_AUTORELEASE(foundString);
+ } else {
+ return nil;
+ }
+ }, @"\\{(.+?)\\|(.+?)\\}", /* "{color|text}" = text in specified color */
+
+ ^NSAttributedString*(NSAttributedString* str, NSTextCheckingResult* match)
+ {
+ NSRange textRange = [match rangeAtIndex:1];
+ NSRange linkRange = [match rangeAtIndex:2];
+ if ((linkRange.length>0) && (textRange.length>0))
+ {
+ NSString* linkString = [str attributedSubstringFromRange:linkRange].string;
+ NSMutableAttributedString* foundString = [[str attributedSubstringFromRange:textRange] mutableCopy];
+ [foundString setLink:[NSURL URLWithString:linkString] range:NSMakeRange(0, foundString.length)];
+ return MRC_AUTORELEASE(foundString);
+ } else {
+ return nil;
+ }
+ }, @"\\[(.+?)\\]\\((.+?)\\)", /* "[text](link)" = add link to text */
nil];
}
diff --git a/OHAttributedLabel/TagParsers/OHASMarkupParserBase.m b/OHAttributedLabel/TagParsers/OHASMarkupParserBase.m
index 8613453..9a2e270 100644
--- a/OHAttributedLabel/TagParsers/OHASMarkupParserBase.m
+++ b/OHAttributedLabel/TagParsers/OHASMarkupParserBase.m
@@ -38,9 +38,12 @@ +(void)processMarkupInAttributedString:(NSMutableAttributedString*)mutAttrString
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop2)
{
NSAttributedString* repl = block(processedString, result);
- NSRange offsetRange = NSMakeRange(result.range.location - offset, result.range.length);
- [mutAttrString replaceCharactersInRange:offsetRange withAttributedString:repl];
- offset += result.range.length - repl.length;
+ if (repl)
+ {
+ NSRange offsetRange = NSMakeRange(result.range.location - offset, result.range.length);
+ [mutAttrString replaceCharactersInRange:offsetRange withAttributedString:repl];
+ offset += result.range.length - repl.length;
+ }
}];
#if ! __has_feature(objc_arc)
[processedString release];