Skip to content

Commit 07d33d5

Browse files
authored
refactor(ios): update paragraph spacing logic to handle marginTop correctly (#106)
1 parent 718798c commit 07d33d5

4 files changed

Lines changed: 31 additions & 14 deletions

File tree

ios/renderer/HeadingRenderer.m

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,10 @@ - (void)renderNode:(MarkdownASTNode *)node into:(NSMutableAttributedString *)out
7272
applyLineHeight(output, range, style.lineHeight);
7373
applyTextAlignment(output, range, style.textAlign);
7474

75-
// Use paragraphSpacingBefore for internal elements; applyBlockSpacingBefore handles index 0
75+
// Skip marginTop for the first block — already handled by applyBlockSpacingBefore above
7676
if (contentStart != 1) {
77-
applyParagraphSpacingBefore(output, range, style.marginTop);
77+
NSUInteger inserted = applyParagraphSpacingBefore(output, range, style.marginTop);
78+
start += inserted;
7879
}
7980
applyParagraphSpacingAfter(output, start, style.marginBottom);
8081
}

ios/renderer/ParagraphRenderer.m

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,10 @@ - (void)renderNode:(MarkdownASTNode *)node into:(NSMutableAttributedString *)out
6565

6666
applyTextAlignment(output, range, _config.paragraphTextAlign);
6767

68-
// Apply marginTop for non-index-0 elements using paragraphSpacingBefore
68+
// Skip marginTop for the first block — already handled by applyBlockSpacingBefore above
6969
if (shouldApplyMargin && contentStart != 1) {
70-
applyParagraphSpacingBefore(output, range, marginTop);
70+
NSUInteger inserted = applyParagraphSpacingBefore(output, range, marginTop);
71+
start += inserted;
7172
}
7273

7374
CGFloat marginBottom = 0;

ios/utils/ParagraphStyleUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ extern NSAttributedString *kNewlineAttributedString;
1010
NSWritingDirection currentWritingDirection(void);
1111
NSMutableParagraphStyle *getOrCreateParagraphStyle(NSMutableAttributedString *output, NSUInteger index);
1212
void applyParagraphSpacingAfter(NSMutableAttributedString *output, NSUInteger start, CGFloat marginBottom);
13-
void applyParagraphSpacingBefore(NSMutableAttributedString *output, NSRange range, CGFloat marginTop);
13+
NSUInteger applyParagraphSpacingBefore(NSMutableAttributedString *output, NSRange range, CGFloat marginTop);
1414
NSUInteger applyBlockSpacingBefore(NSMutableAttributedString *output, NSUInteger insertionPoint, CGFloat marginTop);
1515
void applyBlockSpacingAfter(NSMutableAttributedString *output, CGFloat marginBottom);
1616
void applyLineHeight(NSMutableAttributedString *output, NSRange range, CGFloat lineHeight);

ios/utils/ParagraphStyleUtils.m

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,32 @@ void applyParagraphSpacingAfter(NSMutableAttributedString *output, NSUInteger st
3939
[output addAttribute:NSParagraphStyleAttributeName value:style range:range];
4040
}
4141

42-
void applyParagraphSpacingBefore(NSMutableAttributedString *output, NSRange range, CGFloat marginTop)
42+
NSUInteger applyParagraphSpacingBefore(NSMutableAttributedString *output, NSRange range, CGFloat marginTop)
4343
{
44-
if (marginTop <= 0) {
45-
return;
46-
}
44+
if (marginTop <= 0 || range.location == 0)
45+
return 0;
4746

48-
// Note: paragraphSpacingBefore does not work at index 0 in TextKit.
49-
// Leading spacing for the first element is handled by renderers via applyBlockSpacingBefore.
50-
NSMutableParagraphStyle *style = getOrCreateParagraphStyle(output, range.location);
51-
style.paragraphSpacingBefore = marginTop;
52-
[output addAttribute:NSParagraphStyleAttributeName value:style range:range];
47+
NSUInteger prevIdx = range.location - 1;
48+
if ([output.string characterAtIndex:prevIdx] != '\n')
49+
return 0;
50+
51+
NSParagraphStyle *prevStyle = [output attribute:NSParagraphStyleAttributeName atIndex:prevIdx effectiveRange:NULL];
52+
53+
CGFloat prevMarginBottom = prevStyle.paragraphSpacing;
54+
if (prevMarginBottom >= marginTop)
55+
return 0;
56+
57+
CGFloat extraGap = marginTop - prevMarginBottom;
58+
59+
NSMutableParagraphStyle *spacerStyle = [kBlockSpacerTemplate mutableCopy];
60+
spacerStyle.baseWritingDirection = currentWritingDirection();
61+
spacerStyle.paragraphSpacing = MAX(0, extraGap - 1.0);
62+
63+
NSDictionary *attrs = @{NSParagraphStyleAttributeName : spacerStyle};
64+
NSAttributedString *spacer = [[NSAttributedString alloc] initWithString:@"\n" attributes:attrs];
65+
66+
[output insertAttributedString:spacer atIndex:range.location];
67+
return 1;
5368
}
5469

5570
NSUInteger applyBlockSpacingBefore(NSMutableAttributedString *output, NSUInteger insertionPoint, CGFloat marginTop)

0 commit comments

Comments
 (0)