Разбор NSAttributedString в HTML на iOS 7
У меня есть NSAttributedString
(исходя из HTML), который я установил для UITextView
,
- (void)setHtml:(NSString *)html {
NSData *htmlData = [html dataUsingEncoding:NSUTF8StringEncoding];
// Create the HTML string
NSDictionary *importParams = @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType};
NSError *error = nil;
self.htmlString = [[NSAttributedString alloc] initWithData:htmlData options:importParams documentAttributes:NULL error:&error];
self.editorView.attributedText = self.htmlString;
}
Затем я позволяю пользователю редактировать то, что он хочет, и я хотел бы затем снова преобразовать его в HTML, поэтому я использую отредактированную версию ULIKit htmlFromRange:. Вот соответствующий метод из этого:
-(NSString*) HTMLFromRange: (NSRange)range
{
unsigned int location = 0;
NSRange effRange;
NSMutableString* str = [NSMutableString string];
NSMutableString* endStr = [NSMutableString string];
NSDictionary* attrs = nil;
NSDictionary* oldAttrs = nil;
unsigned int finalLen = range.location +range.length;
// TODO: Use oldAttrs, add NSForegroundColorAttributeName and
attrs = [self attributesAtIndex: location effectiveRange: &effRange];
location = effRange.location +effRange.length;
NSLog(@"attributed string: %@", self);
// Font/color changed?
UIFont* fnt = [attrs objectForKey: NSFontAttributeName];
UIColor* tcol = [attrs objectForKey: NSForegroundColorAttributeName];
if( fnt || tcol )
{
[str appendString: @"<font"];
if( tcol )
{
[str appendFormat: @" color=\"%@\"", ColorToHTMLColor(tcol)];
}
[str appendString: @">"];
[endStr insertString: @"</font>" atIndex: 0];
UIFontDescriptor *fontDescriptor = [fnt fontDescriptor];
if( (fontDescriptor.symbolicTraits & UIFontDescriptorTraitItalic) == UIFontDescriptorTraitItalic )
{
[str appendString: @"<i>"];
[endStr insertString: @"</i>" atIndex: 0];
}
if( (fontDescriptor.symbolicTraits & UIFontDescriptorTraitBold) == UIFontDescriptorTraitBold)
{
[str appendString: @"<b>"];
[endStr insertString: @"</b>" atIndex: 0];
}
}
//Underline
NSNumber *underline = [attrs objectForKey:NSUnderlineStyleAttributeName];
if(underline && [underline intValue] > 0) {
[str appendString:@"<u>"];
[endStr insertString:@"</u>" atIndex:0];
}
// Superscript changed?
NSNumber* supers = [attrs objectForKey: (NSString*)kCTSuperscriptAttributeName];
if( supers && supers != [oldAttrs objectForKey: (NSString*)kCTSuperscriptAttributeName] )
{
[str appendString: [supers intValue] > 0 ? @"<sup>" : @"<sub>"];
[endStr insertString: [supers intValue] > 0 ? @"</sup>" : @"</sub>" atIndex: 0];
}
// Actual text and closing tags:
[str appendString: [[[self string] substringWithRange:effRange] stringByInsertingHTMLEntitiesAndLineBreaks: YES]];
[str appendString: endStr];
while( location < finalLen )
{
[endStr setString: @""];
attrs = [self attributesAtIndex: location effectiveRange: &effRange];
location = effRange.location +effRange.length;
// Font/color changed?
UIFont* fnt = [attrs objectForKey: NSFontAttributeName];
UIColor* tcol = [attrs objectForKey: NSForegroundColorAttributeName];
if( fnt || tcol )
{
[str appendString: @"<font"];
if( tcol )
{
[str appendFormat: @" color=\"%@\"", ColorToHTMLColor(tcol)];
}
[str appendString: @">"];
[endStr insertString: @"</font>" atIndex: 0];
UIFontDescriptor *fontDescriptor = [fnt fontDescriptor];
if( (fontDescriptor.symbolicTraits & UIFontDescriptorTraitItalic) == UIFontDescriptorTraitItalic )
{
[str appendString: @"<i>"];
[endStr insertString: @"</i>" atIndex: 0];
}
if( (fontDescriptor.symbolicTraits & UIFontDescriptorTraitBold) == UIFontDescriptorTraitBold )
{
[str appendString: @"<b>"];
[endStr insertString: @"</b>" atIndex: 0];
}
}
//Underline
NSNumber *underline = [attrs objectForKey:NSUnderlineStyleAttributeName];
if(underline && [underline intValue] > 0) {
[str appendString:@"<u>"];
[endStr insertString:@"</u>" atIndex:0];
}
// Superscript changed?
NSNumber* supers = [attrs objectForKey: (NSString*)kCTSuperscriptAttributeName];
if( supers && supers != [oldAttrs objectForKey: (NSString*)kCTSuperscriptAttributeName] )
{
[str appendString: [supers intValue] > 0 ? @"<sup>" : @"<sub>"];
[endStr insertString: [supers intValue] > 0 ? @"</sup>" : @"</sub>" atIndex: 0];
}
///Lists.
// Actual text and closing tags:
[str appendString: [[[self string] substringWithRange:effRange] stringByInsertingHTMLEntitiesAndLineBreaks: YES]];
[str appendString: endStr];
}
return str;
}
Проблема исходит из списков. В частности, NSAttributedString
метод для анализа HTML-списков (и тегов) в NSTextLists из того, что я вижу в журналах. NSTextList
является частным в UIKit. Есть ли способ разобрать это обратно в список без использования парсера Apple по умолчанию (добавив мой метод htmlFromRange выше)? (Смотрите этот вопрос: от Ник Хаббард).
Я понимаю, как, если пользователь СОЗДАЕТ список в моем текстовом представлении, чтобы использовать пользовательский атрибут для подделки NSTextList, а затем я могу легко разобрать это в html, но не могу найти способ добиться этого с помощью предварительно сделанного NSAttributedString
,
Благодарю. (Отмечу, что я назначил награду за вопрос Ник Хаббард, который очень связан, если вы хотите ответить в обоих местах.)