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

Nested support blockquotes on iOS #97

Closed
wants to merge 7 commits into from
Closed
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
18 changes: 11 additions & 7 deletions ios/MarkdownLayoutManager.mm
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,32 @@ - (void)drawBackgroundForGlyphRange:(NSRange)glyphsToShow atPoint:(CGPoint)origi
[super drawBackgroundForGlyphRange:glyphsToShow atPoint:origin];

[self enumerateLineFragmentsForGlyphRange:glyphsToShow usingBlock:^(CGRect rect, CGRect usedRect, NSTextContainer * _Nonnull textContainer, NSRange glyphRange, BOOL * _Nonnull stop) {
__block BOOL isBlockquote = NO;
__block int nestingLevel = 0;
RCTMarkdownUtils *markdownUtils = [self valueForKey:@"markdownUtils"];
[markdownUtils.blockquoteRanges enumerateObjectsUsingBlock:^(NSValue *item, NSUInteger idx, BOOL * _Nonnull stop) {
NSRange range = [item rangeValue];
NSUInteger start = range.location;
NSUInteger end = start + range.length;
NSUInteger location = glyphRange.location;
if (location >= start && location < end) {
isBlockquote = YES;
*stop = YES;
nestingLevel++;
}
}];
if (isBlockquote) {
if (nestingLevel > 0) {
CGFloat paddingLeft = markdownUtils.backedTextInputView.textContainerInset.left;
CGFloat paddingTop = markdownUtils.backedTextInputView.textContainerInset.top;
CGFloat x = paddingLeft + markdownUtils.markdownStyle.blockquoteMarginLeft;
CGFloat y = paddingTop + rect.origin.y;
CGFloat width = markdownUtils.markdownStyle.blockquoteBorderWidth;
CGFloat height = rect.size.height;
CGRect lineRect = CGRectMake(x, y, width, height);
[markdownUtils.markdownStyle.blockquoteBorderColor setFill];
UIRectFill(lineRect);

CGFloat nestShift = paddingLeft + width + markdownUtils.markdownStyle.blockquoteMarginLeft;

for(int strip = 0; strip < nestingLevel; strip++) {
CGRect lineRect = CGRectMake(x + (strip * nestShift), y, width, height);
[markdownUtils.markdownStyle.blockquoteBorderColor setFill];
UIRectFill(lineRect);
}
}
}];
}
Expand Down
6 changes: 6 additions & 0 deletions ios/RCTMarkdownUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ NS_ASSUME_NONNULL_BEGIN

- (NSAttributedString *)parseMarkdown:(nullable NSAttributedString *)input;

// returns the most outer blockquote range that surrounds the given range; if there is no such range, it returns the passed range
- (NSRange)getCircumferencingBlockquoteRange:(NSRange)range;

// counts the number of ranges the given range is contained within
- (int)getBlockquoteNestLevel:(NSRange)range;

@end

NS_ASSUME_NONNULL_END
33 changes: 29 additions & 4 deletions ios/RCTMarkdownUtils.mm
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,12 @@ - (NSAttributedString *)parseMarkdown:(nullable NSAttributedString *)input
} else if ([type isEqualToString:@"blockquote"]) {
CGFloat indent = _markdownStyle.blockquoteMarginLeft + _markdownStyle.blockquoteBorderWidth + _markdownStyle.blockquotePaddingLeft;
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.firstLineHeadIndent = indent;
paragraphStyle.headIndent = indent;
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range];
[_blockquoteRanges addObject:[NSValue valueWithRange:range]];
NSRange circumferencingRange = [self getCircumferencingBlockquoteRange:range];
int blockquoteNestLevel = [self getBlockquoteNestLevel:range];
paragraphStyle.firstLineHeadIndent = indent * blockquoteNestLevel;
paragraphStyle.headIndent = indent * blockquoteNestLevel;
[_blockquoteRanges addObject:[NSValue valueWithRange:circumferencingRange]];
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:circumferencingRange];
} else if ([type isEqualToString:@"pre"]) {
[attributedString addAttribute:NSForegroundColorAttributeName value:_markdownStyle.preColor range:range];
NSRange rangeForBackground = [inputString characterAtIndex:range.location] == '\n' ? NSMakeRange(range.location + 1, range.length - 1) : range;
Expand All @@ -131,4 +133,27 @@ - (NSAttributedString *)parseMarkdown:(nullable NSAttributedString *)input
return attributedString;
}

- (NSRange)getCircumferencingBlockquoteRange:(NSRange)range
{
for (NSValue *quoteRange in _blockquoteRanges) {
NSRange quoteRangeValue = [quoteRange rangeValue];
if (quoteRangeValue.location < range.location && quoteRangeValue.location + quoteRangeValue.length >= range.location + range.length) {
return quoteRangeValue;
}
}
return range;
}

- (int)getBlockquoteNestLevel:(NSRange)range
{
int nestLevel = 1;
for (NSValue *quoteRange in _blockquoteRanges) {
NSRange quoteRangeValue = [quoteRange rangeValue];
if (quoteRangeValue.location < range.location && quoteRangeValue.location + quoteRangeValue.length >= range.location + range.length) {
nestLevel++;
}
}
return nestLevel;
}

@end
Loading