Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add nested lists and strikethrough. #73

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions TSMarkdownParser/TSMarkdownParser.m
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ - (instancetype)init {
// Courier New and Courier are the only monospace fonts compatible with watchOS 2
// #69: avoiding crash if font is missing
_monospaceAttributes = @{ NSFontAttributeName: [UIFont fontWithName:@"Courier New" size:defaultSize] ?: [UIFont fontWithName:@"Courier" size:defaultSize] ?: [UIFont systemFontOfSize:defaultSize],
NSForegroundColorAttributeName: [UIColor colorWithSRGBRed:0.95 green:0.54 blue:0.55 alpha:1] };
NSForegroundColorAttributeName: [UIColor blackColor] };
_strongAttributes = @{ NSFontAttributeName: [UIFont boldSystemFontOfSize:defaultSize] };

return self;
}

Expand All @@ -93,12 +93,6 @@ + (instancetype)standardParser {

/* block parsing */

[defaultParser addHeaderParsingWithMaxLevel:0 leadFormattingBlock:^(NSMutableAttributedString *attributedString, NSRange range, __unused NSUInteger level) {
[attributedString deleteCharactersInRange:range];
} textFormattingBlock:^(NSMutableAttributedString *attributedString, NSRange range, NSUInteger level) {
[TSMarkdownParser addAttributes:weakParser.headerAttributes atIndex:level - 1 toString:attributedString range:range];
}];

[defaultParser addListParsingWithMaxLevel:0 leadFormattingBlock:^(NSMutableAttributedString *attributedString, NSRange range, NSUInteger level) {
NSMutableString *listString = [NSMutableString string];
while (--level)
Expand Down Expand Up @@ -204,10 +198,22 @@ + (instancetype)standardParser {
[attributedString addAttributes:weakParser.strongAttributes range:range];
}];

[defaultParser addStrikethroughParsingWithFormattingBlock:^(NSMutableAttributedString *attributedString, NSRange range) {
[attributedString addAttribute:NSStrikethroughStyleAttributeName
value:@2
range:range];
}];

[defaultParser addEmphasisParsingWithFormattingBlock:^(NSMutableAttributedString *attributedString, NSRange range) {
[attributedString addAttributes:weakParser.emphasisAttributes range:range];
}];

[defaultParser addHeaderParsingWithMaxLevel:0 leadFormattingBlock:^(NSMutableAttributedString *attributedString, NSRange range, __unused NSUInteger level) {
[attributedString deleteCharactersInRange:range];
} textFormattingBlock:^(NSMutableAttributedString *attributedString, NSRange range, NSUInteger level) {
[TSMarkdownParser addAttributes:weakParser.headerAttributes atIndex:level - 1 toString:attributedString range:range];
}];

/* unescaping parsing */

[defaultParser addCodeUnescapingParsingWithFormattingBlock:^(NSMutableAttributedString *attributedString, NSRange range) {
Expand Down Expand Up @@ -236,7 +242,7 @@ + (void)addAttributes:(NSArray<NSDictionary<NSString *, id> *> *)attributesArray
// lead regex
static NSString *const TSMarkdownHeaderRegex = @"^(#{1,%@})\\s+(.+)$";
static NSString *const TSMarkdownShortHeaderRegex = @"^(#{1,%@})\\s*([^#].*)$";
static NSString *const TSMarkdownListRegex = @"^([\\*\\+\\-]{1,%@})\\s+(.+)$";
static NSString *const TSMarkdownListRegex = @"^([\\h]*[\\*\\+\\-]{1,%@})\\s+(.+)$";
static NSString *const TSMarkdownShortListRegex = @"^([\\*\\+\\-]{1,%@})\\s*([^\\*\\+\\-].*)$";
static NSString *const TSMarkdownQuoteRegex = @"^(\\>{1,%@})\\s+(.+)$";
static NSString *const TSMarkdownShortQuoteRegex = @"^(\\>{1,%@})\\s*([^\\>].*)$";
Expand All @@ -248,6 +254,7 @@ + (void)addAttributes:(NSArray<NSDictionary<NSString *, id> *> *)attributesArray
// inline enclosed regex
static NSString *const TSMarkdownMonospaceRegex = @"(`+)(\\s*.*?[^`]\\s*)(\\1)(?!`)";
static NSString *const TSMarkdownStrongRegex = @"(\\*\\*|__)(.+?)(\\1)";
static NSString *const TSMarkdownStikethroughRegex = @"(\\~\\~|__)(.+?)(\\1)";
static NSString *const TSMarkdownEmRegex = @"(\\*|_)(.+?)(\\1)";

#pragma mark escaping parsing
Expand Down Expand Up @@ -449,6 +456,10 @@ - (void)addStrongParsingWithFormattingBlock:(void(^)(NSMutableAttributedString *
[self addEnclosedParsingWithPattern:TSMarkdownStrongRegex formattingBlock:formattingBlock];
}

- (void)addStrikethroughParsingWithFormattingBlock:(void(^)(NSMutableAttributedString *attributedString, NSRange range))formattingBlock {
[self addEnclosedParsingWithPattern:TSMarkdownStikethroughRegex formattingBlock:formattingBlock];
}

- (void)addEmphasisParsingWithFormattingBlock:(TSMarkdownParserFormattingBlock)formattingBlock {
[self addEnclosedParsingWithPattern:TSMarkdownEmRegex formattingBlock:formattingBlock];
}
Expand Down
12 changes: 12 additions & 0 deletions TSMarkdownParserTests/TSMarkdownParserTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,18 @@ - (void)testStandardListWith2AsterisksParsing {
XCTAssertEqualObjects(attributedString.string, @"Hello\n\t•\tI drink in a café everyday\nto use Wi-Fi");
}

- (void)testNestedList {
NSAttributedString *attributedString = [self.standardParser attributedStringFromMarkdown:@"\n\n- 1\n - 1.1\n- 2"];
XCTAssertEqualObjects(attributedString.string, @"\n\n•\t1\n\t\t•\t1.1\n•\t2");
}

- (void)testStrikethroughParsing {
NSAttributedString *attributedString = [self.standardParser attributedStringFromMarkdown:@"~~Hello~~"];
NSNumber *strikethrough = [attributedString attribute:NSStrikethroughStyleAttributeName atIndex:2 effectiveRange:NULL];
XCTAssertNotNil(strikethrough);
XCTAssertEqualObjects(attributedString.string, @"Hello");
}

- (void)testStandardQuoteParsing {
NSAttributedString *attributedString = [self.standardParser attributedStringFromMarkdown:@"Hello\n> I drink in a café everyday\nto use Wi-Fi"];
XCTAssertEqualObjects(attributedString.string, @"Hello\n\tI drink in a café everyday\nto use Wi-Fi");
Expand Down