// // GMHighlightStrGenerator.m // GMKit // // Created by wangyang on 2020/4/14. // #import "GMHighlightStrGenerator.h" @implementation GMHighlightStrGenerator - (void)debugConfig { NSAssert(self.hightlightColor, @"GMHighlightStrGenerator.hightlightColor不可以为空"); NSAssert(self.normalColor, @"GMHighlightStrGenerator.normalColor不可以为空"); NSAssert(self.hightlightFont, @"GMHighlightStrGenerator.hightlightFont不可以为空"); NSAssert(self.font, @"GMHighlightStrGenerator.font不可以为空"); } - (nullable NSMutableAttributedString *)generateWithString:(NSString *)str { if (str.length == 0) { return nil; } #ifdef DEBUG [self debugConfig]; #endif NSMutableAttributedString *resultAttrString = [self parseHighlight:str]; // 创建一个NSMutableParagraphStyle,以便稍后复用 NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init]; style.lineSpacing = _lineHeight; style.lineBreakMode = NSLineBreakByTruncatingTail; style.alignment = _aligment; if (resultAttrString.length > 0) { // 如果有高亮,resultAttrString不为空,那只加一个NSParagraphStyleAttributeName属性 [resultAttrString addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, resultAttrString.length)]; } else if (resultAttrString.length == 0) { // 如果没有走到正则里面,说明没有需要高亮的内容,设置普通颜色就好 NSAttributedString *subString = [[NSAttributedString alloc] initWithString:str attributes:@{NSFontAttributeName : self.font, NSForegroundColorAttributeName:_normalColor, NSParagraphStyleAttributeName:style}]; [resultAttrString appendAttributedString:subString]; } return resultAttrString; } /// 解析出<ems>xxx</ems>,并将对应的 xxx 文本设置为高亮颜色 - (NSMutableAttributedString *)parseHighlight:(NSString *)str { NSError *error; NSRegularExpression *expression = [NSRegularExpression regularExpressionWithPattern:@"([\\w\\W]*)<ems>([\\w\\W]+)<\\/ems>([\\w\\W]*)" options:0 error:&error]; if (error) { return nil; } NSMutableAttributedString *attString = [[NSMutableAttributedString alloc] init]; [expression enumerateMatchesInString:str options:0 range:NSMakeRange(0, str.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { // 根据NSTextCheckingResult的rangeAtIndex方法文档 // result至少会有一个range,这个range是匹配它自身全部的,所以正则匹配的其它range是从1开始的 // <ems></ems>将string分隔为如下三个部分 // string1:对应<ems>标签前的文本 // string2:对应标签中的高亮文本 // string3:对应</ems>标签后的文本 NSString *string1 = [str substringWithRange:[result rangeAtIndex:1]]; NSAttributedString *attrString1 = [self parseHighlight:string1]; if (attrString1.length > 0) { [attString appendAttributedString:attrString1]; }else{ NSAttributedString *subString = [[NSAttributedString alloc] initWithString:string1 attributes:@{NSFontAttributeName : _font, NSForegroundColorAttributeName:_normalColor}]; [attString appendAttributedString:subString]; } NSString *string2 = [str substringWithRange:[result rangeAtIndex:2]]; NSAttributedString *attrString2 = [self parseHighlight:string2]; if (attrString2.length > 0) { [attString appendAttributedString:attrString2]; }else{ NSAttributedString *subString = [[NSAttributedString alloc] initWithString:string2 attributes:@{NSFontAttributeName : _hightlightFont, NSForegroundColorAttributeName:_hightlightColor}]; [attString appendAttributedString:subString]; } NSString *string3 = [str substringWithRange:[result rangeAtIndex:3]]; NSAttributedString *attrString3 = [self parseHighlight:string3]; if (attrString3.length > 0) { [attString appendAttributedString:attrString3]; }else{ NSAttributedString *subString = [[NSAttributedString alloc] initWithString:string3 attributes:@{NSFontAttributeName : _font, NSForegroundColorAttributeName:_normalColor}]; [attString appendAttributedString:subString]; } }]; return attString; } @end