react-native-enriched-markdown-scaffold 0.7.4-scaffold.1 → 0.7.4-scaffold.10
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/android/build.gradle +5 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerDelegate.java +3 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +1 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +5 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +49 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +6 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputManager.kt +20 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +55 -9
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockSyntaxSentinel.kt +69 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +71 -12
- package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputLayoutManager.kt +30 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +7 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +3 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/HeadingSpan.kt +8 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/LineHeightSpan.kt +27 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/InlineMathStyle.kt +5 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/MathFontWeight.kt +25 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/MathStyle.kt +12 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +7 -7
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/SpannableExtensions.kt +12 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +1 -1
- package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +2 -0
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathInlinePlaceholderSpan.kt +7 -3
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathInlineSpan.kt +8 -5
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathTypeface.kt +30 -0
- package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +3 -1
- package/docs/API_REFERENCE.md +9 -0
- package/docs/INPUT.md +48 -0
- package/docs/LATEX_MATH.md +62 -0
- package/docs/STYLES.md +3 -0
- package/ios/EnrichedMarkdown.mm +44 -12
- package/ios/EnrichedMarkdownText.mm +47 -11
- package/ios/attachments/ENRMMathInlineAttachment+macOS.m +5 -1
- package/ios/attachments/ENRMMathInlineAttachment.h +3 -0
- package/ios/attachments/ENRMMathInlineAttachment.m +2 -1
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +5 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +49 -0
- package/ios/input/ENRMBlockSyntaxSentinel.h +25 -0
- package/ios/input/ENRMBlockSyntaxSentinel.mm +80 -0
- package/ios/input/ENRMInputFormatter.h +4 -0
- package/ios/input/ENRMInputFormatter.mm +2 -0
- package/ios/input/ENRMInputParser.h +5 -0
- package/ios/input/ENRMInputParser.mm +79 -6
- package/ios/input/EnrichedMarkdownTextInput.mm +55 -22
- package/ios/input/InputStylePropsUtils.h +13 -0
- package/ios/internals/MeasurementCache.h +1 -0
- package/ios/math/ENRMRaTeXBridge.swift +52 -3
- package/ios/parser/ENRMMarkdownParser.h +8 -0
- package/ios/parser/ENRMMarkdownParser.mm +11 -0
- package/ios/renderer/ENRMMathInlineRenderer.m +3 -0
- package/ios/renderer/ListItemRenderer.m +8 -5
- package/ios/styles/StyleConfig.h +6 -0
- package/ios/styles/StyleConfig.mm +36 -0
- package/ios/utils/ENRMMathFontWeight.h +18 -0
- package/ios/utils/StylePropsUtils.h +21 -0
- package/ios/views/ENRMMathContainerView.m +3 -1
- package/lib/module/EnrichedMarkdownNativeComponent.ts +3 -0
- package/lib/module/EnrichedMarkdownTextInput.js +2 -0
- package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
- package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +12 -0
- package/lib/module/EnrichedMarkdownTextNativeComponent.ts +3 -0
- package/lib/module/normalizeMarkdownStyle.js +5 -2
- package/lib/module/normalizeMarkdownStyle.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.web.js +5 -2
- package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
- package/lib/module/normalizeMarkdownTextInputStyle.js +7 -3
- package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
- package/lib/module/web/globalStyles.js +8 -1
- package/lib/module/web/globalStyles.js.map +1 -1
- package/lib/module/web/styles.js +3 -1
- package/lib/module/web/styles.js.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +3 -0
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +3 -1
- package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +12 -0
- package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +3 -0
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +1 -0
- package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownStyle.d.ts +32 -0
- package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +3 -0
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
- package/lib/typescript/src/web/styles.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/EnrichedMarkdownNativeComponent.ts +3 -0
- package/src/EnrichedMarkdownTextInput.tsx +4 -0
- package/src/EnrichedMarkdownTextInputNativeComponent.ts +12 -0
- package/src/EnrichedMarkdownTextNativeComponent.ts +3 -0
- package/src/normalizeMarkdownStyle.ts +6 -1
- package/src/normalizeMarkdownStyle.web.ts +6 -1
- package/src/normalizeMarkdownTextInputStyle.ts +5 -0
- package/src/types/MarkdownStyle.ts +32 -0
- package/src/types/MarkdownStyleInternal.ts +3 -0
- package/src/web/globalStyles.ts +7 -0
- package/src/web/styles.ts +5 -1
package/ios/EnrichedMarkdown.mm
CHANGED
|
@@ -123,6 +123,45 @@ static char kENRMSegmentFadeAnimatorKey;
|
|
|
123
123
|
return concreteComponentDescriptorProvider<EnrichedMarkdownComponentDescriptor>();
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
/// Clears every piece of state that `updateProps` derives from props, back to the
|
|
127
|
+
/// values the default-constructed `EnrichedMarkdownProps` describes.
|
|
128
|
+
///
|
|
129
|
+
/// `updateProps` applies most props as a per-field diff against `_props`, so this
|
|
130
|
+
/// state is only correct while it stays in phase with the `_props` baseline it was
|
|
131
|
+
/// diffed from. `prepareForRecycle` resets `_props`, so it must reset this too —
|
|
132
|
+
/// otherwise every field the next consumer leaves at its default silently inherits
|
|
133
|
+
/// the previous consumer's value. Called from `initWithFrame:` as well, so the two
|
|
134
|
+
/// baselines cannot drift apart.
|
|
135
|
+
///
|
|
136
|
+
/// Requires `_fontScaleObserver` to already exist.
|
|
137
|
+
- (void)resetPropDerivedState
|
|
138
|
+
{
|
|
139
|
+
// Discarded rather than cleared field-by-field: the style diff can only clear a
|
|
140
|
+
// field when new and old differ, which never holds against a reset baseline.
|
|
141
|
+
_config = nil;
|
|
142
|
+
|
|
143
|
+
_md4cFlags = [ENRMMd4cFlags propsDefaultFlags];
|
|
144
|
+
_maxFontSizeMultiplier = 0;
|
|
145
|
+
_allowTrailingMargin = NO;
|
|
146
|
+
_fontScaleObserver.allowFontScaling = YES;
|
|
147
|
+
_streamingAnimation = NO;
|
|
148
|
+
_tableStreamingMode = ENRMTableStreamingModeProgressive;
|
|
149
|
+
_spoilerOverlay = ENRMSpoilerOverlayParticles;
|
|
150
|
+
_lineBreakStrategy = NSLineBreakStrategyNone;
|
|
151
|
+
_writingDirectionMode = ENRMWritingDirectionModeFirstStrong;
|
|
152
|
+
_contextMenuItemTexts = nil;
|
|
153
|
+
_contextMenuItemIcons = nil;
|
|
154
|
+
_accessibilityLabels = nil;
|
|
155
|
+
|
|
156
|
+
// Written only once a render completes, so stale until the next one lands.
|
|
157
|
+
_renderedStyleFingerprint = 0;
|
|
158
|
+
_pendingStyleFingerprint = 0;
|
|
159
|
+
|
|
160
|
+
_dirtyFlags = ENRMDirtyNone;
|
|
161
|
+
_heightUpdateCounter = 0;
|
|
162
|
+
_state = nullptr;
|
|
163
|
+
}
|
|
164
|
+
|
|
126
165
|
- (instancetype)initWithFrame:(CGRect)frame
|
|
127
166
|
{
|
|
128
167
|
if (self = [super initWithFrame:frame]) {
|
|
@@ -131,28 +170,22 @@ static char kENRMSegmentFadeAnimatorKey;
|
|
|
131
170
|
|
|
132
171
|
self.backgroundColor = [RCTUIColor clearColor];
|
|
133
172
|
_parser = [[ENRMMarkdownParser alloc] init];
|
|
134
|
-
_md4cFlags = [ENRMMd4cFlags defaultFlags];
|
|
135
173
|
_segmentViews = [NSMutableArray array];
|
|
136
174
|
_segmentSignatures = [NSMutableArray array];
|
|
137
|
-
_dirtyFlags = ENRMDirtyNone;
|
|
138
175
|
[self configureSegmentViewRegistry];
|
|
139
176
|
|
|
140
177
|
_renderCoordinator =
|
|
141
178
|
[[ENRMAsyncRenderCoordinator alloc] initWithQueueLabel:"com.swmansion.enriched.markdown.container.render"];
|
|
142
179
|
|
|
143
|
-
_maxFontSizeMultiplier = 0;
|
|
144
|
-
_allowTrailingMargin = NO;
|
|
145
180
|
_selectable = YES;
|
|
146
181
|
_enableLinkPreview = YES;
|
|
147
|
-
_streamingAnimation = NO;
|
|
148
|
-
_tableStreamingMode = ENRMTableStreamingModeProgressive;
|
|
149
182
|
_selectionMenuConfig = (ENRMSelectionMenuConfig){.copyAsMarkdown = YES, .copyImageURL = YES};
|
|
150
|
-
_lineBreakStrategy = NSLineBreakStrategyNone;
|
|
151
|
-
_writingDirectionMode = ENRMWritingDirectionModeFirstStrong;
|
|
152
183
|
_resolvedLayoutDirection =
|
|
153
184
|
[[RCTI18nUtil sharedInstance] isRTL] ? NSWritingDirectionRightToLeft : NSWritingDirectionLeftToRight;
|
|
154
185
|
|
|
155
186
|
_fontScaleObserver = [[FontScaleObserver alloc] init];
|
|
187
|
+
[self resetPropDerivedState];
|
|
188
|
+
|
|
156
189
|
__weak EnrichedMarkdown *weakSelf = self;
|
|
157
190
|
_fontScaleObserver.onChange = ^{
|
|
158
191
|
EnrichedMarkdown *strongSelf = weakSelf;
|
|
@@ -624,7 +657,7 @@ static char kENRMSegmentFadeAnimatorKey;
|
|
|
624
657
|
selectionEnd:selectionEnd];
|
|
625
658
|
});
|
|
626
659
|
return buildEditMenuForSelection(textView.textStorage, textView.selectedRange, segmentMarkdown, strongSelf->_config,
|
|
627
|
-
@[ baseMenu ], customItems, strongSelf
|
|
660
|
+
@[ baseMenu ], customItems, strongSelf->_selectionMenuConfig);
|
|
628
661
|
}];
|
|
629
662
|
#endif
|
|
630
663
|
|
|
@@ -949,9 +982,8 @@ static char kENRMSegmentFadeAnimatorKey;
|
|
|
949
982
|
|
|
950
983
|
_cachedMarkdown = nil;
|
|
951
984
|
_renderedMarkdown = nil;
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
_dirtyFlags = ENRMDirtyNone;
|
|
985
|
+
|
|
986
|
+
[self resetPropDerivedState];
|
|
955
987
|
|
|
956
988
|
[super prepareForRecycle];
|
|
957
989
|
}
|
|
@@ -46,6 +46,7 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
@interface EnrichedMarkdownText () <RCTEnrichedMarkdownTextViewProtocol, UITextViewDelegate>
|
|
49
|
+
- (void)resetPropDerivedState;
|
|
49
50
|
- (void)setupTextView;
|
|
50
51
|
- (void)renderMarkdownContent:(NSString *)markdownString;
|
|
51
52
|
- (void)applyRenderedText:(NSMutableAttributedString *)attributedText;
|
|
@@ -177,6 +178,46 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
177
178
|
ENRMRequestHeightUpdate<EnrichedMarkdownTextState>(_state, _heightUpdateCounter, self);
|
|
178
179
|
}
|
|
179
180
|
|
|
181
|
+
/// Clears every piece of state that `updateProps` derives from props, back to the
|
|
182
|
+
/// values the default-constructed `EnrichedMarkdownTextProps` describes.
|
|
183
|
+
///
|
|
184
|
+
/// `updateProps` applies most props as a per-field diff against `_props`, so this
|
|
185
|
+
/// state is only correct while it stays in phase with the `_props` baseline it was
|
|
186
|
+
/// diffed from. `prepareForRecycle` resets `_props`, so it must reset this too —
|
|
187
|
+
/// otherwise every field the next consumer leaves at its default silently inherits
|
|
188
|
+
/// the previous consumer's value. Called from `initWithFrame:` as well, so the two
|
|
189
|
+
/// baselines cannot drift apart.
|
|
190
|
+
///
|
|
191
|
+
/// Requires `_fontScaleObserver` to already exist.
|
|
192
|
+
- (void)resetPropDerivedState
|
|
193
|
+
{
|
|
194
|
+
// Discarded rather than cleared field-by-field: the style diff can only clear a
|
|
195
|
+
// field when new and old differ, which never holds against a reset baseline.
|
|
196
|
+
_config = nil;
|
|
197
|
+
_spoilerManager = nil;
|
|
198
|
+
|
|
199
|
+
_md4cFlags = [ENRMMd4cFlags propsDefaultFlags];
|
|
200
|
+
_maxFontSizeMultiplier = 0;
|
|
201
|
+
_allowTrailingMargin = NO;
|
|
202
|
+
_fontScaleObserver.allowFontScaling = YES;
|
|
203
|
+
_streamingAnimation = NO;
|
|
204
|
+
_lineBreakStrategy = NSLineBreakStrategyNone;
|
|
205
|
+
_writingDirectionMode = ENRMWritingDirectionModeFirstStrong;
|
|
206
|
+
_contextMenuItemTexts = nil;
|
|
207
|
+
_contextMenuItemIcons = nil;
|
|
208
|
+
_accessibilityLabels = nil;
|
|
209
|
+
|
|
210
|
+
// Written only once a render completes, so stale until the next one lands.
|
|
211
|
+
_renderedStyleFingerprint = 0;
|
|
212
|
+
_pendingStyleFingerprint = 0;
|
|
213
|
+
_lastElementMarginBottom = 0;
|
|
214
|
+
|
|
215
|
+
_dirtyFlags = ENRMDirtyNone;
|
|
216
|
+
_forceHeightUpdateOnNextRender = NO;
|
|
217
|
+
_heightUpdateCounter = 0;
|
|
218
|
+
_state = nullptr;
|
|
219
|
+
}
|
|
220
|
+
|
|
180
221
|
- (instancetype)initWithFrame:(CGRect)frame
|
|
181
222
|
{
|
|
182
223
|
if (self = [super initWithFrame:frame]) {
|
|
@@ -185,23 +226,18 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
185
226
|
|
|
186
227
|
self.backgroundColor = [RCTUIColor clearColor];
|
|
187
228
|
_parser = [[ENRMMarkdownParser alloc] init];
|
|
188
|
-
_md4cFlags = [ENRMMd4cFlags defaultFlags];
|
|
189
229
|
|
|
190
230
|
_renderCoordinator =
|
|
191
231
|
[[ENRMAsyncRenderCoordinator alloc] initWithQueueLabel:"com.swmansion.enriched.markdown.render"];
|
|
192
232
|
|
|
193
|
-
_maxFontSizeMultiplier = 0;
|
|
194
|
-
_allowTrailingMargin = NO;
|
|
195
233
|
_enableLinkPreview = YES;
|
|
196
|
-
_forceHeightUpdateOnNextRender = NO;
|
|
197
234
|
_selectionMenuConfig = (ENRMSelectionMenuConfig){.copyAsMarkdown = YES, .copyImageURL = YES};
|
|
198
|
-
_lineBreakStrategy = NSLineBreakStrategyNone;
|
|
199
|
-
_writingDirectionMode = ENRMWritingDirectionModeFirstStrong;
|
|
200
235
|
_resolvedLayoutDirection =
|
|
201
236
|
[[RCTI18nUtil sharedInstance] isRTL] ? NSWritingDirectionRightToLeft : NSWritingDirectionLeftToRight;
|
|
202
|
-
_dirtyFlags = ENRMDirtyNone;
|
|
203
237
|
|
|
204
238
|
_fontScaleObserver = [[FontScaleObserver alloc] init];
|
|
239
|
+
[self resetPropDerivedState];
|
|
240
|
+
|
|
205
241
|
__weak EnrichedMarkdownText *weakSelf = self;
|
|
206
242
|
_fontScaleObserver.onChange = ^{
|
|
207
243
|
EnrichedMarkdownText *strongSelf = weakSelf;
|
|
@@ -253,8 +289,7 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
253
289
|
selectionEnd:selectionEnd];
|
|
254
290
|
});
|
|
255
291
|
return buildEditMenuForSelection(textView.textStorage, textView.selectedRange, strongSelf->_cachedMarkdown,
|
|
256
|
-
strongSelf->_config, @[ baseMenu ], customItems,
|
|
257
|
-
strongSelf -> _selectionMenuConfig);
|
|
292
|
+
strongSelf->_config, @[ baseMenu ], customItems, strongSelf->_selectionMenuConfig);
|
|
258
293
|
};
|
|
259
294
|
#endif
|
|
260
295
|
|
|
@@ -636,14 +671,15 @@ typedef NS_OPTIONS(NSUInteger, ENRMDirtyFlags) {
|
|
|
636
671
|
[_fadeAnimator cancel];
|
|
637
672
|
_fadeAnimator = nil;
|
|
638
673
|
_previousTextLength = 0;
|
|
639
|
-
_streamingAnimation = NO;
|
|
640
|
-
_forceHeightUpdateOnNextRender = NO;
|
|
641
674
|
_cachedMarkdown = nil;
|
|
642
675
|
_renderedMarkdown = nil;
|
|
643
676
|
_accessibilityElements = nil;
|
|
644
677
|
_accessibilityInfo = nil;
|
|
645
678
|
_accessibilityNeedsRebuild = NO;
|
|
646
679
|
[_spoilerManager removeAllOverlays];
|
|
680
|
+
|
|
681
|
+
[self resetPropDerivedState];
|
|
682
|
+
|
|
647
683
|
if (_textView != nil) {
|
|
648
684
|
ENRMSetAttributedText(_textView, [[NSAttributedString alloc] initWithString:@""]);
|
|
649
685
|
_textView.hidden = YES;
|
|
@@ -25,7 +25,11 @@
|
|
|
25
25
|
- (void)renderForMacOS
|
|
26
26
|
{
|
|
27
27
|
RCTUIColor *color = self.mathTextColor ?: [RCTUIColor blackColor];
|
|
28
|
-
ENRMRaTeXRenderResult *result = [ENRMRaTeXBridge parse:self.latex
|
|
28
|
+
ENRMRaTeXRenderResult *result = [ENRMRaTeXBridge parse:self.latex
|
|
29
|
+
displayMode:NO
|
|
30
|
+
fontSize:self.fontSize
|
|
31
|
+
color:color
|
|
32
|
+
bold:self.bold];
|
|
29
33
|
if (!result)
|
|
30
34
|
return;
|
|
31
35
|
|
|
@@ -9,6 +9,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
9
9
|
@property (nonatomic, assign) CGFloat fontSize;
|
|
10
10
|
@property (nonatomic, strong, nullable) RCTUIColor *mathTextColor;
|
|
11
11
|
|
|
12
|
+
/// Typeset the glyphs at bold weight (synthetic — see ENRMRaTeXBridge).
|
|
13
|
+
@property (nonatomic, assign) BOOL bold;
|
|
14
|
+
|
|
12
15
|
/// YES if block math (`$$...$$`), NO for inline (`$...$`).
|
|
13
16
|
@property (nonatomic, assign) BOOL displayMode;
|
|
14
17
|
|
|
@@ -144,6 +144,7 @@ EnrichedMarkdownTextInputProps::EnrichedMarkdownTextInputProps(
|
|
|
144
144
|
editable(convertRawProp(context, rawProps, "editable", sourceProps.editable, {false})),
|
|
145
145
|
autoFocus(convertRawProp(context, rawProps, "autoFocus", sourceProps.autoFocus, {false})),
|
|
146
146
|
scrollEnabled(convertRawProp(context, rawProps, "scrollEnabled", sourceProps.scrollEnabled, {false})),
|
|
147
|
+
blockSyntax(convertRawProp(context, rawProps, "blockSyntax", sourceProps.blockSyntax, {false})),
|
|
147
148
|
autoCapitalize(convertRawProp(context, rawProps, "autoCapitalize", sourceProps.autoCapitalize, {})),
|
|
148
149
|
multiline(convertRawProp(context, rawProps, "multiline", sourceProps.multiline, {false})),
|
|
149
150
|
cursorColor(convertRawProp(context, rawProps, "cursorColor", sourceProps.cursorColor, {})),
|
|
@@ -202,6 +203,10 @@ folly::dynamic EnrichedMarkdownTextInputProps::getDiffProps(
|
|
|
202
203
|
result["scrollEnabled"] = scrollEnabled;
|
|
203
204
|
}
|
|
204
205
|
|
|
206
|
+
if (blockSyntax != oldProps->blockSyntax) {
|
|
207
|
+
result["blockSyntax"] = blockSyntax;
|
|
208
|
+
}
|
|
209
|
+
|
|
205
210
|
if (autoCapitalize != oldProps->autoCapitalize) {
|
|
206
211
|
result["autoCapitalize"] = autoCapitalize;
|
|
207
212
|
}
|
|
@@ -1534,6 +1534,7 @@ struct EnrichedMarkdownMarkdownStyleMathStruct {
|
|
|
1534
1534
|
Float marginTop{0.0};
|
|
1535
1535
|
Float marginBottom{0.0};
|
|
1536
1536
|
std::string textAlign{};
|
|
1537
|
+
std::string fontWeight{};
|
|
1537
1538
|
|
|
1538
1539
|
|
|
1539
1540
|
#ifdef RN_SERIALIZABLE_STATE
|
|
@@ -1548,6 +1549,7 @@ struct EnrichedMarkdownMarkdownStyleMathStruct {
|
|
|
1548
1549
|
result["marginTop"] = marginTop;
|
|
1549
1550
|
result["marginBottom"] = marginBottom;
|
|
1550
1551
|
result["textAlign"] = textAlign;
|
|
1552
|
+
result["fontWeight"] = fontWeight;
|
|
1551
1553
|
return result;
|
|
1552
1554
|
}
|
|
1553
1555
|
#endif
|
|
@@ -1584,6 +1586,10 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu
|
|
|
1584
1586
|
if (tmp_textAlign != map.end()) {
|
|
1585
1587
|
fromRawValue(context, tmp_textAlign->second, result.textAlign);
|
|
1586
1588
|
}
|
|
1589
|
+
auto tmp_fontWeight = map.find("fontWeight");
|
|
1590
|
+
if (tmp_fontWeight != map.end()) {
|
|
1591
|
+
fromRawValue(context, tmp_fontWeight->second, result.fontWeight);
|
|
1592
|
+
}
|
|
1587
1593
|
}
|
|
1588
1594
|
|
|
1589
1595
|
static inline std::string toString(const EnrichedMarkdownMarkdownStyleMathStruct &value) {
|
|
@@ -1598,6 +1604,8 @@ static inline folly::dynamic toDynamic(const EnrichedMarkdownMarkdownStyleMathSt
|
|
|
1598
1604
|
|
|
1599
1605
|
struct EnrichedMarkdownMarkdownStyleInlineMathStruct {
|
|
1600
1606
|
SharedColor color{};
|
|
1607
|
+
Float paddingVertical{0.0};
|
|
1608
|
+
std::string fontWeight{};
|
|
1601
1609
|
|
|
1602
1610
|
|
|
1603
1611
|
#ifdef RN_SERIALIZABLE_STATE
|
|
@@ -1606,6 +1614,8 @@ struct EnrichedMarkdownMarkdownStyleInlineMathStruct {
|
|
|
1606
1614
|
folly::dynamic toDynamic() const {
|
|
1607
1615
|
folly::dynamic result = folly::dynamic::object();
|
|
1608
1616
|
result["color"] = ::facebook::react::toDynamic(color);
|
|
1617
|
+
result["paddingVertical"] = paddingVertical;
|
|
1618
|
+
result["fontWeight"] = fontWeight;
|
|
1609
1619
|
return result;
|
|
1610
1620
|
}
|
|
1611
1621
|
#endif
|
|
@@ -1618,6 +1628,14 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu
|
|
|
1618
1628
|
if (tmp_color != map.end()) {
|
|
1619
1629
|
fromRawValue(context, tmp_color->second, result.color);
|
|
1620
1630
|
}
|
|
1631
|
+
auto tmp_paddingVertical = map.find("paddingVertical");
|
|
1632
|
+
if (tmp_paddingVertical != map.end()) {
|
|
1633
|
+
fromRawValue(context, tmp_paddingVertical->second, result.paddingVertical);
|
|
1634
|
+
}
|
|
1635
|
+
auto tmp_fontWeight = map.find("fontWeight");
|
|
1636
|
+
if (tmp_fontWeight != map.end()) {
|
|
1637
|
+
fromRawValue(context, tmp_fontWeight->second, result.fontWeight);
|
|
1638
|
+
}
|
|
1621
1639
|
}
|
|
1622
1640
|
|
|
1623
1641
|
static inline std::string toString(const EnrichedMarkdownMarkdownStyleInlineMathStruct &value) {
|
|
@@ -2804,6 +2822,7 @@ struct EnrichedMarkdownTextInputMarkdownStyleMathStruct {
|
|
|
2804
2822
|
Float paddingVertical{0.0};
|
|
2805
2823
|
SharedColor selectedBackgroundColor{};
|
|
2806
2824
|
SharedColor selectedBorderColor{};
|
|
2825
|
+
std::string fontWeight{};
|
|
2807
2826
|
|
|
2808
2827
|
|
|
2809
2828
|
#ifdef RN_SERIALIZABLE_STATE
|
|
@@ -2821,6 +2840,7 @@ struct EnrichedMarkdownTextInputMarkdownStyleMathStruct {
|
|
|
2821
2840
|
result["paddingVertical"] = paddingVertical;
|
|
2822
2841
|
result["selectedBackgroundColor"] = ::facebook::react::toDynamic(selectedBackgroundColor);
|
|
2823
2842
|
result["selectedBorderColor"] = ::facebook::react::toDynamic(selectedBorderColor);
|
|
2843
|
+
result["fontWeight"] = fontWeight;
|
|
2824
2844
|
return result;
|
|
2825
2845
|
}
|
|
2826
2846
|
#endif
|
|
@@ -2869,6 +2889,10 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu
|
|
|
2869
2889
|
if (tmp_selectedBorderColor != map.end()) {
|
|
2870
2890
|
fromRawValue(context, tmp_selectedBorderColor->second, result.selectedBorderColor);
|
|
2871
2891
|
}
|
|
2892
|
+
auto tmp_fontWeight = map.find("fontWeight");
|
|
2893
|
+
if (tmp_fontWeight != map.end()) {
|
|
2894
|
+
fromRawValue(context, tmp_fontWeight->second, result.fontWeight);
|
|
2895
|
+
}
|
|
2872
2896
|
}
|
|
2873
2897
|
|
|
2874
2898
|
static inline std::string toString(const EnrichedMarkdownTextInputMarkdownStyleMathStruct &value) {
|
|
@@ -2892,6 +2916,7 @@ struct EnrichedMarkdownTextInputMarkdownStyleMathBlockStruct {
|
|
|
2892
2916
|
Float paddingVertical{0.0};
|
|
2893
2917
|
SharedColor selectedBackgroundColor{};
|
|
2894
2918
|
SharedColor selectedBorderColor{};
|
|
2919
|
+
std::string fontWeight{};
|
|
2895
2920
|
Float marginTop{0.0};
|
|
2896
2921
|
Float marginBottom{0.0};
|
|
2897
2922
|
std::string alignment{};
|
|
@@ -2912,6 +2937,7 @@ struct EnrichedMarkdownTextInputMarkdownStyleMathBlockStruct {
|
|
|
2912
2937
|
result["paddingVertical"] = paddingVertical;
|
|
2913
2938
|
result["selectedBackgroundColor"] = ::facebook::react::toDynamic(selectedBackgroundColor);
|
|
2914
2939
|
result["selectedBorderColor"] = ::facebook::react::toDynamic(selectedBorderColor);
|
|
2940
|
+
result["fontWeight"] = fontWeight;
|
|
2915
2941
|
result["marginTop"] = marginTop;
|
|
2916
2942
|
result["marginBottom"] = marginBottom;
|
|
2917
2943
|
result["alignment"] = alignment;
|
|
@@ -2963,6 +2989,10 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu
|
|
|
2963
2989
|
if (tmp_selectedBorderColor != map.end()) {
|
|
2964
2990
|
fromRawValue(context, tmp_selectedBorderColor->second, result.selectedBorderColor);
|
|
2965
2991
|
}
|
|
2992
|
+
auto tmp_fontWeight = map.find("fontWeight");
|
|
2993
|
+
if (tmp_fontWeight != map.end()) {
|
|
2994
|
+
fromRawValue(context, tmp_fontWeight->second, result.fontWeight);
|
|
2995
|
+
}
|
|
2966
2996
|
auto tmp_marginTop = map.find("marginTop");
|
|
2967
2997
|
if (tmp_marginTop != map.end()) {
|
|
2968
2998
|
fromRawValue(context, tmp_marginTop->second, result.marginTop);
|
|
@@ -3329,6 +3359,7 @@ class EnrichedMarkdownTextInputProps final : public ViewProps {
|
|
|
3329
3359
|
bool editable{false};
|
|
3330
3360
|
bool autoFocus{false};
|
|
3331
3361
|
bool scrollEnabled{false};
|
|
3362
|
+
bool blockSyntax{false};
|
|
3332
3363
|
std::string autoCapitalize{};
|
|
3333
3364
|
bool multiline{false};
|
|
3334
3365
|
SharedColor cursorColor{};
|
|
@@ -4872,6 +4903,7 @@ struct EnrichedMarkdownTextMarkdownStyleMathStruct {
|
|
|
4872
4903
|
Float marginTop{0.0};
|
|
4873
4904
|
Float marginBottom{0.0};
|
|
4874
4905
|
std::string textAlign{};
|
|
4906
|
+
std::string fontWeight{};
|
|
4875
4907
|
|
|
4876
4908
|
|
|
4877
4909
|
#ifdef RN_SERIALIZABLE_STATE
|
|
@@ -4886,6 +4918,7 @@ struct EnrichedMarkdownTextMarkdownStyleMathStruct {
|
|
|
4886
4918
|
result["marginTop"] = marginTop;
|
|
4887
4919
|
result["marginBottom"] = marginBottom;
|
|
4888
4920
|
result["textAlign"] = textAlign;
|
|
4921
|
+
result["fontWeight"] = fontWeight;
|
|
4889
4922
|
return result;
|
|
4890
4923
|
}
|
|
4891
4924
|
#endif
|
|
@@ -4922,6 +4955,10 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu
|
|
|
4922
4955
|
if (tmp_textAlign != map.end()) {
|
|
4923
4956
|
fromRawValue(context, tmp_textAlign->second, result.textAlign);
|
|
4924
4957
|
}
|
|
4958
|
+
auto tmp_fontWeight = map.find("fontWeight");
|
|
4959
|
+
if (tmp_fontWeight != map.end()) {
|
|
4960
|
+
fromRawValue(context, tmp_fontWeight->second, result.fontWeight);
|
|
4961
|
+
}
|
|
4925
4962
|
}
|
|
4926
4963
|
|
|
4927
4964
|
static inline std::string toString(const EnrichedMarkdownTextMarkdownStyleMathStruct &value) {
|
|
@@ -4936,6 +4973,8 @@ static inline folly::dynamic toDynamic(const EnrichedMarkdownTextMarkdownStyleMa
|
|
|
4936
4973
|
|
|
4937
4974
|
struct EnrichedMarkdownTextMarkdownStyleInlineMathStruct {
|
|
4938
4975
|
SharedColor color{};
|
|
4976
|
+
Float paddingVertical{0.0};
|
|
4977
|
+
std::string fontWeight{};
|
|
4939
4978
|
|
|
4940
4979
|
|
|
4941
4980
|
#ifdef RN_SERIALIZABLE_STATE
|
|
@@ -4944,6 +4983,8 @@ struct EnrichedMarkdownTextMarkdownStyleInlineMathStruct {
|
|
|
4944
4983
|
folly::dynamic toDynamic() const {
|
|
4945
4984
|
folly::dynamic result = folly::dynamic::object();
|
|
4946
4985
|
result["color"] = ::facebook::react::toDynamic(color);
|
|
4986
|
+
result["paddingVertical"] = paddingVertical;
|
|
4987
|
+
result["fontWeight"] = fontWeight;
|
|
4947
4988
|
return result;
|
|
4948
4989
|
}
|
|
4949
4990
|
#endif
|
|
@@ -4956,6 +4997,14 @@ static inline void fromRawValue(const PropsParserContext& context, const RawValu
|
|
|
4956
4997
|
if (tmp_color != map.end()) {
|
|
4957
4998
|
fromRawValue(context, tmp_color->second, result.color);
|
|
4958
4999
|
}
|
|
5000
|
+
auto tmp_paddingVertical = map.find("paddingVertical");
|
|
5001
|
+
if (tmp_paddingVertical != map.end()) {
|
|
5002
|
+
fromRawValue(context, tmp_paddingVertical->second, result.paddingVertical);
|
|
5003
|
+
}
|
|
5004
|
+
auto tmp_fontWeight = map.find("fontWeight");
|
|
5005
|
+
if (tmp_fontWeight != map.end()) {
|
|
5006
|
+
fromRawValue(context, tmp_fontWeight->second, result.fontWeight);
|
|
5007
|
+
}
|
|
4959
5008
|
}
|
|
4960
5009
|
|
|
4961
5010
|
static inline std::string toString(const EnrichedMarkdownTextMarkdownStyleInlineMathStruct &value) {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#import <Foundation/Foundation.h>
|
|
4
|
+
|
|
5
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
6
|
+
|
|
7
|
+
/// Vertical tab. md4c treats it as ordinary whitespace, never as a line break.
|
|
8
|
+
extern const unichar ENRMBlockSyntaxSentinelChar;
|
|
9
|
+
|
|
10
|
+
/// Collapses `\r\n` / `\r` to `\n` and drops any `0x0B` already in the input.
|
|
11
|
+
/// Dropping is deliberate: a pre-existing `0x0B` would come back out of
|
|
12
|
+
/// `ENRMBlockSyntaxDecode` as a newline and silently corrupt the text.
|
|
13
|
+
NSString *ENRMBlockSyntaxCanonicalize(NSString *markdown);
|
|
14
|
+
|
|
15
|
+
/// Prepends one sentinel and replaces every `\n` with one. Grows the string by
|
|
16
|
+
/// exactly one character and one UTF-8 byte, which is what keeps the parser's
|
|
17
|
+
/// byte-to-UTF16 map valid and the offset correction a flat -1.
|
|
18
|
+
NSString *ENRMBlockSyntaxEncode(NSString *canonical);
|
|
19
|
+
|
|
20
|
+
/// Reverses `ENRMBlockSyntaxEncode`. Returns nil when the leading sentinel is
|
|
21
|
+
/// missing, so the caller can fall back instead of shifting offsets that no
|
|
22
|
+
/// longer hold.
|
|
23
|
+
NSString *_Nullable ENRMBlockSyntaxDecode(NSString *plainText);
|
|
24
|
+
|
|
25
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#import "ENRMBlockSyntaxSentinel.h"
|
|
2
|
+
|
|
3
|
+
#import <vector>
|
|
4
|
+
|
|
5
|
+
const unichar ENRMBlockSyntaxSentinelChar = 0x000B;
|
|
6
|
+
|
|
7
|
+
NSString *ENRMBlockSyntaxCanonicalize(NSString *markdown)
|
|
8
|
+
{
|
|
9
|
+
NSUInteger length = markdown.length;
|
|
10
|
+
if (length == 0) {
|
|
11
|
+
return @"";
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
std::vector<unichar> source(length);
|
|
15
|
+
[markdown getCharacters:source.data() range:NSMakeRange(0, length)];
|
|
16
|
+
|
|
17
|
+
std::vector<unichar> out;
|
|
18
|
+
out.reserve(length);
|
|
19
|
+
|
|
20
|
+
for (NSUInteger i = 0; i < length; i++) {
|
|
21
|
+
unichar c = source[i];
|
|
22
|
+
if (c == '\r') {
|
|
23
|
+
out.push_back('\n');
|
|
24
|
+
if (i + 1 < length && source[i + 1] == '\n') {
|
|
25
|
+
i++;
|
|
26
|
+
}
|
|
27
|
+
} else if (c != ENRMBlockSyntaxSentinelChar) {
|
|
28
|
+
out.push_back(c);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// `out.data()` on an empty vector may be null, which -stringWithCharacters: rejects.
|
|
33
|
+
if (out.empty()) {
|
|
34
|
+
return @"";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return [NSString stringWithCharacters:out.data() length:out.size()];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
NSString *ENRMBlockSyntaxEncode(NSString *canonical)
|
|
41
|
+
{
|
|
42
|
+
NSUInteger length = canonical.length;
|
|
43
|
+
|
|
44
|
+
std::vector<unichar> out;
|
|
45
|
+
out.reserve(length + 1);
|
|
46
|
+
out.push_back(ENRMBlockSyntaxSentinelChar);
|
|
47
|
+
|
|
48
|
+
if (length > 0) {
|
|
49
|
+
std::vector<unichar> source(length);
|
|
50
|
+
[canonical getCharacters:source.data() range:NSMakeRange(0, length)];
|
|
51
|
+
for (NSUInteger i = 0; i < length; i++) {
|
|
52
|
+
out.push_back(source[i] == '\n' ? ENRMBlockSyntaxSentinelChar : source[i]);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return [NSString stringWithCharacters:out.data() length:out.size()];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
NSString *ENRMBlockSyntaxDecode(NSString *plainText)
|
|
60
|
+
{
|
|
61
|
+
NSUInteger length = plainText.length;
|
|
62
|
+
if (length == 0 || [plainText characterAtIndex:0] != ENRMBlockSyntaxSentinelChar) {
|
|
63
|
+
return nil;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
std::vector<unichar> source(length);
|
|
67
|
+
[plainText getCharacters:source.data() range:NSMakeRange(0, length)];
|
|
68
|
+
|
|
69
|
+
std::vector<unichar> out;
|
|
70
|
+
out.reserve(length - 1);
|
|
71
|
+
for (NSUInteger i = 1; i < length; i++) {
|
|
72
|
+
out.push_back(source[i] == ENRMBlockSyntaxSentinelChar ? '\n' : source[i]);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (out.empty()) {
|
|
76
|
+
return @"";
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return [NSString stringWithCharacters:out.data() length:out.size()];
|
|
80
|
+
}
|
|
@@ -50,6 +50,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
50
50
|
@property (nonatomic, assign) CGFloat mathPaddingVertical;
|
|
51
51
|
@property (nonatomic, strong, nullable) RCTUIColor *mathSelectedBackgroundColor;
|
|
52
52
|
@property (nonatomic, strong, nullable) RCTUIColor *mathSelectedBorderColor;
|
|
53
|
+
/// Raw `fontWeight` string; narrowed at the draw site (see ENRMMathFontWeight.h).
|
|
54
|
+
@property (nonatomic, copy, nullable) NSString *mathFontWeight;
|
|
53
55
|
|
|
54
56
|
/// Math block (`$$...$$`)
|
|
55
57
|
@property (nonatomic, strong, nullable) RCTUIColor *mathBlockColor;
|
|
@@ -65,6 +67,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
65
67
|
@property (nonatomic, assign) CGFloat mathBlockMarginTop;
|
|
66
68
|
@property (nonatomic, assign) CGFloat mathBlockMarginBottom;
|
|
67
69
|
@property (nonatomic, assign) NSTextAlignment mathBlockAlignment;
|
|
70
|
+
/// Raw `fontWeight` string; narrowed at the draw site (see ENRMMathFontWeight.h).
|
|
71
|
+
@property (nonatomic, copy, nullable) NSString *mathBlockFontWeight;
|
|
68
72
|
|
|
69
73
|
- (UIFont *)fontForTraits:(UIFontDescriptorSymbolicTraits)traits;
|
|
70
74
|
- (void)invalidateFontCache;
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
copy.mathPaddingVertical = _mathPaddingVertical;
|
|
57
57
|
copy.mathSelectedBackgroundColor = _mathSelectedBackgroundColor;
|
|
58
58
|
copy.mathSelectedBorderColor = _mathSelectedBorderColor;
|
|
59
|
+
copy.mathFontWeight = _mathFontWeight;
|
|
59
60
|
copy.mathBlockColor = _mathBlockColor;
|
|
60
61
|
copy.mathBlockFontSize = _mathBlockFontSize;
|
|
61
62
|
copy.mathBlockBackgroundColor = _mathBlockBackgroundColor;
|
|
@@ -69,6 +70,7 @@
|
|
|
69
70
|
copy.mathBlockMarginTop = _mathBlockMarginTop;
|
|
70
71
|
copy.mathBlockMarginBottom = _mathBlockMarginBottom;
|
|
71
72
|
copy.mathBlockAlignment = _mathBlockAlignment;
|
|
73
|
+
copy.mathBlockFontWeight = _mathBlockFontWeight;
|
|
72
74
|
return copy;
|
|
73
75
|
}
|
|
74
76
|
|
|
@@ -22,6 +22,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
22
22
|
|
|
23
23
|
- (ENRMParseResult *)parseToPlainTextAndRanges:(NSString *)markdown;
|
|
24
24
|
|
|
25
|
+
/// `blockSyntax = NO` hides block structure from md4c (see ENRMBlockSyntaxSentinel)
|
|
26
|
+
/// and skips `ENRMInputRemendComplete`, so list markers, headings and blockquotes
|
|
27
|
+
/// survive as text and the markdown round-trips byte-for-byte.
|
|
28
|
+
- (ENRMParseResult *)parseToPlainTextAndRanges:(NSString *)markdown blockSyntax:(BOOL)blockSyntax;
|
|
29
|
+
|
|
25
30
|
@end
|
|
26
31
|
|
|
27
32
|
NS_ASSUME_NONNULL_END
|