react-native-enriched-markdown 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +80 -8
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +17 -2
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +6 -1
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +9 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +6 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +28 -3
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +225 -1
- package/android/src/main/cpp/jni-adapter.cpp +28 -11
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +132 -15
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager.kt +1 -16
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +67 -13
- package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +241 -21
- package/android/src/main/java/com/swmansion/enriched/markdown/accessibility/MarkdownAccessibilityHelper.kt +279 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/events/LinkLongPressEvent.kt +23 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +2 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +17 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +13 -18
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +23 -24
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeRenderer.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/DocumentRenderer.kt +2 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/EmphasisRenderer.kt +2 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +18 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ImageRenderer.kt +22 -6
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/LineBreakRenderer.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt +3 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +2 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +16 -9
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +5 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ParagraphRenderer.kt +23 -9
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/Renderer.kt +24 -10
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/StrikethroughRenderer.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/StrongRenderer.kt +2 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/TextRenderer.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ThematicBreakRenderer.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/UnderlineRenderer.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/LineHeightSpan.kt +8 -17
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt +19 -5
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/MarginBottomSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrikethroughSpan.kt +12 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/BaseBlockStyle.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +3 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +3 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/HeadingStyle.kt +5 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +3 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +3 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ParagraphStyle.kt +5 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StrikethroughStyle.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +32 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleParser.kt +22 -5
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/TextAlignment.kt +32 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/UnderlineStyle.kt +17 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/HTMLGenerator.kt +23 -5
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/LinkLongPressMovementMethod.kt +121 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/MarkdownExtractor.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/Utils.kt +58 -56
- package/android/src/main/jni/CMakeLists.txt +1 -13
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +0 -13
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +2 -14
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +3 -0
- package/cpp/parser/MD4CParser.cpp +21 -8
- package/cpp/parser/MD4CParser.hpp +5 -1
- package/cpp/parser/MarkdownASTNode.hpp +2 -0
- package/ios/EnrichedMarkdownText.mm +356 -29
- package/ios/attachments/{ImageAttachment.h → EnrichedMarkdownImageAttachment.h} +1 -1
- package/ios/attachments/{ImageAttachment.m → EnrichedMarkdownImageAttachment.m} +4 -4
- package/ios/generated/EnrichedMarkdownTextSpec/EventEmitters.cpp +9 -0
- package/ios/generated/EnrichedMarkdownTextSpec/EventEmitters.h +6 -0
- package/ios/generated/EnrichedMarkdownTextSpec/Props.cpp +28 -3
- package/ios/generated/EnrichedMarkdownTextSpec/Props.h +225 -1
- package/ios/parser/MarkdownASTNode.h +2 -0
- package/ios/parser/MarkdownParser.h +9 -0
- package/ios/parser/MarkdownParser.mm +31 -2
- package/ios/parser/MarkdownParserBridge.mm +13 -3
- package/ios/renderer/AttributedRenderer.h +2 -0
- package/ios/renderer/AttributedRenderer.m +52 -19
- package/ios/renderer/BlockquoteRenderer.m +7 -6
- package/ios/renderer/CodeBlockRenderer.m +9 -8
- package/ios/renderer/HeadingRenderer.m +31 -24
- package/ios/renderer/ImageRenderer.m +31 -10
- package/ios/renderer/ListItemRenderer.m +51 -39
- package/ios/renderer/ListRenderer.m +21 -18
- package/ios/renderer/ParagraphRenderer.m +27 -16
- package/ios/renderer/RenderContext.h +17 -0
- package/ios/renderer/RenderContext.m +66 -2
- package/ios/renderer/RendererFactory.m +6 -0
- package/ios/renderer/StrikethroughRenderer.h +6 -0
- package/ios/renderer/StrikethroughRenderer.m +40 -0
- package/ios/renderer/UnderlineRenderer.h +6 -0
- package/ios/renderer/UnderlineRenderer.m +39 -0
- package/ios/styles/StyleConfig.h +46 -0
- package/ios/styles/StyleConfig.mm +351 -12
- package/ios/utils/AccessibilityInfo.h +35 -0
- package/ios/utils/AccessibilityInfo.m +24 -0
- package/ios/utils/CodeBlockBackground.m +4 -9
- package/ios/utils/FontUtils.h +5 -0
- package/ios/utils/FontUtils.m +14 -0
- package/ios/utils/HTMLGenerator.m +21 -7
- package/ios/utils/MarkdownAccessibilityElementBuilder.h +45 -0
- package/ios/utils/MarkdownAccessibilityElementBuilder.m +323 -0
- package/ios/utils/MarkdownExtractor.m +18 -5
- package/ios/utils/ParagraphStyleUtils.h +10 -2
- package/ios/utils/ParagraphStyleUtils.m +57 -2
- package/ios/utils/PasteboardUtils.h +1 -1
- package/ios/utils/PasteboardUtils.m +3 -3
- package/lib/module/EnrichedMarkdownText.js +33 -2
- package/lib/module/EnrichedMarkdownText.js.map +1 -1
- package/lib/module/EnrichedMarkdownTextNativeComponent.ts +83 -3
- package/lib/module/index.js +0 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.js +58 -14
- package/lib/module/normalizeMarkdownStyle.js.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownText.d.ts +85 -3
- package/lib/typescript/src/EnrichedMarkdownText.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +75 -1
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/EnrichedMarkdownText.tsx +133 -5
- package/src/EnrichedMarkdownTextNativeComponent.ts +83 -3
- package/src/index.tsx +5 -2
- package/src/normalizeMarkdownStyle.ts +46 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +0 -9
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +0 -25
|
@@ -20,12 +20,9 @@
|
|
|
20
20
|
return self;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
#pragma mark - Rendering
|
|
24
|
-
|
|
25
23
|
- (void)renderNode:(MarkdownASTNode *)node into:(NSMutableAttributedString *)output context:(RenderContext *)context
|
|
26
24
|
{
|
|
27
|
-
//
|
|
28
|
-
// We only set the block style if no parent element (like a list or blockquote) has already established one.
|
|
25
|
+
// Only set block style if a parent element (e.g. List, Blockquote) hasn't already established one
|
|
29
26
|
BOOL isTopLevel = (context.currentBlockType == BlockTypeNone);
|
|
30
27
|
|
|
31
28
|
if (isTopLevel) {
|
|
@@ -33,37 +30,51 @@
|
|
|
33
30
|
}
|
|
34
31
|
|
|
35
32
|
NSUInteger start = output.length;
|
|
33
|
+
BOOL shouldApplyMargin =
|
|
34
|
+
(context.currentBlockType == BlockTypeNone || context.currentBlockType == BlockTypeParagraph);
|
|
35
|
+
|
|
36
|
+
// Detect if the paragraph is a wrapper for a standalone image to use image-specific spacing
|
|
37
|
+
BOOL isBlockImage = (node.children.count == 1 && ((MarkdownASTNode *)node.children[0]).type == MarkdownNodeTypeImage);
|
|
38
|
+
CGFloat marginTop = isBlockImage ? _config.imageMarginTop : _config.paragraphMarginTop;
|
|
39
|
+
|
|
40
|
+
NSUInteger contentStart = start;
|
|
41
|
+
|
|
42
|
+
// Handle leading margin for the first element in the document (Index 0 check)
|
|
43
|
+
if (shouldApplyMargin && start == 0) {
|
|
44
|
+
NSUInteger offset = applyBlockSpacingBefore(output, 0, marginTop);
|
|
45
|
+
contentStart += offset;
|
|
46
|
+
start += offset;
|
|
47
|
+
}
|
|
48
|
+
|
|
36
49
|
@try {
|
|
37
50
|
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
38
51
|
} @finally {
|
|
39
|
-
// Only clear the style if this paragraph was the one that set it.
|
|
40
52
|
if (isTopLevel) {
|
|
41
53
|
[context clearBlockStyle];
|
|
42
54
|
}
|
|
43
55
|
}
|
|
44
56
|
|
|
45
|
-
// 2. Geometry and Spacing Logic
|
|
46
57
|
if (output.length <= start)
|
|
47
58
|
return;
|
|
48
59
|
NSRange range = NSMakeRange(start, output.length - start);
|
|
49
60
|
|
|
50
|
-
//
|
|
51
|
-
// Images often require different spacing and should not have standard line height applied.
|
|
52
|
-
BOOL isBlockImage = (node.children.count == 1 && ((MarkdownASTNode *)node.children[0]).type == MarkdownNodeTypeImage);
|
|
53
|
-
|
|
54
|
-
// Apply line height only for text paragraphs to avoid unwanted gaps above/below images.
|
|
61
|
+
// Avoid standard line height on block images to prevent vertical alignment issues
|
|
55
62
|
if (!isBlockImage) {
|
|
56
63
|
applyLineHeight(output, range, _config.paragraphLineHeight);
|
|
57
64
|
}
|
|
58
65
|
|
|
59
|
-
|
|
60
|
-
|
|
66
|
+
applyTextAlignment(output, range, _config.paragraphTextAlign);
|
|
67
|
+
|
|
68
|
+
// Apply marginTop for non-index-0 elements using paragraphSpacingBefore
|
|
69
|
+
if (shouldApplyMargin && contentStart != 1) {
|
|
70
|
+
applyParagraphSpacingBefore(output, range, marginTop);
|
|
71
|
+
}
|
|
72
|
+
|
|
61
73
|
CGFloat marginBottom = 0;
|
|
62
|
-
if (
|
|
74
|
+
if (shouldApplyMargin) {
|
|
63
75
|
marginBottom = isBlockImage ? _config.imageMarginBottom : _config.paragraphMarginBottom;
|
|
64
76
|
}
|
|
65
|
-
|
|
66
|
-
applyParagraphSpacing(output, start, marginBottom);
|
|
77
|
+
applyParagraphSpacingAfter(output, start, marginBottom);
|
|
67
78
|
}
|
|
68
79
|
|
|
69
80
|
@end
|
|
@@ -25,6 +25,15 @@ typedef NS_ENUM(NSInteger, ListType) { ListTypeUnordered, ListTypeOrdered };
|
|
|
25
25
|
@interface RenderContext : NSObject
|
|
26
26
|
@property (nonatomic, strong) NSMutableArray<NSValue *> *linkRanges;
|
|
27
27
|
@property (nonatomic, strong) NSMutableArray<NSString *> *linkURLs;
|
|
28
|
+
@property (nonatomic, strong) NSMutableArray<NSValue *> *headingRanges;
|
|
29
|
+
@property (nonatomic, strong) NSMutableArray<NSNumber *> *headingLevels;
|
|
30
|
+
@property (nonatomic, strong) NSMutableArray<NSValue *> *imageRanges;
|
|
31
|
+
@property (nonatomic, strong) NSMutableArray<NSString *> *imageAltTexts;
|
|
32
|
+
@property (nonatomic, strong) NSMutableArray<NSString *> *imageURLs;
|
|
33
|
+
@property (nonatomic, strong) NSMutableArray<NSValue *> *listItemRanges;
|
|
34
|
+
@property (nonatomic, strong) NSMutableArray<NSNumber *> *listItemPositions; // Position in parent list (1, 2, 3...)
|
|
35
|
+
@property (nonatomic, strong) NSMutableArray<NSNumber *> *listItemDepths; // Nesting depth (1 = top level, 2+ = nested)
|
|
36
|
+
@property (nonatomic, strong) NSMutableArray<NSNumber *> *listItemOrdered; // YES = ordered, NO = unordered (bullet)
|
|
28
37
|
@property (nonatomic, assign) BlockType currentBlockType;
|
|
29
38
|
@property (nonatomic, strong) BlockStyle *currentBlockStyle;
|
|
30
39
|
@property (nonatomic, assign) NSInteger currentHeadingLevel;
|
|
@@ -32,6 +41,8 @@ typedef NS_ENUM(NSInteger, ListType) { ListTypeUnordered, ListTypeOrdered };
|
|
|
32
41
|
@property (nonatomic, assign) NSInteger listDepth;
|
|
33
42
|
@property (nonatomic, assign) ListType listType;
|
|
34
43
|
@property (nonatomic, assign) NSInteger listItemNumber;
|
|
44
|
+
@property (nonatomic, assign) BOOL allowFontScaling;
|
|
45
|
+
@property (nonatomic, assign) CGFloat maxFontSizeMultiplier;
|
|
35
46
|
|
|
36
47
|
- (instancetype)init;
|
|
37
48
|
- (void)reset;
|
|
@@ -40,6 +51,12 @@ typedef NS_ENUM(NSInteger, ListType) { ListTypeUnordered, ListTypeOrdered };
|
|
|
40
51
|
- (NSMutableParagraphStyle *)spacerStyleWithHeight:(CGFloat)height spacing:(CGFloat)spacing;
|
|
41
52
|
- (NSMutableParagraphStyle *)blockSpacerStyleWithMargin:(CGFloat)margin;
|
|
42
53
|
- (void)registerLinkRange:(NSRange)range url:(NSString *)url;
|
|
54
|
+
- (void)registerHeadingRange:(NSRange)range level:(NSInteger)level text:(NSString *)text;
|
|
55
|
+
- (void)registerImageRange:(NSRange)range altText:(NSString *)altText url:(NSString *)url;
|
|
56
|
+
- (void)registerListItemRange:(NSRange)range
|
|
57
|
+
position:(NSInteger)position
|
|
58
|
+
depth:(NSInteger)depth
|
|
59
|
+
isOrdered:(BOOL)isOrdered;
|
|
43
60
|
- (void)setBlockStyle:(BlockType)type
|
|
44
61
|
fontSize:(CGFloat)fontSize
|
|
45
62
|
fontFamily:(NSString *)fontFamily
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#import "RenderContext.h"
|
|
2
2
|
#import "CodeBackground.h"
|
|
3
|
+
#import "FontUtils.h"
|
|
3
4
|
#import <React/RCTFont.h>
|
|
4
5
|
|
|
5
6
|
@implementation BlockStyle
|
|
@@ -16,8 +17,19 @@
|
|
|
16
17
|
if (self = [super init]) {
|
|
17
18
|
_linkRanges = [NSMutableArray array];
|
|
18
19
|
_linkURLs = [NSMutableArray array];
|
|
20
|
+
_headingRanges = [NSMutableArray array];
|
|
21
|
+
_headingLevels = [NSMutableArray array];
|
|
22
|
+
_imageRanges = [NSMutableArray array];
|
|
23
|
+
_imageAltTexts = [NSMutableArray array];
|
|
24
|
+
_imageURLs = [NSMutableArray array];
|
|
25
|
+
_listItemRanges = [NSMutableArray array];
|
|
26
|
+
_listItemPositions = [NSMutableArray array];
|
|
27
|
+
_listItemDepths = [NSMutableArray array];
|
|
28
|
+
_listItemOrdered = [NSMutableArray array];
|
|
19
29
|
_fontCache = [NSMutableDictionary dictionary];
|
|
20
30
|
_currentBlockStyle = [[BlockStyle alloc] init];
|
|
31
|
+
_allowFontScaling = YES;
|
|
32
|
+
_maxFontSizeMultiplier = 0;
|
|
21
33
|
|
|
22
34
|
NSMutableParagraphStyle *spacerTemplate = [[NSMutableParagraphStyle alloc] init];
|
|
23
35
|
_baseSpacerTemplate = [spacerTemplate copy];
|
|
@@ -36,8 +48,11 @@
|
|
|
36
48
|
|
|
37
49
|
- (UIFont *)cachedFontForSize:(CGFloat)fontSize family:(NSString *)fontFamily weight:(NSString *)fontWeight
|
|
38
50
|
{
|
|
51
|
+
CGFloat effectiveMultiplier = _allowFontScaling ? RCTFontSizeMultiplierWithMax(_maxFontSizeMultiplier) : 1.0;
|
|
52
|
+
|
|
39
53
|
NSString *weightKey = (fontWeight.length > 0) ? fontWeight : @"";
|
|
40
|
-
NSString *key =
|
|
54
|
+
NSString *key =
|
|
55
|
+
[NSString stringWithFormat:@"%.1f|%@|%@|%.2f", fontSize, fontFamily ?: @"", weightKey, effectiveMultiplier];
|
|
41
56
|
|
|
42
57
|
UIFont *cached = _fontCache[key];
|
|
43
58
|
if (cached) {
|
|
@@ -52,7 +67,7 @@
|
|
|
52
67
|
weight:effectiveWeight
|
|
53
68
|
style:nil
|
|
54
69
|
variant:nil
|
|
55
|
-
scaleMultiplier:
|
|
70
|
+
scaleMultiplier:effectiveMultiplier];
|
|
56
71
|
|
|
57
72
|
if (font) {
|
|
58
73
|
_fontCache[key] = font;
|
|
@@ -88,6 +103,46 @@
|
|
|
88
103
|
[self.linkURLs addObject:url ?: @""];
|
|
89
104
|
}
|
|
90
105
|
|
|
106
|
+
- (void)registerHeadingRange:(NSRange)range level:(NSInteger)level text:(NSString *)text
|
|
107
|
+
{
|
|
108
|
+
if (range.length == 0)
|
|
109
|
+
return;
|
|
110
|
+
[self.headingRanges addObject:[NSValue valueWithRange:range]];
|
|
111
|
+
[self.headingLevels addObject:@(level)];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
- (void)registerImageRange:(NSRange)range altText:(NSString *)altText url:(NSString *)url
|
|
115
|
+
{
|
|
116
|
+
if (range.length == 0)
|
|
117
|
+
return;
|
|
118
|
+
[self.imageRanges addObject:[NSValue valueWithRange:range]];
|
|
119
|
+
[self.imageAltTexts addObject:altText ?: @""];
|
|
120
|
+
[self.imageURLs addObject:url ?: @""];
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
#pragma mark - Registration Helpers
|
|
124
|
+
|
|
125
|
+
- (void)registerListItemRange:(NSRange)range
|
|
126
|
+
position:(NSInteger)position
|
|
127
|
+
depth:(NSInteger)depth
|
|
128
|
+
isOrdered:(BOOL)isOrdered
|
|
129
|
+
{
|
|
130
|
+
if (![self isValidRange:range])
|
|
131
|
+
return;
|
|
132
|
+
|
|
133
|
+
[self.listItemRanges addObject:[NSValue valueWithRange:range]];
|
|
134
|
+
[self.listItemPositions addObject:@(position)];
|
|
135
|
+
[self.listItemDepths addObject:@(depth)];
|
|
136
|
+
[self.listItemOrdered addObject:@(isOrdered)];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
#pragma mark - Private
|
|
140
|
+
|
|
141
|
+
- (BOOL)isValidRange:(NSRange)range
|
|
142
|
+
{
|
|
143
|
+
return range.length > 0 && range.location != NSNotFound;
|
|
144
|
+
}
|
|
145
|
+
|
|
91
146
|
#pragma mark - Block Style Management
|
|
92
147
|
|
|
93
148
|
/**
|
|
@@ -175,6 +230,15 @@
|
|
|
175
230
|
{
|
|
176
231
|
[_linkRanges removeAllObjects];
|
|
177
232
|
[_linkURLs removeAllObjects];
|
|
233
|
+
[_headingRanges removeAllObjects];
|
|
234
|
+
[_headingLevels removeAllObjects];
|
|
235
|
+
[_imageRanges removeAllObjects];
|
|
236
|
+
[_imageAltTexts removeAllObjects];
|
|
237
|
+
[_imageURLs removeAllObjects];
|
|
238
|
+
[_listItemRanges removeAllObjects];
|
|
239
|
+
[_listItemPositions removeAllObjects];
|
|
240
|
+
[_listItemDepths removeAllObjects];
|
|
241
|
+
[_listItemOrdered removeAllObjects];
|
|
178
242
|
[self clearBlockStyle];
|
|
179
243
|
|
|
180
244
|
_blockquoteDepth = 0;
|
|
@@ -10,10 +10,12 @@
|
|
|
10
10
|
#import "ListRenderer.h"
|
|
11
11
|
#import "ParagraphRenderer.h"
|
|
12
12
|
#import "RenderContext.h"
|
|
13
|
+
#import "StrikethroughRenderer.h"
|
|
13
14
|
#import "StrongRenderer.h"
|
|
14
15
|
#import "StyleConfig.h"
|
|
15
16
|
#import "TextRenderer.h"
|
|
16
17
|
#import "ThematicBreakRenderer.h"
|
|
18
|
+
#import "UnderlineRenderer.h"
|
|
17
19
|
|
|
18
20
|
@implementation RendererFactory {
|
|
19
21
|
StyleConfig *_config;
|
|
@@ -64,6 +66,10 @@
|
|
|
64
66
|
return [[StrongRenderer alloc] initWithRendererFactory:self config:_config];
|
|
65
67
|
case MarkdownNodeTypeEmphasis:
|
|
66
68
|
return [[EmphasisRenderer alloc] initWithRendererFactory:self config:_config];
|
|
69
|
+
case MarkdownNodeTypeStrikethrough:
|
|
70
|
+
return [[StrikethroughRenderer alloc] initWithRendererFactory:self config:_config];
|
|
71
|
+
case MarkdownNodeTypeUnderline:
|
|
72
|
+
return [[UnderlineRenderer alloc] initWithRendererFactory:self config:_config];
|
|
67
73
|
case MarkdownNodeTypeParagraph:
|
|
68
74
|
return [[ParagraphRenderer alloc] initWithRendererFactory:self config:_config];
|
|
69
75
|
case MarkdownNodeTypeLink:
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#import "StrikethroughRenderer.h"
|
|
2
|
+
#import "MarkdownASTNode.h"
|
|
3
|
+
#import "RenderContext.h"
|
|
4
|
+
#import "RendererFactory.h"
|
|
5
|
+
#import "StyleConfig.h"
|
|
6
|
+
|
|
7
|
+
@implementation StrikethroughRenderer {
|
|
8
|
+
RendererFactory *_rendererFactory;
|
|
9
|
+
StyleConfig *_config;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
- (instancetype)initWithRendererFactory:(id)rendererFactory config:(id)config
|
|
13
|
+
{
|
|
14
|
+
if (self = [super init]) {
|
|
15
|
+
_rendererFactory = rendererFactory;
|
|
16
|
+
_config = (StyleConfig *)config;
|
|
17
|
+
}
|
|
18
|
+
return self;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#pragma mark - Rendering
|
|
22
|
+
|
|
23
|
+
- (void)renderNode:(MarkdownASTNode *)node into:(NSMutableAttributedString *)output context:(RenderContext *)context
|
|
24
|
+
{
|
|
25
|
+
NSUInteger start = output.length;
|
|
26
|
+
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
27
|
+
|
|
28
|
+
NSRange range = NSMakeRange(start, output.length - start);
|
|
29
|
+
if (range.length == 0)
|
|
30
|
+
return;
|
|
31
|
+
|
|
32
|
+
// Apply strikethrough style
|
|
33
|
+
[output addAttribute:NSStrikethroughStyleAttributeName value:@(NSUnderlineStyleSingle) range:range];
|
|
34
|
+
|
|
35
|
+
// Apply strikethrough line color (not text color)
|
|
36
|
+
UIColor *strikethroughColor = [_config strikethroughColor];
|
|
37
|
+
[output addAttribute:NSStrikethroughColorAttributeName value:strikethroughColor range:range];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#import "UnderlineRenderer.h"
|
|
2
|
+
#import "MarkdownASTNode.h"
|
|
3
|
+
#import "RenderContext.h"
|
|
4
|
+
#import "RendererFactory.h"
|
|
5
|
+
#import "StyleConfig.h"
|
|
6
|
+
|
|
7
|
+
@implementation UnderlineRenderer {
|
|
8
|
+
RendererFactory *_rendererFactory;
|
|
9
|
+
StyleConfig *_config;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
- (instancetype)initWithRendererFactory:(id)rendererFactory config:(id)config
|
|
13
|
+
{
|
|
14
|
+
if (self = [super init]) {
|
|
15
|
+
_rendererFactory = rendererFactory;
|
|
16
|
+
_config = (StyleConfig *)config;
|
|
17
|
+
}
|
|
18
|
+
return self;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#pragma mark - Rendering
|
|
22
|
+
|
|
23
|
+
- (void)renderNode:(MarkdownASTNode *)node into:(NSMutableAttributedString *)output context:(RenderContext *)context
|
|
24
|
+
{
|
|
25
|
+
NSUInteger start = output.length;
|
|
26
|
+
[_rendererFactory renderChildrenOfNode:node into:output context:context];
|
|
27
|
+
|
|
28
|
+
NSRange range = NSMakeRange(start, output.length - start);
|
|
29
|
+
if (range.length == 0)
|
|
30
|
+
return;
|
|
31
|
+
|
|
32
|
+
[output addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:range];
|
|
33
|
+
|
|
34
|
+
UIColor *underlineColor = [_config underlineColor];
|
|
35
|
+
|
|
36
|
+
[output addAttribute:NSUnderlineColorAttributeName value:underlineColor range:range];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@end
|
package/ios/styles/StyleConfig.h
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
@interface StyleConfig : NSObject <NSCopying>
|
|
5
5
|
- (instancetype)init;
|
|
6
|
+
- (CGFloat)fontScaleMultiplier;
|
|
7
|
+
- (void)setFontScaleMultiplier:(CGFloat)newValue;
|
|
8
|
+
- (CGFloat)maxFontSizeMultiplier;
|
|
9
|
+
- (void)setMaxFontSizeMultiplier:(CGFloat)newValue;
|
|
6
10
|
// Primary font properties
|
|
7
11
|
- (UIColor *)primaryColor;
|
|
8
12
|
- (void)setPrimaryColor:(UIColor *)newValue;
|
|
@@ -22,10 +26,14 @@
|
|
|
22
26
|
- (void)setParagraphFontWeight:(NSString *)newValue;
|
|
23
27
|
- (UIColor *)paragraphColor;
|
|
24
28
|
- (void)setParagraphColor:(UIColor *)newValue;
|
|
29
|
+
- (CGFloat)paragraphMarginTop;
|
|
30
|
+
- (void)setParagraphMarginTop:(CGFloat)newValue;
|
|
25
31
|
- (CGFloat)paragraphMarginBottom;
|
|
26
32
|
- (void)setParagraphMarginBottom:(CGFloat)newValue;
|
|
27
33
|
- (CGFloat)paragraphLineHeight;
|
|
28
34
|
- (void)setParagraphLineHeight:(CGFloat)newValue;
|
|
35
|
+
- (NSTextAlignment)paragraphTextAlign;
|
|
36
|
+
- (void)setParagraphTextAlign:(NSTextAlignment)newValue;
|
|
29
37
|
- (UIFont *)paragraphFont;
|
|
30
38
|
// H1 properties
|
|
31
39
|
- (CGFloat)h1FontSize;
|
|
@@ -36,10 +44,14 @@
|
|
|
36
44
|
- (void)setH1FontWeight:(NSString *)newValue;
|
|
37
45
|
- (UIColor *)h1Color;
|
|
38
46
|
- (void)setH1Color:(UIColor *)newValue;
|
|
47
|
+
- (CGFloat)h1MarginTop;
|
|
48
|
+
- (void)setH1MarginTop:(CGFloat)newValue;
|
|
39
49
|
- (CGFloat)h1MarginBottom;
|
|
40
50
|
- (void)setH1MarginBottom:(CGFloat)newValue;
|
|
41
51
|
- (CGFloat)h1LineHeight;
|
|
42
52
|
- (void)setH1LineHeight:(CGFloat)newValue;
|
|
53
|
+
- (NSTextAlignment)h1TextAlign;
|
|
54
|
+
- (void)setH1TextAlign:(NSTextAlignment)newValue;
|
|
43
55
|
- (UIFont *)h1Font;
|
|
44
56
|
// H2 properties
|
|
45
57
|
- (CGFloat)h2FontSize;
|
|
@@ -50,10 +62,14 @@
|
|
|
50
62
|
- (void)setH2FontWeight:(NSString *)newValue;
|
|
51
63
|
- (UIColor *)h2Color;
|
|
52
64
|
- (void)setH2Color:(UIColor *)newValue;
|
|
65
|
+
- (CGFloat)h2MarginTop;
|
|
66
|
+
- (void)setH2MarginTop:(CGFloat)newValue;
|
|
53
67
|
- (CGFloat)h2MarginBottom;
|
|
54
68
|
- (void)setH2MarginBottom:(CGFloat)newValue;
|
|
55
69
|
- (CGFloat)h2LineHeight;
|
|
56
70
|
- (void)setH2LineHeight:(CGFloat)newValue;
|
|
71
|
+
- (NSTextAlignment)h2TextAlign;
|
|
72
|
+
- (void)setH2TextAlign:(NSTextAlignment)newValue;
|
|
57
73
|
- (UIFont *)h2Font;
|
|
58
74
|
// H3 properties
|
|
59
75
|
- (CGFloat)h3FontSize;
|
|
@@ -64,10 +80,14 @@
|
|
|
64
80
|
- (void)setH3FontWeight:(NSString *)newValue;
|
|
65
81
|
- (UIColor *)h3Color;
|
|
66
82
|
- (void)setH3Color:(UIColor *)newValue;
|
|
83
|
+
- (CGFloat)h3MarginTop;
|
|
84
|
+
- (void)setH3MarginTop:(CGFloat)newValue;
|
|
67
85
|
- (CGFloat)h3MarginBottom;
|
|
68
86
|
- (void)setH3MarginBottom:(CGFloat)newValue;
|
|
69
87
|
- (CGFloat)h3LineHeight;
|
|
70
88
|
- (void)setH3LineHeight:(CGFloat)newValue;
|
|
89
|
+
- (NSTextAlignment)h3TextAlign;
|
|
90
|
+
- (void)setH3TextAlign:(NSTextAlignment)newValue;
|
|
71
91
|
- (UIFont *)h3Font;
|
|
72
92
|
// H4 properties
|
|
73
93
|
- (CGFloat)h4FontSize;
|
|
@@ -78,10 +98,14 @@
|
|
|
78
98
|
- (void)setH4FontWeight:(NSString *)newValue;
|
|
79
99
|
- (UIColor *)h4Color;
|
|
80
100
|
- (void)setH4Color:(UIColor *)newValue;
|
|
101
|
+
- (CGFloat)h4MarginTop;
|
|
102
|
+
- (void)setH4MarginTop:(CGFloat)newValue;
|
|
81
103
|
- (CGFloat)h4MarginBottom;
|
|
82
104
|
- (void)setH4MarginBottom:(CGFloat)newValue;
|
|
83
105
|
- (CGFloat)h4LineHeight;
|
|
84
106
|
- (void)setH4LineHeight:(CGFloat)newValue;
|
|
107
|
+
- (NSTextAlignment)h4TextAlign;
|
|
108
|
+
- (void)setH4TextAlign:(NSTextAlignment)newValue;
|
|
85
109
|
- (UIFont *)h4Font;
|
|
86
110
|
// H5 properties
|
|
87
111
|
- (CGFloat)h5FontSize;
|
|
@@ -92,10 +116,14 @@
|
|
|
92
116
|
- (void)setH5FontWeight:(NSString *)newValue;
|
|
93
117
|
- (UIColor *)h5Color;
|
|
94
118
|
- (void)setH5Color:(UIColor *)newValue;
|
|
119
|
+
- (CGFloat)h5MarginTop;
|
|
120
|
+
- (void)setH5MarginTop:(CGFloat)newValue;
|
|
95
121
|
- (CGFloat)h5MarginBottom;
|
|
96
122
|
- (void)setH5MarginBottom:(CGFloat)newValue;
|
|
97
123
|
- (CGFloat)h5LineHeight;
|
|
98
124
|
- (void)setH5LineHeight:(CGFloat)newValue;
|
|
125
|
+
- (NSTextAlignment)h5TextAlign;
|
|
126
|
+
- (void)setH5TextAlign:(NSTextAlignment)newValue;
|
|
99
127
|
- (UIFont *)h5Font;
|
|
100
128
|
// H6 properties
|
|
101
129
|
- (CGFloat)h6FontSize;
|
|
@@ -106,10 +134,14 @@
|
|
|
106
134
|
- (void)setH6FontWeight:(NSString *)newValue;
|
|
107
135
|
- (UIColor *)h6Color;
|
|
108
136
|
- (void)setH6Color:(UIColor *)newValue;
|
|
137
|
+
- (CGFloat)h6MarginTop;
|
|
138
|
+
- (void)setH6MarginTop:(CGFloat)newValue;
|
|
109
139
|
- (CGFloat)h6MarginBottom;
|
|
110
140
|
- (void)setH6MarginBottom:(CGFloat)newValue;
|
|
111
141
|
- (CGFloat)h6LineHeight;
|
|
112
142
|
- (void)setH6LineHeight:(CGFloat)newValue;
|
|
143
|
+
- (NSTextAlignment)h6TextAlign;
|
|
144
|
+
- (void)setH6TextAlign:(NSTextAlignment)newValue;
|
|
113
145
|
- (UIFont *)h6Font;
|
|
114
146
|
// Link properties
|
|
115
147
|
- (UIColor *)linkColor;
|
|
@@ -122,6 +154,12 @@
|
|
|
122
154
|
// Emphasis properties
|
|
123
155
|
- (UIColor *)emphasisColor;
|
|
124
156
|
- (void)setEmphasisColor:(UIColor *)newValue;
|
|
157
|
+
// Strikethrough properties
|
|
158
|
+
- (UIColor *)strikethroughColor;
|
|
159
|
+
- (void)setStrikethroughColor:(UIColor *)newValue;
|
|
160
|
+
// Underline properties
|
|
161
|
+
- (UIColor *)underlineColor;
|
|
162
|
+
- (void)setUnderlineColor:(UIColor *)newValue;
|
|
125
163
|
// Code properties
|
|
126
164
|
- (UIColor *)codeColor;
|
|
127
165
|
- (void)setCodeColor:(UIColor *)newValue;
|
|
@@ -134,6 +172,8 @@
|
|
|
134
172
|
- (void)setImageHeight:(CGFloat)newValue;
|
|
135
173
|
- (CGFloat)imageBorderRadius;
|
|
136
174
|
- (void)setImageBorderRadius:(CGFloat)newValue;
|
|
175
|
+
- (CGFloat)imageMarginTop;
|
|
176
|
+
- (void)setImageMarginTop:(CGFloat)newValue;
|
|
137
177
|
- (CGFloat)imageMarginBottom;
|
|
138
178
|
- (void)setImageMarginBottom:(CGFloat)newValue;
|
|
139
179
|
// Inline image properties
|
|
@@ -148,6 +188,8 @@
|
|
|
148
188
|
- (void)setBlockquoteFontWeight:(NSString *)newValue;
|
|
149
189
|
- (UIColor *)blockquoteColor;
|
|
150
190
|
- (void)setBlockquoteColor:(UIColor *)newValue;
|
|
191
|
+
- (CGFloat)blockquoteMarginTop;
|
|
192
|
+
- (void)setBlockquoteMarginTop:(CGFloat)newValue;
|
|
151
193
|
- (CGFloat)blockquoteMarginBottom;
|
|
152
194
|
- (void)setBlockquoteMarginBottom:(CGFloat)newValue;
|
|
153
195
|
- (CGFloat)blockquoteLineHeight;
|
|
@@ -170,6 +212,8 @@
|
|
|
170
212
|
- (void)setListStyleFontWeight:(NSString *)newValue;
|
|
171
213
|
- (UIColor *)listStyleColor;
|
|
172
214
|
- (void)setListStyleColor:(UIColor *)newValue;
|
|
215
|
+
- (CGFloat)listStyleMarginTop;
|
|
216
|
+
- (void)setListStyleMarginTop:(CGFloat)newValue;
|
|
173
217
|
- (CGFloat)listStyleMarginBottom;
|
|
174
218
|
- (void)setListStyleMarginBottom:(CGFloat)newValue;
|
|
175
219
|
- (CGFloat)listStyleLineHeight;
|
|
@@ -200,6 +244,8 @@
|
|
|
200
244
|
- (void)setCodeBlockFontWeight:(NSString *)newValue;
|
|
201
245
|
- (UIColor *)codeBlockColor;
|
|
202
246
|
- (void)setCodeBlockColor:(UIColor *)newValue;
|
|
247
|
+
- (CGFloat)codeBlockMarginTop;
|
|
248
|
+
- (void)setCodeBlockMarginTop:(CGFloat)newValue;
|
|
203
249
|
- (CGFloat)codeBlockMarginBottom;
|
|
204
250
|
- (void)setCodeBlockMarginBottom:(CGFloat)newValue;
|
|
205
251
|
- (CGFloat)codeBlockLineHeight;
|