Question

I'm building a simple HTML to NSAttributedString conversion method and for some reason the NSScanner class is discarding a space after a tag is found. For example, if the html-formatted string is @"This is a <b>bold</b> word", the result is @"This is a boldword". Why is my method losing the space following the closing tag? Do you see anything suspicious with my method?

+ (NSAttributedString *)attributedStringFromHtmlString:(NSString *)htmlString {

    NSMutableAttributedString *attributedString;
    NSRange range;
    NSScanner *htmlScanner;
    NSMutableString *strippedString;

    BOOL boldFlag = NO;
    BOOL italicFlag = NO;
    BOOL underlineFlag = NO;

    htmlScanner = [NSScanner scannerWithString:htmlString];
    while (![htmlScanner isAtEnd]) {
        NSString *firstPass, *tagString;
        NSCharacterSet *openTagSet;
        NSCharacterSet *closeTagSet;
        NSMutableAttributedString *newAttributedString;

        openTagSet = [NSCharacterSet characterSetWithCharactersInString:@"<"];
        closeTagSet = [NSCharacterSet characterSetWithCharactersInString:@">"];
        newAttributedString = [[NSMutableAttributedString alloc] init];

        if ([htmlScanner scanUpToCharactersFromSet:openTagSet intoString:&firstPass]) {
            [newAttributedString appendAttributedString:[[NSAttributedString alloc] initWithString:firstPass]];
            [attributedString appendAttributedString:newAttributedString];
        }

        // Either we hit a '<' or we're at the end of the text.
        if (![htmlScanner isAtEnd]) {
            [htmlScanner scanCharactersFromSet:openTagSet intoString:NULL];
            [htmlScanner scanUpToCharactersFromSet:closeTagSet intoString:&tagString];
            [htmlScanner scanCharactersFromSet:closeTagSet intoString:NULL];
            tagString = [tagString lowercaseString];

            if ([tagString isEqual:@"b"]) {
                boldFlag = YES;
            }
            else if ([tagString isEqual:@"/b"]) {
                boldFlag = NO;
            }
            else if ([tagString isEqual:@"h"]) {
                boldFlag = YES;
            }
            else if ([tagString isEqual:@"/h"]) {
                boldFlag = NO;
            }
            else if ([tagString isEqual:@"i"]) {
                italicFlag = YES;
            }
            else if ([tagString isEqual:@"/i"]) {
                italicFlag = NO;
            }
            else if ([tagString isEqual:@"br /"]) {
                [attributedString appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n"]];
            }
        }
    }

    range.location = 0;
    range.length = [attributedString length];

    return attributedString;
}

Thanks in advance for your wisdom!

Was it helpful?

Solution

Because the default value for NSScanner's charactersToBeSkipped is all whitespace characters.

Try setting it to nil:

htmlScanner.charactersToBeSkipped = nil;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top