diff --git a/Core/Source/DTMarkdownParser.m b/Core/Source/DTMarkdownParser.m index 5bc4c16..3698b9c 100644 --- a/Core/Source/DTMarkdownParser.m +++ b/Core/Source/DTMarkdownParser.m @@ -142,6 +142,10 @@ - (NSString *)_effectiveMarkerPrefixOfString:(NSString *)string { return @"`"; } + else if ([string hasPrefix:@"<"]) + { + return @"<"; + } return nil; } @@ -205,7 +209,7 @@ - (void)_processLine:(NSString *)line NSScanner *scanner = [NSScanner scannerWithString:line]; scanner.charactersToBeSkipped = nil; - NSCharacterSet *markerChars = [NSCharacterSet characterSetWithCharactersInString:@"*_~[!`"]; + NSCharacterSet *markerChars = [NSCharacterSet characterSetWithCharactersInString:@"*_~[!`<"]; while (![scanner isAtEnd]) { @@ -230,80 +234,100 @@ - (void)_processLine:(NSString *)line NSAssert(effectiveOpeningMarker, @"There should be a closing marker to look for because we only get here from having scanned for marker characters"); - - if ([effectiveOpeningMarker isEqualToString:@"!["] || [effectiveOpeningMarker isEqualToString:@"["]) + if ([effectiveOpeningMarker isEqualToString:@"!["] || [effectiveOpeningMarker isEqualToString:@"["] || [effectiveOpeningMarker isEqualToString:@"<"]) { NSDictionary *attributes = nil; - if ([scanner scanUpToString:@"]" intoString:&enclosedPart]) + NSString *closingMarker; + BOOL isSimpleHREF; + + if ([effectiveOpeningMarker isEqualToString:@"<"]) + { + closingMarker = @">"; + isSimpleHREF = YES; + } + else + { + closingMarker = @"]"; + isSimpleHREF = NO; + } + + if ([scanner scanUpToString:closingMarker intoString:&enclosedPart]) { // scan closing part of link - if ([scanner scanString:@"]" intoString:NULL]) + if ([scanner scanString:closingMarker intoString:NULL]) { - // skip whitespace - [scanner scanCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:NULL]; - - if ([scanner scanString:@"(" intoString:NULL]) + if (isSimpleHREF) { - // has potentially inline address - - NSString *hyperlink; + attributes = [NSDictionary dictionaryWithObject:enclosedPart forKey:@"href"]; + } + else + { + // skip whitespace + [scanner scanCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:NULL]; - if ([scanner scanUpToString:@")" intoString:&hyperlink]) + if ([scanner scanString:@"(" intoString:NULL]) { - // see if it is closed too - if ([scanner scanString:@")" intoString:NULL]) + // has potentially inline address + + NSString *hyperlink; + + if ([scanner scanUpToString:@")" intoString:&hyperlink]) { - NSString *URLString; - NSString *title; - - NSScanner *urlScanner = [NSScanner scannerWithString:hyperlink]; - urlScanner.charactersToBeSkipped = nil; - - if ([urlScanner scanMarkdownHyperlink:&URLString title:&title]) + // see if it is closed too + if ([scanner scanString:@")" intoString:NULL]) { - NSMutableDictionary *tmpDict = [NSMutableDictionary dictionary]; + NSString *URLString; + NSString *title; - if ([URLString length]) - { - tmpDict[@"href"] = URLString; - } + NSScanner *urlScanner = [NSScanner scannerWithString:hyperlink]; + urlScanner.charactersToBeSkipped = nil; - if ([title length]) + if ([urlScanner scanMarkdownHyperlink:&URLString title:&title]) { - tmpDict[@"title"] = title; - } - - if ([tmpDict count]) - { - attributes = [tmpDict copy]; + NSMutableDictionary *tmpDict = [NSMutableDictionary dictionary]; + + if ([URLString length]) + { + tmpDict[@"href"] = URLString; + } + + if ([title length]) + { + tmpDict[@"title"] = title; + } + + if ([tmpDict count]) + { + attributes = [tmpDict copy]; + } } } } } - } - else if ([scanner scanString:@"[" intoString:NULL]) - { - // has potentially address via ref - - NSString *reference; - - if ([scanner scanUpToString:@"]" intoString:&reference]) + else if ([scanner scanString:@"[" intoString:NULL]) { - // see if it is closed too - if ([scanner scanString:@"]" intoString:NULL]) + // has potentially address via ref + + NSString *reference; + + if ([scanner scanUpToString:@"]" intoString:&reference]) { - attributes = _references[[reference lowercaseString]]; + // see if it is closed too + if ([scanner scanString:@"]" intoString:NULL]) + { + attributes = _references[[reference lowercaseString]]; + } } - } - else - { - // could be [] - - if ([scanner scanString:@"]" intoString:NULL]) + else { - reference = [enclosedPart lowercaseString]; - attributes = _references[reference]; + // could be [] + + if ([scanner scanString:@"]" intoString:NULL]) + { + reference = [enclosedPart lowercaseString]; + attributes = _references[reference]; + } } } } @@ -313,7 +337,7 @@ - (void)_processLine:(NSString *)line // only output hyperlink if all is ok if (attributes) { - if ([effectiveOpeningMarker isEqualToString:@"["]) + if ([effectiveOpeningMarker isEqualToString:@"["] || isSimpleHREF) { [self _pushTag:@"a" attributes:attributes]; [self _reportCharacters:enclosedPart]; diff --git a/Test/Source/DTMarkdownParserTest.m b/Test/Source/DTMarkdownParserTest.m index 893bebf..a425c8a 100644 --- a/Test/Source/DTMarkdownParserTest.m +++ b/Test/Source/DTMarkdownParserTest.m @@ -818,6 +818,21 @@ - (void)testDoubleSquareLinkMissingClose STAssertEqualObjects(actual, expected, @"Expected result did not match"); } +- (void)testLinkWithAngleBrackets +{ + NSString *string = @"This is a link to \n"; + + DTMarkdownParser *parser = [self _parserForString:string options:0]; + + BOOL result = [parser parse]; + STAssertTrue(result, @"Parser should return YES"); + + NSString *expected = @"

This is a link to http://foo.com

\n"; + NSString *actual = [self _HTMLFromInvocations]; + + STAssertEqualObjects(actual, expected, @"Expected result did not match"); +} + #pragma mark - Images - (void)testInlineImage