Permalink
Browse files

Merge pull request #426 from robbertkl/url-fix

Fix handling of links containing underscores
  • Loading branch information...
2 parents 7b51b9a + 1760fc2 commit 3fc19dc79cbe1239d3a9f6a703112b7bf5709e01 @tomaz committed Feb 14, 2014
Showing with 54 additions and 6 deletions.
  1. +45 −6 Processing/GBCommentsProcessor.m
  2. +9 −0 Testing/GBCommentsProcessor-PreprocessingTesting.m
View
51 Processing/GBCommentsProcessor.m
@@ -105,6 +105,7 @@ - (BOOL)isLineMatchingDirectiveStatement:(NSString *)string;
- (GBCommentComponent *)commentComponentByPreprocessingString:(NSString *)string withFlags:(GBProcessingFlag)flags;
- (GBCommentComponent *)commentComponentWithStringValue:(NSString *)string;
- (NSString *)stringByPreprocessingString:(NSString *)string withFlags:(GBProcessingFlag)flags;
+- (NSString *)stringByPreprocessingNonLinkString:(NSString *)string withFlags:(GBProcessingFlag)flags;
- (NSString *)stringByConvertingCrossReferencesInString:(NSString *)string withFlags:(GBProcessingFlag)flags;
- (NSString *)stringByConvertingSimpleCrossReferencesInString:(NSString *)string searchRange:(NSRange)searchRange flags:(GBProcessingFlag)flags;
- (NSString *)markdownLinkWithDescription:(NSString *)description address:(NSString *)address flags:(GBProcessingFlag)flags;
@@ -605,6 +606,49 @@ - (NSString *)stringByPreprocessingString:(NSString *)string withFlags:(GBProces
// Converts all appledoc formatting and cross refs to proper Markdown text suitable for passing to Markdown generator.
if ([string length] == 0) return string;
+ // Process all links separately, so that they won't be cut off if the contain _'s (which is a formatting marker)
+ NSString *pattern = @"(\\[.+?\\]\\(.+?\\))";
+ NSArray *components = [string arrayOfDictionariesByMatchingRegex:pattern withKeysAndCaptures:@"link", 1, nil];
+ NSRange searchRange = NSMakeRange(0, [string length]);
+ NSMutableString *result = [NSMutableString stringWithCapacity:[string length]];
+ for (NSDictionary *component in components) {
+ NSString *componentLink = [component objectForKey:@"link"];
+ NSRange componentRange = [string rangeOfString:componentLink options:0 range:searchRange];
+
+ if (componentRange.location > searchRange.location) {
+ NSRange skippedRange = NSMakeRange(searchRange.location, componentRange.location - searchRange.location);
+ NSString *skippedText = [string substringWithRange:skippedRange];
+ NSString *preprocessedText = [self stringByPreprocessingNonLinkString:skippedText withFlags:flags];
+ [result appendString:preprocessedText];
+ }
+
+ // Don't process the link using the formatting markers, might contain formatting markers
+ NSString *convertedLink = [self stringByConvertingCrossReferencesInString:componentLink withFlags:flags];
+ [result appendString:convertedLink];
+
+ NSUInteger location = componentRange.location + [componentLink length];
+ searchRange = NSMakeRange(location, [string length] - location);
+ }
+
+ // If there is some remaining text, preprocess it as well.
+ if ([string length] > searchRange.location) {
+ NSString *remainingText = [string substringWithRange:searchRange];
+ NSString *preprocessedText = [self stringByPreprocessingNonLinkString:remainingText withFlags:flags];
+ [result appendString:preprocessedText];
+ }
+
+ // Finally replace all embedded code span Markdown links to proper ones. Embedded links look like: `[`desc`](address)`.
+ NSString *regex = [NSString stringWithFormat:@"`((?:%@)?\\[`[^`]*`\\]\\(.+?\\)(?:%@)?)`", self.components.codeSpanStartMarker, self.components.codeSpanEndMarker];
+ NSString *clean = [result stringByReplacingOccurrencesOfRegex:regex usingBlock:^NSString *(NSInteger captureCount, NSString *const *capturedStrings, const NSRange *capturedRanges, volatile BOOL *const stop) {
+ return capturedStrings[1];
+ }];
+ return clean;
+}
+
+- (NSString *)stringByPreprocessingNonLinkString:(NSString *)string withFlags:(GBProcessingFlag)flags {
+ // Converts all appledoc formatting and cross refs to proper Markdown text suitable for passing to Markdown generator.
+ if ([string length] == 0) return string;
+
// Formatting markers are fine, except *, which should be converted to **. To simplify cross refs detection, we handle all possible formatting markers though so we can search for cross refs within "clean" formatted text, without worrying about markers interfering with search. Note that we also handle "standard" Markdown nested formats and bold markers here, so that we properly handle cross references within.
NSString *pattern = @"(?s:(\\*__|__\\*|\\*\\*_|_\\*\\*|\\*\\*\\*|___|\\*_|_\\*|\\*\\*|__|\\*|_|==!!==|`)(.+?)\\1)";
NSArray *components = [string arrayOfDictionariesByMatchingRegex:pattern withKeysAndCaptures:@"marker", 1, @"value", 2, nil];
@@ -677,12 +721,7 @@ - (NSString *)stringByPreprocessingString:(NSString *)string withFlags:(GBProces
[result appendString:convertedText];
}
- // Finally replace all embedded code span Markdown links to proper ones. Embedded links look like: `[`desc`](address)`.
- NSString *regex = [NSString stringWithFormat:@"`((?:%@)?\\[`[^`]*`\\]\\(.+?\\)(?:%@)?)`", self.components.codeSpanStartMarker, self.components.codeSpanEndMarker];
- NSString *clean = [result stringByReplacingOccurrencesOfRegex:regex usingBlock:^NSString *(NSInteger captureCount, NSString *const *capturedStrings, const NSRange *capturedRanges, volatile BOOL *const stop) {
- return capturedStrings[1];
- }];
- return clean;
+ return result;
}
- (NSString *)stringByConvertingCrossReferencesInString:(NSString *)string withFlags:(GBProcessingFlag)flags {
View
9 Testing/GBCommentsProcessor-PreprocessingTesting.m
@@ -119,6 +119,15 @@ - (void)testStringByPreprocessingString_shouldLeaveMarkdownBoldItalicsMarkers {
assertThat(result6, is(@"***text1*** *** marked ***"));
}
+- (void)testStringByPreprocessingString_shouldKeepReferencesWithMarkersIntact {
+ // setup
+ GBCommentsProcessor *processor = [self defaultProcessor];
+ // execute
+ NSString *result = [processor stringByPreprocessingString:@"[test_test](http://www.example.com/test_test.html)" withFlags:0];
+ // verify
+ assertThat(result, is(@"[test_test](http://www.example.com/test_test.html)"));
+}
+
#pragma mark Class, category and protocol cross references detection
- (void)testStringByConvertingCrossReferencesInString_shouldConvertClass {

0 comments on commit 3fc19dc

Please sign in to comment.