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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#import "ENRMInputParser.h"
|
|
2
|
+
#import "ENRMBlockSyntaxSentinel.h"
|
|
2
3
|
#import "ENRMFormattingRange.h"
|
|
3
4
|
#import "ENRMInputRemend.h"
|
|
4
5
|
#include "md4c.h"
|
|
@@ -14,6 +15,11 @@
|
|
|
14
15
|
@implementation ENRMParseResult
|
|
15
16
|
@end
|
|
16
17
|
|
|
18
|
+
@interface ENRMInputParser ()
|
|
19
|
+
/// Shared body of both public entry points. `remend` gates `ENRMInputRemendComplete`.
|
|
20
|
+
- (ENRMParseResult *)parseToPlainTextAndRanges:(NSString *)markdown remend:(BOOL)remend;
|
|
21
|
+
@end
|
|
22
|
+
|
|
17
23
|
@implementation ENRMMathAtom
|
|
18
24
|
@end
|
|
19
25
|
|
|
@@ -256,9 +262,9 @@ static int onText(MD_TEXTTYPE textType, const MD_CHAR *text, MD_SIZE size, void
|
|
|
256
262
|
return 0;
|
|
257
263
|
}
|
|
258
264
|
|
|
259
|
-
static bool runMd4cParse(NSString *markdown, ParseContext &context)
|
|
265
|
+
static bool runMd4cParse(NSString *markdown, ParseContext &context, bool remend)
|
|
260
266
|
{
|
|
261
|
-
NSString *completed = ENRMInputRemendComplete(markdown);
|
|
267
|
+
NSString *completed = remend ? ENRMInputRemendComplete(markdown) : markdown;
|
|
262
268
|
const char *completedUTF8 = [completed UTF8String];
|
|
263
269
|
size_t completedLength = strlen(completedUTF8);
|
|
264
270
|
size_t originalLength = [markdown lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
|
|
@@ -286,14 +292,14 @@ struct ParsedSpans {
|
|
|
286
292
|
std::vector<MathSpanInfo> mathSpans;
|
|
287
293
|
};
|
|
288
294
|
|
|
289
|
-
static NSArray<ENRMInputStyledRange *> *runParseInternal(NSString *markdown, ParsedSpans &out)
|
|
295
|
+
static NSArray<ENRMInputStyledRange *> *runParseInternal(NSString *markdown, ParsedSpans &out, bool remend)
|
|
290
296
|
{
|
|
291
297
|
if (markdown.length == 0) {
|
|
292
298
|
return @[];
|
|
293
299
|
}
|
|
294
300
|
|
|
295
301
|
ParseContext context;
|
|
296
|
-
if (!runMd4cParse(markdown, context)) {
|
|
302
|
+
if (!runMd4cParse(markdown, context, remend)) {
|
|
297
303
|
return @[];
|
|
298
304
|
}
|
|
299
305
|
|
|
@@ -355,10 +361,77 @@ static NSArray<ENRMInputStyledRange *> *runParseInternal(NSString *markdown, Par
|
|
|
355
361
|
- (NSArray<ENRMInputStyledRange *> *)parse:(NSString *)markdown
|
|
356
362
|
{
|
|
357
363
|
ParsedSpans spans;
|
|
358
|
-
return runParseInternal(markdown, spans);
|
|
364
|
+
return runParseInternal(markdown, spans, /* remend */ true);
|
|
359
365
|
}
|
|
360
366
|
|
|
361
367
|
- (ENRMParseResult *)parseToPlainTextAndRanges:(NSString *)markdown
|
|
368
|
+
{
|
|
369
|
+
return [self parseToPlainTextAndRanges:markdown remend:YES];
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
- (ENRMParseResult *)parseToPlainTextAndRanges:(NSString *)markdown blockSyntax:(BOOL)blockSyntax
|
|
373
|
+
{
|
|
374
|
+
if (blockSyntax) {
|
|
375
|
+
return [self parseToPlainTextAndRanges:markdown];
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
NSString *canonical = ENRMBlockSyntaxCanonicalize(markdown);
|
|
379
|
+
if (canonical.length == 0) {
|
|
380
|
+
ENRMParseResult *empty = [[ENRMParseResult alloc] init];
|
|
381
|
+
empty.plainText = @"";
|
|
382
|
+
empty.formattingRanges = @[];
|
|
383
|
+
empty.mathAtoms = @[];
|
|
384
|
+
return empty;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Remending is skipped too: its speculative closing delimiters are the other
|
|
388
|
+
// source of characters the serializer cannot replay.
|
|
389
|
+
ENRMParseResult *encoded = [self parseToPlainTextAndRanges:ENRMBlockSyntaxEncode(canonical) remend:NO];
|
|
390
|
+
|
|
391
|
+
NSString *decoded = ENRMBlockSyntaxDecode(encoded.plainText);
|
|
392
|
+
ENRMParseResult *result = [[ENRMParseResult alloc] init];
|
|
393
|
+
|
|
394
|
+
if (decoded == nil) {
|
|
395
|
+
result.plainText = canonical;
|
|
396
|
+
result.formattingRanges = @[];
|
|
397
|
+
result.mathAtoms = @[];
|
|
398
|
+
return result;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Only the leading sentinel was removed, so every offset shifts by exactly one.
|
|
402
|
+
NSUInteger decodedLength = decoded.length;
|
|
403
|
+
|
|
404
|
+
NSMutableArray<ENRMFormattingRange *> *shiftedRanges =
|
|
405
|
+
[NSMutableArray arrayWithCapacity:encoded.formattingRanges.count];
|
|
406
|
+
for (ENRMFormattingRange *range in encoded.formattingRanges) {
|
|
407
|
+
NSRange r = range.range;
|
|
408
|
+
if (r.location == 0 || r.length == 0 || NSMaxRange(r) - 1 > decodedLength) {
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
[shiftedRanges addObject:[ENRMFormattingRange rangeWithType:range.type
|
|
412
|
+
range:NSMakeRange(r.location - 1, r.length)
|
|
413
|
+
url:range.url]];
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
NSMutableArray<ENRMMathAtom *> *shiftedAtoms = [NSMutableArray arrayWithCapacity:encoded.mathAtoms.count];
|
|
417
|
+
for (ENRMMathAtom *atom in encoded.mathAtoms) {
|
|
418
|
+
if (atom.position == 0 || atom.position - 1 >= decodedLength) {
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
ENRMMathAtom *shifted = [[ENRMMathAtom alloc] init];
|
|
422
|
+
shifted.position = atom.position - 1;
|
|
423
|
+
shifted.latex = atom.latex;
|
|
424
|
+
shifted.displayMode = atom.displayMode;
|
|
425
|
+
[shiftedAtoms addObject:shifted];
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
result.plainText = decoded;
|
|
429
|
+
result.formattingRanges = shiftedRanges;
|
|
430
|
+
result.mathAtoms = shiftedAtoms;
|
|
431
|
+
return result;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
- (ENRMParseResult *)parseToPlainTextAndRanges:(NSString *)markdown remend:(BOOL)remend
|
|
362
435
|
{
|
|
363
436
|
ENRMParseResult *parseResult = [[ENRMParseResult alloc] init];
|
|
364
437
|
|
|
@@ -370,7 +443,7 @@ static NSArray<ENRMInputStyledRange *> *runParseInternal(NSString *markdown, Par
|
|
|
370
443
|
}
|
|
371
444
|
|
|
372
445
|
ParsedSpans parsedSpans;
|
|
373
|
-
NSArray<ENRMInputStyledRange *> *styledRanges = runParseInternal(markdown, parsedSpans);
|
|
446
|
+
NSArray<ENRMInputStyledRange *> *styledRanges = runParseInternal(markdown, parsedSpans, remend);
|
|
374
447
|
|
|
375
448
|
// Compute byte map + raw byte ranges for math spans so we can strip the
|
|
376
449
|
// entire `$...$` (or `$$...$$`) syntax and inject a single `` at each.
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
#import "ENRMInputTextView.h"
|
|
14
14
|
#import "ENRMLinkRegexConfig.h"
|
|
15
15
|
#import "ENRMMarkdownSerializer.h"
|
|
16
|
+
#import "ENRMMathFontWeight.h"
|
|
16
17
|
#if ENRICHED_MARKDOWN_MATH
|
|
17
18
|
#import "ENRMMathInlineAttachment.h"
|
|
18
19
|
#endif
|
|
@@ -68,6 +69,8 @@ using namespace facebook::react;
|
|
|
68
69
|
BOOL _isApplyingFormatting;
|
|
69
70
|
BOOL _isTextChanging;
|
|
70
71
|
BOOL _emitMarkdown;
|
|
72
|
+
BOOL _blockSyntax;
|
|
73
|
+
NSString *_lastImportedMarkdown;
|
|
71
74
|
CFTimeInterval _lastTextChangeTime;
|
|
72
75
|
|
|
73
76
|
ENRMPlaceholderLabel *_placeholderLabel;
|
|
@@ -142,6 +145,8 @@ using namespace facebook::react;
|
|
|
142
145
|
|
|
143
146
|
self.backgroundColor = [RCTUIColor clearColor];
|
|
144
147
|
_blockEmitting = NO;
|
|
148
|
+
_blockSyntax = YES;
|
|
149
|
+
_lastImportedMarkdown = nil;
|
|
145
150
|
_heightUpdateCounter = 0;
|
|
146
151
|
_formatter = [[ENRMInputFormatter alloc] init];
|
|
147
152
|
_formatterStyle = [[ENRMInputFormatterStyle alloc] init];
|
|
@@ -253,6 +258,20 @@ using namespace facebook::react;
|
|
|
253
258
|
|
|
254
259
|
#if ENRICHED_MARKDOWN_MATH && !TARGET_OS_OSX
|
|
255
260
|
|
|
261
|
+
// Glyph rect of the chip at `index`, in _textView coordinates (the same space
|
|
262
|
+
// `locationInView:_textView` reports). Single source of truth for both the tap
|
|
263
|
+
// hit-test and the rect reported to JS.
|
|
264
|
+
- (CGRect)mathChipRectInTextViewAtIndex:(NSUInteger)index layoutManager:(NSLayoutManager *)lm
|
|
265
|
+
{
|
|
266
|
+
if (lm == nil)
|
|
267
|
+
return CGRectNull;
|
|
268
|
+
NSRange glyphRange = [lm glyphRangeForCharacterRange:NSMakeRange(index, 1) actualCharacterRange:NULL];
|
|
269
|
+
CGRect rect = [lm boundingRectForGlyphRange:glyphRange inTextContainer:_textView.textContainer];
|
|
270
|
+
rect.origin.x += _textView.textContainerInset.left;
|
|
271
|
+
rect.origin.y += _textView.textContainerInset.top;
|
|
272
|
+
return rect;
|
|
273
|
+
}
|
|
274
|
+
|
|
256
275
|
- (void)handleTapForMathChip:(UITapGestureRecognizer *)gesture
|
|
257
276
|
{
|
|
258
277
|
if (gesture.state != UIGestureRecognizerStateRecognized)
|
|
@@ -265,23 +284,28 @@ using namespace facebook::react;
|
|
|
265
284
|
if (idx < 0)
|
|
266
285
|
return;
|
|
267
286
|
NSTextStorage *storage = _textView.textStorage;
|
|
268
|
-
|
|
287
|
+
NSLayoutManager *lm = storage.layoutManagers.firstObject;
|
|
288
|
+
// The closest position can land just past the chip, so probe both `idx` and `idx-1`.
|
|
289
|
+
// `closestPositionToPoint:` has no distance bound — it clamps a tap anywhere in the
|
|
290
|
+
// text view (blank space past the text, textContainerInset padding) onto the nearest
|
|
291
|
+
// character. Requiring the touch to fall inside the chip's own glyph rect is what
|
|
292
|
+
// keeps a tap beside a chip from reading as a tap on it.
|
|
269
293
|
ENRMMathInlineAttachment *att = nil;
|
|
270
294
|
NSUInteger chipIdx = NSNotFound;
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
295
|
+
for (NSInteger probe = idx; probe >= idx - 1; probe--) {
|
|
296
|
+
if (probe < 0 || (NSUInteger)probe >= storage.length)
|
|
297
|
+
continue;
|
|
298
|
+
id v = [storage attribute:NSAttachmentAttributeName atIndex:(NSUInteger)probe effectiveRange:NULL];
|
|
299
|
+
if (![v isKindOfClass:[ENRMMathInlineAttachment class]])
|
|
300
|
+
continue;
|
|
301
|
+
// An empty rect means the layout could not give us the chip's extent; accept the
|
|
302
|
+
// candidate then, rather than making the chip untappable.
|
|
303
|
+
CGRect rect = [self mathChipRectInTextViewAtIndex:(NSUInteger)probe layoutManager:lm];
|
|
304
|
+
if (!CGRectIsEmpty(rect) && !CGRectContainsPoint(rect, loc))
|
|
305
|
+
continue;
|
|
306
|
+
att = v;
|
|
307
|
+
chipIdx = (NSUInteger)probe;
|
|
308
|
+
break;
|
|
285
309
|
}
|
|
286
310
|
if (!att)
|
|
287
311
|
return;
|
|
@@ -290,7 +314,6 @@ using namespace facebook::react;
|
|
|
290
314
|
[self clearMathChipSelectionsExcept:chipRange];
|
|
291
315
|
att.isSelected = YES;
|
|
292
316
|
[att invalidateRender];
|
|
293
|
-
NSLayoutManager *lm = storage.layoutManagers.firstObject;
|
|
294
317
|
if (lm) {
|
|
295
318
|
[lm invalidateLayoutForCharacterRange:chipRange actualCharacterRange:NULL];
|
|
296
319
|
[lm ensureLayoutForCharacterRange:chipRange];
|
|
@@ -306,10 +329,8 @@ using namespace facebook::react;
|
|
|
306
329
|
_suppressMathChipClearOnce = YES;
|
|
307
330
|
_textView.selectedRange = NSMakeRange(caretIndex, 0);
|
|
308
331
|
|
|
309
|
-
|
|
310
|
-
CGRect glyphRect = [
|
|
311
|
-
glyphRect.origin.x += _textView.textContainerInset.left;
|
|
312
|
-
glyphRect.origin.y += _textView.textContainerInset.top;
|
|
332
|
+
// Recomputed rather than reused from the hit-test: the layout was invalidated above.
|
|
333
|
+
CGRect glyphRect = [self mathChipRectInTextViewAtIndex:chipIdx layoutManager:lm];
|
|
313
334
|
CGRect rectInSelf = [self.contentView convertRect:glyphRect fromView:_textView];
|
|
314
335
|
|
|
315
336
|
[self emitOnMathPressWithLatex:att.latex start:chipIdx end:chipIdx + 1 displayMode:att.displayMode rect:rectInSelf];
|
|
@@ -546,11 +567,20 @@ using namespace facebook::react;
|
|
|
546
567
|
writingDirectionChanged = YES;
|
|
547
568
|
}
|
|
548
569
|
|
|
570
|
+
// Must land before the defaultValue import below, so the first parse already sees
|
|
571
|
+
// the right flag. Assigned unconditionally, not just on change: the generated C++
|
|
572
|
+
// default is `false` while the JS default is `true`, so `blockSyntax={false}` on the
|
|
573
|
+
// first render compares equal to the old props and a change-guard would drop it.
|
|
574
|
+
BOOL blockSyntaxChanged = (_blockSyntax != (BOOL)newViewProps.blockSyntax);
|
|
575
|
+
_blockSyntax = newViewProps.blockSyntax;
|
|
576
|
+
|
|
549
577
|
if (newViewProps.defaultValue != oldViewProps.defaultValue) {
|
|
550
578
|
if (!newViewProps.defaultValue.empty() && oldViewProps.defaultValue.empty()) {
|
|
551
579
|
NSString *markdown = [NSString stringWithUTF8String:newViewProps.defaultValue.c_str()];
|
|
552
580
|
[self importMarkdown:markdown];
|
|
553
581
|
}
|
|
582
|
+
} else if (blockSyntaxChanged && _lastImportedMarkdown != nil) {
|
|
583
|
+
[self importMarkdown:_lastImportedMarkdown];
|
|
554
584
|
}
|
|
555
585
|
|
|
556
586
|
if (styleChanged) {
|
|
@@ -694,8 +724,9 @@ using namespace facebook::react;
|
|
|
694
724
|
|
|
695
725
|
- (void)importMarkdown:(NSString *)markdown
|
|
696
726
|
{
|
|
727
|
+
_lastImportedMarkdown = [markdown copy];
|
|
697
728
|
ENRMInputParser *parser = [[ENRMInputParser alloc] init];
|
|
698
|
-
ENRMParseResult *parsed = [parser parseToPlainTextAndRanges:markdown];
|
|
729
|
+
ENRMParseResult *parsed = [parser parseToPlainTextAndRanges:markdown blockSyntax:_blockSyntax];
|
|
699
730
|
|
|
700
731
|
_blockEmitting = YES;
|
|
701
732
|
|
|
@@ -754,6 +785,7 @@ using namespace facebook::react;
|
|
|
754
785
|
att.blockAlignment = _formatterStyle.mathBlockAlignment;
|
|
755
786
|
att.selectedBackgroundColor = _formatterStyle.mathBlockSelectedBackgroundColor;
|
|
756
787
|
att.selectedBorderColor = _formatterStyle.mathBlockSelectedBorderColor;
|
|
788
|
+
att.bold = ENRMMathFontWeightIsBold(_formatterStyle.mathBlockFontWeight);
|
|
757
789
|
} else {
|
|
758
790
|
att.fontSize = _formatterStyle.mathFontSize > 0 ? _formatterStyle.mathFontSize : 16.0;
|
|
759
791
|
att.mathTextColor = _formatterStyle.mathColor ?: _formatterStyle.baseTextColor;
|
|
@@ -768,6 +800,7 @@ using namespace facebook::react;
|
|
|
768
800
|
att.blockAlignment = NSTextAlignmentNatural;
|
|
769
801
|
att.selectedBackgroundColor = _formatterStyle.mathSelectedBackgroundColor;
|
|
770
802
|
att.selectedBorderColor = _formatterStyle.mathSelectedBorderColor;
|
|
803
|
+
att.bold = ENRMMathFontWeightIsBold(_formatterStyle.mathFontWeight);
|
|
771
804
|
}
|
|
772
805
|
}
|
|
773
806
|
|
|
@@ -854,7 +887,7 @@ using namespace facebook::react;
|
|
|
854
887
|
- (void)pasteMarkdown:(NSString *)markdown
|
|
855
888
|
{
|
|
856
889
|
ENRMInputParser *parser = [[ENRMInputParser alloc] init];
|
|
857
|
-
ENRMParseResult *parsed = [parser parseToPlainTextAndRanges:markdown];
|
|
890
|
+
ENRMParseResult *parsed = [parser parseToPlainTextAndRanges:markdown blockSyntax:_blockSyntax];
|
|
858
891
|
[self replaceSelectedTextWith:parsed.plainText formattingRanges:parsed.formattingRanges];
|
|
859
892
|
}
|
|
860
893
|
|
|
@@ -187,6 +187,12 @@ BOOL applyInputStyleProps(ENRMInputFormatterStyle *style, const InputProps &newP
|
|
|
187
187
|
style.mathSelectedBorderColor = (sbc && CGColorGetAlpha(sbc.CGColor) > 0) ? sbc : nil;
|
|
188
188
|
changed = YES;
|
|
189
189
|
}
|
|
190
|
+
if (newProps.markdownStyle.math.fontWeight != oldProps.markdownStyle.math.fontWeight) {
|
|
191
|
+
if (!newProps.markdownStyle.math.fontWeight.empty()) {
|
|
192
|
+
style.mathFontWeight = [[NSString alloc] initWithUTF8String:newProps.markdownStyle.math.fontWeight.c_str()];
|
|
193
|
+
changed = YES;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
190
196
|
|
|
191
197
|
// Math block (`$$...$$`)
|
|
192
198
|
if (newProps.markdownStyle.mathBlock.color != oldProps.markdownStyle.mathBlock.color) {
|
|
@@ -237,6 +243,13 @@ BOOL applyInputStyleProps(ENRMInputFormatterStyle *style, const InputProps &newP
|
|
|
237
243
|
style.mathBlockSelectedBorderColor = (sbc && CGColorGetAlpha(sbc.CGColor) > 0) ? sbc : nil;
|
|
238
244
|
changed = YES;
|
|
239
245
|
}
|
|
246
|
+
if (newProps.markdownStyle.mathBlock.fontWeight != oldProps.markdownStyle.mathBlock.fontWeight) {
|
|
247
|
+
if (!newProps.markdownStyle.mathBlock.fontWeight.empty()) {
|
|
248
|
+
style.mathBlockFontWeight =
|
|
249
|
+
[[NSString alloc] initWithUTF8String:newProps.markdownStyle.mathBlock.fontWeight.c_str()];
|
|
250
|
+
changed = YES;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
240
253
|
if (newProps.markdownStyle.mathBlock.marginTop != oldProps.markdownStyle.mathBlock.marginTop) {
|
|
241
254
|
style.mathBlockMarginTop = newProps.markdownStyle.mathBlock.marginTop;
|
|
242
255
|
changed = YES;
|
|
@@ -131,6 +131,7 @@ template <typename StyleStruct> inline size_t computeStyleFingerprint(const Styl
|
|
|
131
131
|
hashFields(s.table.headerFontFamily, s.table.cellPaddingHorizontal, s.table.cellPaddingVertical, s.table.borderWidth,
|
|
132
132
|
s.table.borderRadius);
|
|
133
133
|
hashFields(s.math.fontSize, s.math.padding, s.math.marginTop, s.math.marginBottom, s.math.textAlign);
|
|
134
|
+
hashFields(s.inlineMath.paddingVertical);
|
|
134
135
|
hashFields(s.taskList.checkboxSize, s.taskList.checkboxBorderRadius);
|
|
135
136
|
|
|
136
137
|
return h;
|
|
@@ -10,17 +10,45 @@ import AppKit
|
|
|
10
10
|
private typealias UIColor = NSColor
|
|
11
11
|
#endif
|
|
12
12
|
|
|
13
|
+
/// Weight a formula is typeset at.
|
|
14
|
+
///
|
|
15
|
+
/// An enum rather than the `BOOL` that crosses the ObjC boundary so the draw
|
|
16
|
+
/// path's switch turns a third weight into a compile error. Mirrors
|
|
17
|
+
/// MathFontWeight.kt on Android.
|
|
18
|
+
private enum MathFontWeight {
|
|
19
|
+
case normal
|
|
20
|
+
case bold
|
|
21
|
+
|
|
22
|
+
init(bold: Bool) {
|
|
23
|
+
self = bold ? .bold : .normal
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/// Stroke added to each glyph outline, as a fraction of the em size. Scales
|
|
27
|
+
/// with the formula so a display block and an inline fraction read alike.
|
|
28
|
+
var strokeEmRatio: CGFloat {
|
|
29
|
+
switch self {
|
|
30
|
+
case .normal: return 0
|
|
31
|
+
case .bold: return 0.035
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
13
36
|
@objc(ENRMRaTeXRenderResult)
|
|
14
37
|
public final class ENRMRaTeXRenderResult: NSObject {
|
|
15
38
|
private let renderer: RaTeXRenderer
|
|
39
|
+
/// Non-zero only in bold mode: half of it grows the glyph ink on each side.
|
|
40
|
+
private let boldStrokeWidth: CGFloat
|
|
41
|
+
private let boldStrokeColor: CGColor?
|
|
16
42
|
|
|
17
43
|
@objc public let width: CGFloat
|
|
18
44
|
@objc public let ascent: CGFloat
|
|
19
45
|
@objc public let descent: CGFloat
|
|
20
46
|
@objc public var totalHeight: CGFloat { ascent + descent }
|
|
21
47
|
|
|
22
|
-
init(renderer: RaTeXRenderer) {
|
|
48
|
+
init(renderer: RaTeXRenderer, boldStrokeWidth: CGFloat, boldStrokeColor: CGColor?) {
|
|
23
49
|
self.renderer = renderer
|
|
50
|
+
self.boldStrokeWidth = boldStrokeWidth
|
|
51
|
+
self.boldStrokeColor = boldStrokeColor
|
|
24
52
|
self.width = renderer.width
|
|
25
53
|
self.ascent = renderer.height
|
|
26
54
|
self.descent = renderer.depth
|
|
@@ -28,7 +56,22 @@ public final class ENRMRaTeXRenderResult: NSObject {
|
|
|
28
56
|
}
|
|
29
57
|
|
|
30
58
|
@objc public func draw(in context: CGContext) {
|
|
59
|
+
guard boldStrokeWidth > 0, let boldStrokeColor else {
|
|
60
|
+
renderer.draw(in: context)
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
// Synthetic bold: stroke each glyph outline over its fill, the only way to
|
|
64
|
+
// add weight without moving glyphs whose positions RaTeX has already fixed
|
|
65
|
+
// (the KaTeX bold faces run up to 15% wider and would collide). It reaches
|
|
66
|
+
// every glyph because RaTeXRenderer.drawGlyph sets no text drawing mode of
|
|
67
|
+
// its own, including the paths RaTeX strokes itself (\cancel, \textcircled),
|
|
68
|
+
// which is why bold is opt-in per surface.
|
|
69
|
+
context.saveGState()
|
|
70
|
+
context.setTextDrawingMode(.fillStroke)
|
|
71
|
+
context.setLineWidth(boldStrokeWidth)
|
|
72
|
+
context.setStrokeColor(boldStrokeColor)
|
|
31
73
|
renderer.draw(in: context)
|
|
74
|
+
context.restoreGState()
|
|
32
75
|
}
|
|
33
76
|
}
|
|
34
77
|
|
|
@@ -43,13 +86,19 @@ public final class ENRMRaTeXBridge: NSObject {
|
|
|
43
86
|
_ latex: String,
|
|
44
87
|
displayMode: Bool,
|
|
45
88
|
fontSize: CGFloat,
|
|
46
|
-
color: UIColor
|
|
89
|
+
color: UIColor,
|
|
90
|
+
bold: Bool
|
|
47
91
|
) -> ENRMRaTeXRenderResult? {
|
|
48
92
|
RaTeXFontLoader.ensureLoaded()
|
|
49
93
|
do {
|
|
50
94
|
let displayList = try RaTeXEngine.shared.parse(latex, displayMode: displayMode, color: color)
|
|
51
95
|
let renderer = RaTeXRenderer(displayList: displayList, fontSize: fontSize)
|
|
52
|
-
|
|
96
|
+
let strokeWidth = fontSize * MathFontWeight(bold: bold).strokeEmRatio
|
|
97
|
+
return ENRMRaTeXRenderResult(
|
|
98
|
+
renderer: renderer,
|
|
99
|
+
boldStrokeWidth: strokeWidth,
|
|
100
|
+
boldStrokeColor: strokeWidth > 0 ? color.cgColor : nil
|
|
101
|
+
)
|
|
53
102
|
} catch {
|
|
54
103
|
NSLog("[RaTeX] Failed to parse LaTeX: %@", error.localizedDescription)
|
|
55
104
|
return nil
|
|
@@ -11,6 +11,14 @@
|
|
|
11
11
|
|
|
12
12
|
+ (instancetype)defaultFlags;
|
|
13
13
|
|
|
14
|
+
/// Flags matching the codegen `md4cFlags` Props defaults (every flag off).
|
|
15
|
+
///
|
|
16
|
+
/// Components mirror `md4cFlags` into an ivar with a per-field diff against the
|
|
17
|
+
/// props baseline, so the ivar has to start from the same baseline the props do.
|
|
18
|
+
/// `defaultFlags` enables `latexMath`, which is the right default for the
|
|
19
|
+
/// standalone parser API but would make a `latexMath: false` prop a no-op.
|
|
20
|
+
+ (instancetype)propsDefaultFlags;
|
|
21
|
+
|
|
14
22
|
@end
|
|
15
23
|
|
|
16
24
|
@interface ENRMMarkdownParser : NSObject
|
|
@@ -22,6 +22,17 @@ extern MarkdownASTNode *parseMarkdownWithCppParser(NSString *markdown, ENRMMd4cF
|
|
|
22
22
|
return [[ENRMMd4cFlags alloc] init];
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
+ (instancetype)propsDefaultFlags
|
|
26
|
+
{
|
|
27
|
+
ENRMMd4cFlags *flags = [[ENRMMd4cFlags alloc] init];
|
|
28
|
+
flags.underline = NO;
|
|
29
|
+
flags.latexMath = NO;
|
|
30
|
+
flags.superscript = NO;
|
|
31
|
+
flags.subscript = NO;
|
|
32
|
+
flags.highlight = NO;
|
|
33
|
+
return flags;
|
|
34
|
+
}
|
|
35
|
+
|
|
25
36
|
- (id)copyWithZone:(NSZone *)zone
|
|
26
37
|
{
|
|
27
38
|
ENRMMd4cFlags *copy = [[ENRMMd4cFlags allocWithZone:zone] init];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#import "ENRMMathInlineRenderer.h"
|
|
2
|
+
#import "ENRMMathFontWeight.h"
|
|
2
3
|
#import "ENRMMathInlineAttachment.h"
|
|
3
4
|
#import "MarkdownASTNode.h"
|
|
4
5
|
#import "RenderContext.h"
|
|
@@ -25,6 +26,8 @@
|
|
|
25
26
|
attachment.latex = latex;
|
|
26
27
|
attachment.fontSize = currentFont ? currentFont.pointSize : [_config paragraphFontSize];
|
|
27
28
|
attachment.mathTextColor = [_config inlineMathColor];
|
|
29
|
+
attachment.containerPaddingVertical = [_config inlineMathPaddingVertical];
|
|
30
|
+
attachment.bold = ENRMMathFontWeightIsBold([_config inlineMathFontWeight]);
|
|
28
31
|
|
|
29
32
|
#if TARGET_OS_OSX
|
|
30
33
|
// On macOS, NSLayoutManager uses self.image/self.bounds rather than calling
|
|
@@ -109,15 +109,18 @@ NSString *const TaskIndexAttribute = @"TaskIndex";
|
|
|
109
109
|
style.firstLineHeadIndent = totalIndent;
|
|
110
110
|
style.headIndent = totalIndent;
|
|
111
111
|
|
|
112
|
-
if (lineHeightConfig > 0) {
|
|
113
|
-
style.minimumLineHeight = lineHeightConfig;
|
|
114
|
-
style.maximumLineHeight = lineHeightConfig;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
112
|
NSMutableDictionary *attributesToApply = [metadata mutableCopy];
|
|
118
113
|
attributesToApply[NSParagraphStyleAttributeName] = style;
|
|
119
114
|
|
|
120
115
|
[output addAttributes:attributesToApply range:range];
|
|
116
|
+
|
|
117
|
+
// Line height goes through the shared helper so list items get the same math
|
|
118
|
+
// carve-out as paragraphs. Setting maximumLineHeight here directly would clamp
|
|
119
|
+
// the line fragment below the height an inline math attachment draws at, and the
|
|
120
|
+
// overflow paints over the neighbouring lines. applyLineHeight reads back the
|
|
121
|
+
// paragraph style we just applied, so the indents above survive, and it
|
|
122
|
+
// early-returns on a non-positive line height like the old guard did.
|
|
123
|
+
applyLineHeight(output, range, lineHeightConfig);
|
|
121
124
|
}];
|
|
122
125
|
|
|
123
126
|
if (isTask && isChecked) {
|
package/ios/styles/StyleConfig.h
CHANGED
|
@@ -378,10 +378,16 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
378
378
|
- (void)setMathMarginBottom:(CGFloat)newValue;
|
|
379
379
|
- (NSString *)mathTextAlign;
|
|
380
380
|
- (void)setMathTextAlign:(NSString *)newValue;
|
|
381
|
+
- (NSString *)mathFontWeight;
|
|
382
|
+
- (void)setMathFontWeight:(NSString *)newValue;
|
|
381
383
|
|
|
382
384
|
// Inline Math properties
|
|
383
385
|
- (RCTUIColor *)inlineMathColor;
|
|
384
386
|
- (void)setInlineMathColor:(RCTUIColor *)newValue;
|
|
387
|
+
- (CGFloat)inlineMathPaddingVertical;
|
|
388
|
+
- (void)setInlineMathPaddingVertical:(CGFloat)newValue;
|
|
389
|
+
- (NSString *)inlineMathFontWeight;
|
|
390
|
+
- (void)setInlineMathFontWeight:(NSString *)newValue;
|
|
385
391
|
// Spoiler properties
|
|
386
392
|
- (RCTUIColor *)spoilerColor;
|
|
387
393
|
- (void)setSpoilerColor:(RCTUIColor *)newValue;
|
|
@@ -224,8 +224,11 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
|
|
|
224
224
|
CGFloat _mathMarginTop;
|
|
225
225
|
CGFloat _mathMarginBottom;
|
|
226
226
|
NSString *_mathTextAlign;
|
|
227
|
+
NSString *_mathFontWeight;
|
|
227
228
|
// Inline Math properties
|
|
228
229
|
RCTUIColor *_inlineMathColor;
|
|
230
|
+
CGFloat _inlineMathPaddingVertical;
|
|
231
|
+
NSString *_inlineMathFontWeight;
|
|
229
232
|
// Spoiler properties
|
|
230
233
|
RCTUIColor *_spoilerColor;
|
|
231
234
|
CGFloat _spoilerParticleDensity;
|
|
@@ -482,7 +485,10 @@ static inline NSString *normalizedFontWeight(NSString *fontWeight)
|
|
|
482
485
|
copy->_mathMarginTop = _mathMarginTop;
|
|
483
486
|
copy->_mathMarginBottom = _mathMarginBottom;
|
|
484
487
|
copy->_mathTextAlign = [_mathTextAlign copy];
|
|
488
|
+
copy->_mathFontWeight = [_mathFontWeight copy];
|
|
485
489
|
copy->_inlineMathColor = [_inlineMathColor copy];
|
|
490
|
+
copy->_inlineMathPaddingVertical = _inlineMathPaddingVertical;
|
|
491
|
+
copy->_inlineMathFontWeight = [_inlineMathFontWeight copy];
|
|
486
492
|
copy->_spoilerColor = [_spoilerColor copy];
|
|
487
493
|
copy->_spoilerParticleDensity = _spoilerParticleDensity;
|
|
488
494
|
copy->_spoilerParticleSpeed = _spoilerParticleSpeed;
|
|
@@ -2430,6 +2436,36 @@ static const CGFloat kDefaultMinGap = 4.0;
|
|
|
2430
2436
|
_inlineMathColor = newValue;
|
|
2431
2437
|
}
|
|
2432
2438
|
|
|
2439
|
+
- (CGFloat)inlineMathPaddingVertical
|
|
2440
|
+
{
|
|
2441
|
+
return _inlineMathPaddingVertical;
|
|
2442
|
+
}
|
|
2443
|
+
|
|
2444
|
+
- (NSString *)mathFontWeight
|
|
2445
|
+
{
|
|
2446
|
+
return _mathFontWeight;
|
|
2447
|
+
}
|
|
2448
|
+
|
|
2449
|
+
- (void)setMathFontWeight:(NSString *)newValue
|
|
2450
|
+
{
|
|
2451
|
+
_mathFontWeight = newValue;
|
|
2452
|
+
}
|
|
2453
|
+
|
|
2454
|
+
- (NSString *)inlineMathFontWeight
|
|
2455
|
+
{
|
|
2456
|
+
return _inlineMathFontWeight;
|
|
2457
|
+
}
|
|
2458
|
+
|
|
2459
|
+
- (void)setInlineMathFontWeight:(NSString *)newValue
|
|
2460
|
+
{
|
|
2461
|
+
_inlineMathFontWeight = newValue;
|
|
2462
|
+
}
|
|
2463
|
+
|
|
2464
|
+
- (void)setInlineMathPaddingVertical:(CGFloat)newValue
|
|
2465
|
+
{
|
|
2466
|
+
_inlineMathPaddingVertical = newValue;
|
|
2467
|
+
}
|
|
2468
|
+
|
|
2433
2469
|
// ── Spoiler ─────────────────────────────────────────────────────────────
|
|
2434
2470
|
|
|
2435
2471
|
- (RCTUIColor *)spoilerColor
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#import <Foundation/Foundation.h>
|
|
4
|
+
|
|
5
|
+
/// Weight a formula can actually be typeset at.
|
|
6
|
+
///
|
|
7
|
+
/// The style config keeps `fontWeight` as an `NSString *`, the way the other 13
|
|
8
|
+
/// `fontWeight` props do, so a value like `@"600"` survives as far as the
|
|
9
|
+
/// renderer. This is the narrowing step at that last hop — the only place on
|
|
10
|
+
/// iOS that decides what "bold" means for math — so the rule lives in one
|
|
11
|
+
/// place instead of at every prop boundary. Mirrors MathFontWeight.kt on
|
|
12
|
+
/// Android.
|
|
13
|
+
///
|
|
14
|
+
/// `nil` (prop never set) reads as normal, which is the documented default.
|
|
15
|
+
static inline BOOL ENRMMathFontWeightIsBold(NSString *_Nullable fontWeight)
|
|
16
|
+
{
|
|
17
|
+
return [fontWeight isEqualToString:@"bold"];
|
|
18
|
+
}
|
|
@@ -1078,6 +1078,14 @@ BOOL applyMarkdownStyleToConfig(StyleConfig *config, const MarkdownStyle &newSty
|
|
|
1078
1078
|
changed = YES;
|
|
1079
1079
|
}
|
|
1080
1080
|
|
|
1081
|
+
if (newStyle.math.fontWeight != oldStyle.math.fontWeight) {
|
|
1082
|
+
if (!newStyle.math.fontWeight.empty()) {
|
|
1083
|
+
NSString *fontWeight = [[NSString alloc] initWithUTF8String:newStyle.math.fontWeight.c_str()];
|
|
1084
|
+
[config setMathFontWeight:fontWeight];
|
|
1085
|
+
changed = YES;
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1081
1089
|
if (newStyle.math.textAlign != oldStyle.math.textAlign) {
|
|
1082
1090
|
[config setMathTextAlign:@(newStyle.math.textAlign.c_str())];
|
|
1083
1091
|
changed = YES;
|
|
@@ -1095,6 +1103,19 @@ BOOL applyMarkdownStyleToConfig(StyleConfig *config, const MarkdownStyle &newSty
|
|
|
1095
1103
|
changed = YES;
|
|
1096
1104
|
}
|
|
1097
1105
|
|
|
1106
|
+
if (newStyle.inlineMath.fontWeight != oldStyle.inlineMath.fontWeight) {
|
|
1107
|
+
if (!newStyle.inlineMath.fontWeight.empty()) {
|
|
1108
|
+
NSString *fontWeight = [[NSString alloc] initWithUTF8String:newStyle.inlineMath.fontWeight.c_str()];
|
|
1109
|
+
[config setInlineMathFontWeight:fontWeight];
|
|
1110
|
+
changed = YES;
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
if (newStyle.inlineMath.paddingVertical != oldStyle.inlineMath.paddingVertical) {
|
|
1115
|
+
[config setInlineMathPaddingVertical:newStyle.inlineMath.paddingVertical];
|
|
1116
|
+
changed = YES;
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1098
1119
|
// ── Spoiler ─────────────────────────────────────────────────────────────
|
|
1099
1120
|
|
|
1100
1121
|
if (newStyle.spoiler.color != oldStyle.spoiler.color) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#import "ENRMMathContainerView.h"
|
|
2
2
|
#import "ENRMAccessibilityLabels.h"
|
|
3
3
|
#import "ENRMFeatureFlags.h"
|
|
4
|
+
#import "ENRMMathFontWeight.h"
|
|
4
5
|
#include <TargetConditionals.h>
|
|
5
6
|
|
|
6
7
|
#if ENRICHED_MARKDOWN_MATH
|
|
@@ -94,7 +95,8 @@
|
|
|
94
95
|
ENRMRaTeXRenderResult *result = [ENRMRaTeXBridge parse:latex
|
|
95
96
|
displayMode:YES
|
|
96
97
|
fontSize:config.mathFontSize
|
|
97
|
-
color:config.mathColor
|
|
98
|
+
color:config.mathColor
|
|
99
|
+
bold:ENRMMathFontWeightIsBold(config.mathFontWeight)];
|
|
98
100
|
_mathView.renderResult = result;
|
|
99
101
|
|
|
100
102
|
CGFloat padding = config.mathPadding;
|
|
@@ -141,10 +141,13 @@ interface MathStyleInternal {
|
|
|
141
141
|
marginTop: CodegenTypes.Float;
|
|
142
142
|
marginBottom: CodegenTypes.Float;
|
|
143
143
|
textAlign: string;
|
|
144
|
+
fontWeight: string;
|
|
144
145
|
}
|
|
145
146
|
|
|
146
147
|
interface InlineMathStyleInternal {
|
|
147
148
|
color: ColorValue;
|
|
149
|
+
paddingVertical: CodegenTypes.Float;
|
|
150
|
+
fontWeight: string;
|
|
148
151
|
}
|
|
149
152
|
|
|
150
153
|
interface SpoilerParticlesStyleInternal {
|