react-native-marcus 0.1.0 → 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 +220 -63
- package/RNMarcus.podspec +6 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusPackage.kt +2 -1
- package/android/src/main/java/app/getbullet/marcus/MarcusTextDecoratorView.kt +168 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusTextDecoratorViewManager.kt +38 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusTextDecoratorViewManagerSpec.kt +19 -0
- package/android/src/main/java/app/getbullet/marcus/MarcusTextInputDecoratorView.kt +23 -1
- package/android/src/main/java/app/getbullet/marcus/MarkdownBackgroundPainter.kt +147 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownBackgroundPass.kt +19 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownCopy.kt +87 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownFormatter.kt +652 -113
- package/android/src/main/java/app/getbullet/marcus/MarkdownRanges.kt +47 -0
- package/android/src/main/java/app/getbullet/marcus/MarkdownStyle.kt +140 -61
- package/android/src/main/java/app/getbullet/marcus/MarkdownUtils.kt +37 -7
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownAbsoluteLineHeightSpan.kt +48 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBackgroundSpan.kt +102 -48
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBlockIndentSpan.kt +22 -4
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBulletSpan.kt +78 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownCodeBlockSpan.kt +177 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownFontStyleSpan.kt +32 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownFontWeightSpan.kt +34 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownGapSpan.kt +24 -11
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownLetterSpacingSpan.kt +32 -0
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownTextShadowSpan.kt +32 -0
- package/android/src/main/new_arch/CMakeLists.txt +17 -0
- package/android/src/main/new_arch/RNMarcusSpec.h +1 -0
- package/android/src/main/new_arch/react/renderer/components/RNMarcusSpec/MarcusTextDecoratorShadowNode.cpp +235 -0
- package/android/src/main/new_arch/react/renderer/components/RNMarcusSpec/MarcusTextDecoratorShadowNode.h +62 -0
- package/android/src/reactNativeVersionPatch/CustomMountingManager/81/app/getbullet/marcus/CustomFabricUIManager.java +22 -3
- package/android/src/reactNativeVersionPatch/CustomMountingManager/latest/app/getbullet/marcus/CustomFabricUIManager.java +22 -3
- package/android/src/test/java/app/getbullet/marcus/MarkdownCopyTest.kt +69 -0
- package/android/src/test/java/app/getbullet/marcus/MarkdownFormatterTest.kt +170 -25
- package/android/src/test/java/app/getbullet/marcus/RenderModel.kt +22 -5
- package/android/src/test/java/app/getbullet/marcus/spans/MarkdownCodeBlockSpanTest.kt +91 -0
- package/android/src/test/resources/render-model.txt +221 -16
- package/apple/MarcusSwizzle.h +25 -0
- package/apple/MarcusTextDecoratorComponentView.h +22 -0
- package/apple/MarcusTextDecoratorComponentView.mm +72 -0
- package/apple/MarcusTextDecoratorShadowNode.h +62 -0
- package/apple/MarcusTextDecoratorShadowNode.mm +192 -0
- package/apple/MarcusTextDecoratorViewManager.h +4 -0
- package/apple/MarcusTextDecoratorViewManager.mm +11 -0
- package/apple/MarcusTextInputDecoratorComponentView.mm +1 -1
- package/apple/MarcusTextInputDecoratorShadowNode.mm +1 -1
- package/apple/MarcusTextLayoutManager.h +40 -0
- package/apple/MarcusTextLayoutManager.mm +173 -0
- package/apple/MarkdownAttributes.h +23 -2
- package/apple/MarkdownAttributes.m +6 -0
- package/apple/MarkdownCopy.swift +63 -0
- package/apple/MarkdownDecorator.swift +2 -2
- package/apple/MarkdownFormatter+React.swift +23 -0
- package/apple/MarkdownFormatter.swift +869 -148
- package/apple/MarkdownParagraphLayoutManager.swift +455 -0
- package/apple/MarkdownSwiftInterop.h +0 -1
- package/apple/MarkdownTextBackground.swift +59 -1
- package/apple/MarkdownTextFieldObserver.swift +2 -2
- package/apple/MarkdownTextLayoutFragment.swift +159 -33
- package/apple/MarkdownTextLayoutManagerDelegate.swift +67 -3
- package/apple/MarkdownTextStorageDelegate.swift +2 -2
- package/apple/MarkdownTextViewObserver.swift +2 -2
- package/apple/MarkdownUtils.swift +38 -0
- package/apple/MarkdownWritingDirection.swift +132 -0
- package/apple/RCTMarcusStyle+Codegen.h +115 -9
- package/apple/RCTMarcusStyle.h +128 -31
- package/apple/RCTMarcusStyle.m +48 -0
- package/apple/RCTParagraphComponentView+Marcus.h +17 -0
- package/apple/RCTParagraphComponentView+Marcus.mm +38 -0
- package/apple/RCTTextInputComponentView+Marcus.mm +1 -25
- package/cpp/react/renderer/components/RNMarcusSpec/MarcusTextDecoratorState.h +37 -0
- package/cpp/react/renderer/components/RNMarcusSpec/MarcusTextDecoratorViewComponentDescriptor.h +17 -0
- package/lib/commonjs/MarcusTextDecoratorViewNativeComponent.ts +199 -0
- package/lib/commonjs/MarcusTextInputDecoratorViewNativeComponent.ts +145 -58
- package/lib/commonjs/MarkdownText.js +330 -0
- package/lib/commonjs/MarkdownText.js.map +1 -0
- package/lib/commonjs/MarkdownText.web.js +529 -0
- package/lib/commonjs/MarkdownText.web.js.map +1 -0
- package/lib/commonjs/MarkdownTextInput.js +22 -27
- package/lib/commonjs/MarkdownTextInput.js.map +1 -1
- package/lib/commonjs/MarkdownTextInput.web.js +12 -7
- package/lib/commonjs/MarkdownTextInput.web.js.map +1 -1
- package/lib/commonjs/atomUtils.js +112 -0
- package/lib/commonjs/atomUtils.js.map +1 -0
- package/lib/commonjs/childrenUtils.js +36 -0
- package/lib/commonjs/childrenUtils.js.map +1 -0
- package/lib/commonjs/index.js +8 -7
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/math/environment.js +69 -0
- package/lib/commonjs/math/environment.js.map +1 -0
- package/lib/commonjs/math/index.js +61 -0
- package/lib/commonjs/math/index.js.map +1 -0
- package/lib/commonjs/math/mathjax.js +548 -0
- package/lib/commonjs/math/mathjax.js.map +1 -0
- package/lib/commonjs/metro.js +172 -0
- package/lib/commonjs/metro.js.map +1 -0
- package/lib/commonjs/parser/index.d.ts +3 -0
- package/lib/commonjs/parser/index.js +450 -42
- package/lib/commonjs/parser/index.js.map +4 -4
- package/lib/commonjs/stripUtils.js +743 -0
- package/lib/commonjs/stripUtils.js.map +1 -0
- package/lib/commonjs/styleUtils.js +194 -23
- package/lib/commonjs/styleUtils.js.map +1 -1
- package/lib/commonjs/web/MarkdownElements.css +67 -0
- package/lib/commonjs/web/MarkdownTextInput.css +9 -7
- package/lib/commonjs/web/utils/blockLayout.js +95 -7
- package/lib/commonjs/web/utils/blockLayout.js.map +1 -1
- package/lib/commonjs/web/utils/blockUtils.js +327 -54
- package/lib/commonjs/web/utils/blockUtils.js.map +1 -1
- package/lib/commonjs/web/utils/elementUtils.js +80 -0
- package/lib/commonjs/web/utils/elementUtils.js.map +1 -0
- package/lib/commonjs/web/utils/parserUtils.js +84 -28
- package/lib/commonjs/web/utils/parserUtils.js.map +1 -1
- package/lib/commonjs/web/utils/treeUtils.js +6 -0
- package/lib/commonjs/web/utils/treeUtils.js.map +1 -1
- package/lib/commonjs/web/utils/webStyleUtils.js +25 -5
- package/lib/commonjs/web/utils/webStyleUtils.js.map +1 -1
- package/lib/module/MarcusTextDecoratorViewNativeComponent.ts +199 -0
- package/lib/module/MarcusTextInputDecoratorViewNativeComponent.ts +145 -58
- package/lib/module/MarkdownText.js +325 -0
- package/lib/module/MarkdownText.js.map +1 -0
- package/lib/module/MarkdownText.web.js +524 -0
- package/lib/module/MarkdownText.web.js.map +1 -0
- package/lib/module/MarkdownTextInput.js +24 -29
- package/lib/module/MarkdownTextInput.js.map +1 -1
- package/lib/module/MarkdownTextInput.web.js +12 -7
- package/lib/module/MarkdownTextInput.web.js.map +1 -1
- package/lib/module/atomUtils.js +106 -0
- package/lib/module/atomUtils.js.map +1 -0
- package/lib/module/childrenUtils.js +33 -0
- package/lib/module/childrenUtils.js.map +1 -0
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/math/environment.js +67 -0
- package/lib/module/math/environment.js.map +1 -0
- package/lib/module/math/index.js +56 -0
- package/lib/module/math/index.js.map +1 -0
- package/lib/module/math/mathjax.js +541 -0
- package/lib/module/math/mathjax.js.map +1 -0
- package/lib/module/metro.js +169 -0
- package/lib/module/metro.js.map +1 -0
- package/lib/module/parser/index.d.ts +3 -0
- package/lib/module/parser/index.js +450 -42
- package/lib/module/parser/index.js.map +4 -4
- package/lib/module/stripUtils.js +739 -0
- package/lib/module/stripUtils.js.map +1 -0
- package/lib/module/styleUtils.js +196 -25
- package/lib/module/styleUtils.js.map +1 -1
- package/lib/module/web/MarkdownElements.css +67 -0
- package/lib/module/web/MarkdownTextInput.css +9 -7
- package/lib/module/web/utils/blockLayout.js +94 -8
- package/lib/module/web/utils/blockLayout.js.map +1 -1
- package/lib/module/web/utils/blockUtils.js +328 -56
- package/lib/module/web/utils/blockUtils.js.map +1 -1
- package/lib/module/web/utils/elementUtils.js +75 -0
- package/lib/module/web/utils/elementUtils.js.map +1 -0
- package/lib/module/web/utils/parserUtils.js +86 -30
- package/lib/module/web/utils/parserUtils.js.map +1 -1
- package/lib/module/web/utils/treeUtils.js +6 -0
- package/lib/module/web/utils/treeUtils.js.map +1 -1
- package/lib/module/web/utils/webStyleUtils.js +25 -5
- package/lib/module/web/utils/webStyleUtils.js.map +1 -1
- package/lib/typescript/commonjs/e2e/links.test.d.ts +2 -0
- package/lib/typescript/commonjs/e2e/links.test.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/MarcusTextDecoratorViewNativeComponent.d.ts +93 -0
- package/lib/typescript/commonjs/src/MarcusTextDecoratorViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/MarcusTextInputDecoratorViewNativeComponent.d.ts +64 -51
- package/lib/typescript/commonjs/src/MarcusTextInputDecoratorViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/MarkdownText.d.ts +127 -0
- package/lib/typescript/commonjs/src/MarkdownText.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/MarkdownText.web.d.ts +126 -0
- package/lib/typescript/commonjs/src/MarkdownText.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/MarkdownTextInput.d.ts +23 -1
- package/lib/typescript/commonjs/src/MarkdownTextInput.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/MarkdownTextInput.web.d.ts +26 -4
- package/lib/typescript/commonjs/src/MarkdownTextInput.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/atomUtils.d.ts +58 -0
- package/lib/typescript/commonjs/src/atomUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/childrenUtils.d.ts +12 -0
- package/lib/typescript/commonjs/src/childrenUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/commonTypes.d.ts +39 -3
- package/lib/typescript/commonjs/src/commonTypes.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.d.ts +2 -1
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/math/environment.d.ts +7 -0
- package/lib/typescript/commonjs/src/math/environment.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/math/index.d.ts +64 -0
- package/lib/typescript/commonjs/src/math/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/math/mathjax.d.ts +63 -0
- package/lib/typescript/commonjs/src/math/mathjax.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/metro.d.ts +59 -0
- package/lib/typescript/commonjs/src/metro.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/parser/index.d.ts +3 -3
- package/lib/typescript/commonjs/src/parser/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/parser/micromark-extension-mentions.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/rangeUtils.d.ts +1 -1
- package/lib/typescript/commonjs/src/stripUtils.d.ts +108 -0
- package/lib/typescript/commonjs/src/stripUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/styleUtils.d.ts +62 -4
- package/lib/typescript/commonjs/src/styleUtils.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/web/utils/blockLayout.d.ts +32 -4
- package/lib/typescript/commonjs/src/web/utils/blockLayout.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/web/utils/blockUtils.d.ts +20 -8
- package/lib/typescript/commonjs/src/web/utils/blockUtils.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/web/utils/elementUtils.d.ts +37 -0
- package/lib/typescript/commonjs/src/web/utils/elementUtils.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/web/utils/parserUtils.d.ts +5 -5
- package/lib/typescript/commonjs/src/web/utils/parserUtils.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/web/utils/treeUtils.d.ts +6 -1
- package/lib/typescript/commonjs/src/web/utils/treeUtils.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/web/utils/webStyleUtils.d.ts +2 -2
- package/lib/typescript/commonjs/src/web/utils/webStyleUtils.d.ts.map +1 -1
- package/lib/typescript/module/e2e/links.test.d.ts +2 -0
- package/lib/typescript/module/e2e/links.test.d.ts.map +1 -0
- package/lib/typescript/module/src/MarcusTextDecoratorViewNativeComponent.d.ts +93 -0
- package/lib/typescript/module/src/MarcusTextDecoratorViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/module/src/MarcusTextInputDecoratorViewNativeComponent.d.ts +64 -51
- package/lib/typescript/module/src/MarcusTextInputDecoratorViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/module/src/MarkdownText.d.ts +127 -0
- package/lib/typescript/module/src/MarkdownText.d.ts.map +1 -0
- package/lib/typescript/module/src/MarkdownText.web.d.ts +126 -0
- package/lib/typescript/module/src/MarkdownText.web.d.ts.map +1 -0
- package/lib/typescript/module/src/MarkdownTextInput.d.ts +23 -1
- package/lib/typescript/module/src/MarkdownTextInput.d.ts.map +1 -1
- package/lib/typescript/module/src/MarkdownTextInput.web.d.ts +26 -4
- package/lib/typescript/module/src/MarkdownTextInput.web.d.ts.map +1 -1
- package/lib/typescript/module/src/atomUtils.d.ts +58 -0
- package/lib/typescript/module/src/atomUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/childrenUtils.d.ts +12 -0
- package/lib/typescript/module/src/childrenUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/commonTypes.d.ts +39 -3
- package/lib/typescript/module/src/commonTypes.d.ts.map +1 -1
- package/lib/typescript/module/src/index.d.ts +2 -1
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/lib/typescript/module/src/math/environment.d.ts +7 -0
- package/lib/typescript/module/src/math/environment.d.ts.map +1 -0
- package/lib/typescript/module/src/math/index.d.ts +64 -0
- package/lib/typescript/module/src/math/index.d.ts.map +1 -0
- package/lib/typescript/module/src/math/mathjax.d.ts +63 -0
- package/lib/typescript/module/src/math/mathjax.d.ts.map +1 -0
- package/lib/typescript/module/src/metro.d.ts +59 -0
- package/lib/typescript/module/src/metro.d.ts.map +1 -0
- package/lib/typescript/module/src/parser/index.d.ts +3 -3
- package/lib/typescript/module/src/parser/index.d.ts.map +1 -1
- package/lib/typescript/module/src/parser/micromark-extension-mentions.d.ts.map +1 -1
- package/lib/typescript/module/src/rangeUtils.d.ts +1 -1
- package/lib/typescript/module/src/stripUtils.d.ts +108 -0
- package/lib/typescript/module/src/stripUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/styleUtils.d.ts +62 -4
- package/lib/typescript/module/src/styleUtils.d.ts.map +1 -1
- package/lib/typescript/module/src/web/utils/blockLayout.d.ts +32 -4
- package/lib/typescript/module/src/web/utils/blockLayout.d.ts.map +1 -1
- package/lib/typescript/module/src/web/utils/blockUtils.d.ts +20 -8
- package/lib/typescript/module/src/web/utils/blockUtils.d.ts.map +1 -1
- package/lib/typescript/module/src/web/utils/elementUtils.d.ts +37 -0
- package/lib/typescript/module/src/web/utils/elementUtils.d.ts.map +1 -0
- package/lib/typescript/module/src/web/utils/parserUtils.d.ts +5 -5
- package/lib/typescript/module/src/web/utils/parserUtils.d.ts.map +1 -1
- package/lib/typescript/module/src/web/utils/treeUtils.d.ts +6 -1
- package/lib/typescript/module/src/web/utils/treeUtils.d.ts.map +1 -1
- package/lib/typescript/module/src/web/utils/webStyleUtils.d.ts +2 -2
- package/lib/typescript/module/src/web/utils/webStyleUtils.d.ts.map +1 -1
- package/package.json +29 -2
- package/react-native.config.js +8 -1
- package/src/MarcusTextDecoratorViewNativeComponent.ts +199 -0
- package/src/MarcusTextInputDecoratorViewNativeComponent.ts +145 -58
- package/src/MarkdownText.tsx +472 -0
- package/src/MarkdownText.web.tsx +668 -0
- package/src/MarkdownTextInput.tsx +42 -38
- package/src/MarkdownTextInput.web.tsx +36 -13
- package/src/atomUtils.ts +112 -0
- package/src/childrenUtils.ts +39 -0
- package/src/commonTypes.ts +69 -9
- package/src/index.tsx +2 -1
- package/src/math/environment.ts +68 -0
- package/src/math/index.ts +78 -0
- package/src/math/mathjax.ts +604 -0
- package/src/metro.ts +238 -0
- package/src/parser/index.ts +175 -10
- package/src/parser/micromark-extension-mentions.ts +104 -11
- package/src/stripUtils.ts +919 -0
- package/src/styleUtils.ts +290 -26
- package/src/web/MarkdownElements.css +67 -0
- package/src/web/MarkdownTextInput.css +9 -7
- package/src/web/utils/blockLayout.ts +124 -14
- package/src/web/utils/blockUtils.ts +365 -59
- package/src/web/utils/elementUtils.ts +87 -0
- package/src/web/utils/parserUtils.ts +119 -31
- package/src/web/utils/treeUtils.ts +6 -1
- package/src/web/utils/webStyleUtils.ts +32 -8
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBackgroundColorSpan.kt +0 -6
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownBoldSpan.kt +0 -6
- package/android/src/main/java/app/getbullet/marcus/spans/MarkdownItalicSpan.kt +0 -6
- package/apple/RCTMarcusStyle+Codegen.mm +0 -64
- package/apple/RCTMarcusUtils.h +0 -26
- package/apple/RCTMarcusUtils.mm +0 -26
|
@@ -3,66 +3,145 @@ import type { ColorValue, ViewProps } from "react-native"
|
|
|
3
3
|
|
|
4
4
|
import type { Float, Int32 } from "react-native/Libraries/Types/CodegenTypes"
|
|
5
5
|
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
// The text attributes one styled run can carry: the subset of React Native's
|
|
7
|
+
// `TextStyle` that survives as an `NSAttributedString` attribute on iOS, as a
|
|
8
|
+
// span on Android, and as a declaration on an inline element on the web.
|
|
9
|
+
//
|
|
10
|
+
// Everything here is optional and everything unset is inherited, which is what a
|
|
11
|
+
// run of markdown wants -- a mention that only names a colour keeps the face,
|
|
12
|
+
// the size and the weight of the prose it sits in. Native reads "unset" off the
|
|
13
|
+
// zero value: an empty string, a null colour, a zero length. That costs nothing,
|
|
14
|
+
// because a zero-length `letterSpacing`, `lineHeight` or `fontSize` means the
|
|
15
|
+
// same as leaving it out.
|
|
16
|
+
//
|
|
17
|
+
// `fontWeight`, `fontStyle`, `textDecorationLine` and `textDecorationStyle`
|
|
18
|
+
// arrive as plain strings rather than as unions. Codegen turns a union of string
|
|
19
|
+
// literals into an enum named after the prop it was found on, so the same
|
|
20
|
+
// spelling on twelve entries would become twelve unrelated C++ types and the one
|
|
21
|
+
// conversion template in `RCTMarcusStyle+Codegen.h` could not read any of them.
|
|
22
|
+
// The public type in `styleUtils` is the narrow one; this is the wire.
|
|
23
|
+
interface MarkdownTextStyle {
|
|
24
|
+
color?: ColorValue
|
|
25
|
+
fontFamily?: string
|
|
26
|
+
fontSize?: Float
|
|
27
|
+
fontStyle?: string
|
|
28
|
+
fontWeight?: string
|
|
29
|
+
letterSpacing?: Float
|
|
30
|
+
// Applies to whole lines: the platforms set it on the paragraph, so a range
|
|
31
|
+
// covering part of a line raises the height of all of it.
|
|
32
|
+
lineHeight?: Float
|
|
33
|
+
textDecorationLine?: string
|
|
34
|
+
// iOS and web only. Android draws an underline and a strikethrough in the text
|
|
35
|
+
// colour and offers no way to say otherwise.
|
|
36
|
+
textDecorationColor?: ColorValue
|
|
37
|
+
textDecorationStyle?: string
|
|
38
|
+
textShadowColor?: ColorValue
|
|
39
|
+
textShadowOffset?: { width: Float; height: Float }
|
|
40
|
+
textShadowRadius?: Float
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// A run drawn as a box rather than as a background behind the glyphs: an inline
|
|
44
|
+
// or fenced run of code, or a mention's pill. Rounded, optionally bordered, with
|
|
45
|
+
// room inside it and around it, on top of whatever text attributes it carries.
|
|
46
|
+
//
|
|
47
|
+
// What the room holds open differs, because a block owns its lines and a run
|
|
48
|
+
// shares one. A block's padding and margin are held open on the leading edge and
|
|
49
|
+
// vertically, and a line long enough to wrap reaches the padding on the trailing
|
|
50
|
+
// edge rather than stopping in front of it: neither platform can reserve a
|
|
51
|
+
// trailing indent per paragraph. An inline run holds its padding and margin open
|
|
52
|
+
// on both sides, by widening the characters it starts and ends with, and grows
|
|
53
|
+
// into the line's own spacing above and below rather than pushing the lines
|
|
54
|
+
// apart.
|
|
55
|
+
//
|
|
56
|
+
// `padding` is the fallback for both axes; `paddingHorizontal` and
|
|
57
|
+
// `paddingVertical` win over it where they are set, and `margin` the same. A
|
|
58
|
+
// fenced block usually wants more room above and below than beside it, and one
|
|
59
|
+
// number cannot say that.
|
|
60
|
+
interface MarkdownBoxStyle extends MarkdownTextStyle {
|
|
61
|
+
backgroundColor?: ColorValue
|
|
62
|
+
borderColor?: ColorValue
|
|
63
|
+
borderWidth?: Float
|
|
64
|
+
borderRadius?: Float
|
|
65
|
+
padding?: Float
|
|
66
|
+
paddingHorizontal?: Float
|
|
67
|
+
paddingVertical?: Float
|
|
68
|
+
margin?: Float
|
|
69
|
+
marginHorizontal?: Float
|
|
70
|
+
marginVertical?: Float
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
interface MarkdownHeadingStyle extends MarkdownTextStyle {
|
|
74
|
+
// Each level down multiplies the one above, so level N is
|
|
75
|
+
// fontSize * scale^(N - 1). Six levels, matching HTML.
|
|
76
|
+
scale?: Float
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// The bar beside a quoted block, the indent it opens, and the text inside it.
|
|
80
|
+
//
|
|
81
|
+
// `marginStart` and `paddingStart` rather than `marginLeft`/`paddingLeft`
|
|
82
|
+
// because the gutter opens on the line's leading edge, which is the right-hand
|
|
83
|
+
// side of a right-to-left paragraph. Both platforms already indent from the
|
|
84
|
+
// leading edge -- `NSParagraphStyle`'s head indent and Android's leading margin
|
|
85
|
+
// are both writing-direction relative -- so the names now say what was always
|
|
86
|
+
// drawn, and the web builder resolves them to `padding-inline-start`.
|
|
87
|
+
interface MarkdownBlockquoteStyle extends MarkdownTextStyle {
|
|
88
|
+
borderColor?: ColorValue
|
|
89
|
+
borderWidth?: Float
|
|
90
|
+
// Rounds the bar's ends. A bar whose radius is half its width comes out a
|
|
91
|
+
// capsule.
|
|
92
|
+
borderRadius?: Float
|
|
93
|
+
marginStart?: Float
|
|
94
|
+
paddingStart?: Float
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Indent, and the marker that sits in the gutter it opens. Kept as two separate
|
|
98
|
+
// entries so a renderer can style ordered and unordered lists differently, which
|
|
99
|
+
// is exactly what `markerScale` ends up meaning: an ordered item's number is
|
|
100
|
+
// text, an unordered item's bullet is a shape.
|
|
101
|
+
//
|
|
102
|
+
// Both markers are sized from the base font -- the size the wrapped `Text`
|
|
103
|
+
// renders at -- rather than from a size of their own, so a list marks itself in
|
|
104
|
+
// proportion to the prose it marks however that prose is sized. `marker` styles
|
|
105
|
+
// the marker itself, and what it leaves unset falls back to `syntax`, which is
|
|
106
|
+
// where a marker's colour came from before this entry existed.
|
|
107
|
+
//
|
|
108
|
+
// Only `MarkdownText` draws them. An input shows the marker you typed, in the
|
|
109
|
+
// base font, because it is text you are editing rather than a rendering of it.
|
|
110
|
+
interface MarkdownListStyle {
|
|
111
|
+
marginStart?: Float
|
|
112
|
+
paddingStart?: Float
|
|
113
|
+
// An ordered item's number is drawn at this fraction of the base font size; an
|
|
114
|
+
// unordered item's bullet takes it as a diameter, as a fraction of the same.
|
|
115
|
+
markerScale?: Float
|
|
116
|
+
// Room held open either side of the marker, between the gutter and the text.
|
|
117
|
+
markerPadding?: Float
|
|
118
|
+
marker?: MarkdownTextStyle
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Left as the two values it always was rather than folded into
|
|
122
|
+
// `MarkdownTextStyle`: an emoji run is swapped onto a font that has the glyph
|
|
123
|
+
// and sized to sit with the prose, and nothing else about it is worth saying.
|
|
124
|
+
interface MarkdownEmojiStyle {
|
|
125
|
+
fontSize?: Float
|
|
126
|
+
fontFamily?: string
|
|
14
127
|
}
|
|
15
128
|
|
|
16
129
|
interface MarkdownStyle {
|
|
17
|
-
syntax:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
blockquote: {
|
|
34
|
-
borderColor: ColorValue
|
|
35
|
-
borderWidth: Float
|
|
36
|
-
marginLeft: Float
|
|
37
|
-
paddingLeft: Float
|
|
38
|
-
}
|
|
39
|
-
// Indent only, no gutter decoration. Kept as two separate entries so a
|
|
40
|
-
// renderer can style ordered and unordered lists differently.
|
|
41
|
-
orderedList: {
|
|
42
|
-
marginLeft: Float
|
|
43
|
-
paddingLeft: Float
|
|
44
|
-
}
|
|
45
|
-
unorderedList: {
|
|
46
|
-
marginLeft: Float
|
|
47
|
-
paddingLeft: Float
|
|
48
|
-
}
|
|
49
|
-
code: CodeBlockStyle
|
|
50
|
-
pre: CodeBlockStyle
|
|
51
|
-
mentionHere: {
|
|
52
|
-
color: ColorValue
|
|
53
|
-
backgroundColor: ColorValue
|
|
54
|
-
borderRadius?: Float
|
|
55
|
-
}
|
|
56
|
-
mentionUser: {
|
|
57
|
-
color: ColorValue
|
|
58
|
-
backgroundColor: ColorValue
|
|
59
|
-
borderRadius?: Float
|
|
60
|
-
}
|
|
61
|
-
mentionReport: {
|
|
62
|
-
color: ColorValue
|
|
63
|
-
backgroundColor: ColorValue
|
|
64
|
-
borderRadius?: Float
|
|
65
|
-
}
|
|
130
|
+
syntax: MarkdownTextStyle
|
|
131
|
+
emoji: MarkdownEmojiStyle
|
|
132
|
+
link: MarkdownTextStyle
|
|
133
|
+
strong: MarkdownTextStyle
|
|
134
|
+
emphasis: MarkdownTextStyle
|
|
135
|
+
strikethrough: MarkdownTextStyle
|
|
136
|
+
heading: MarkdownHeadingStyle
|
|
137
|
+
blockquote: MarkdownBlockquoteStyle
|
|
138
|
+
orderedList: MarkdownListStyle
|
|
139
|
+
unorderedList: MarkdownListStyle
|
|
140
|
+
code: MarkdownBoxStyle
|
|
141
|
+
pre: MarkdownBoxStyle
|
|
142
|
+
// A name with an `@` in front of it, drawn as a pill: the same inline box an
|
|
143
|
+
// inline run of code sits in, and so the same lengths.
|
|
144
|
+
mention: MarkdownBoxStyle
|
|
66
145
|
}
|
|
67
146
|
|
|
68
147
|
interface NativeProps extends ViewProps {
|
|
@@ -74,4 +153,12 @@ export default codegenNativeComponent<NativeProps>("MarcusTextInputDecoratorView
|
|
|
74
153
|
interfaceOnly: true,
|
|
75
154
|
})
|
|
76
155
|
|
|
77
|
-
export type {
|
|
156
|
+
export type {
|
|
157
|
+
MarkdownStyle,
|
|
158
|
+
MarkdownTextStyle,
|
|
159
|
+
MarkdownEmojiStyle,
|
|
160
|
+
MarkdownBoxStyle,
|
|
161
|
+
MarkdownHeadingStyle,
|
|
162
|
+
MarkdownBlockquoteStyle,
|
|
163
|
+
MarkdownListStyle,
|
|
164
|
+
}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { StyleSheet, Text, View } from "react-native";
|
|
4
|
+
import React from "react";
|
|
5
|
+
import MarcusTextDecoratorViewNativeComponent from "./MarcusTextDecoratorViewNativeComponent";
|
|
6
|
+
import { processMarkdownStyle } from "./styleUtils.js";
|
|
7
|
+
import { stripSyntax } from "./stripUtils.js";
|
|
8
|
+
import { atomsOf, describeAtoms, sourceOf } from "./atomUtils.js";
|
|
9
|
+
import { available as mathAvailable, renderMath, speakMath } from "./math/index.js";
|
|
10
|
+
import { flattenText } from "./childrenUtils.js";
|
|
11
|
+
import { createParser } from "./parser/index.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* What to show in place of an image.
|
|
15
|
+
*
|
|
16
|
+
* Must return a single view with a definite width and height, or nothing: the
|
|
17
|
+
* text layout has to know how much room to leave before it can lay the line
|
|
18
|
+
* out, and markdown carries no dimensions. Anything that reports no size --
|
|
19
|
+
* a bare `Image` with a remote source, most obviously -- measures zero and
|
|
20
|
+
* disappears.
|
|
21
|
+
*
|
|
22
|
+
* The alt text is passed through rather than used: what it is good for, an
|
|
23
|
+
* accessibility label most of all, is a question only the caller can answer.
|
|
24
|
+
*
|
|
25
|
+
* `inline` says whether the image shares its line with anything else, which is
|
|
26
|
+
* usually what decides how big it should be: alone on a line it is a figure,
|
|
27
|
+
* and in the middle of a sentence it is a badge. A block marker does not count
|
|
28
|
+
* as company, and another image does.
|
|
29
|
+
*
|
|
30
|
+
* Every string is always a string: an image written without a title is handed
|
|
31
|
+
* an empty one rather than nothing, so a caller never has to tell the two
|
|
32
|
+
* apart.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* What to draw an SVG with.
|
|
37
|
+
*
|
|
38
|
+
* Handed a complete SVG document and the box it belongs in, and expected to
|
|
39
|
+
* return a view of exactly that size. There is deliberately nothing else in the
|
|
40
|
+
* signature: everything a picture needs -- the colour, the glyph outlines, the
|
|
41
|
+
* baseline it sits on -- is either inside the XML already or has been taken
|
|
42
|
+
* care of by the time this is called, so `<SvgXml xml={xml} width={width}
|
|
43
|
+
* height={height} />` is the whole of a correct implementation.
|
|
44
|
+
*
|
|
45
|
+
* It exists because a renderer for SVG is a dependency, and which one is not
|
|
46
|
+
* this library's business: `react-native-svg` on native, whatever you like on
|
|
47
|
+
* the web.
|
|
48
|
+
*
|
|
49
|
+
* Returning nothing leaves the drawing out, and the span it stood for still
|
|
50
|
+
* costs its one character either way.
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* What to do when a link is pressed.
|
|
55
|
+
*
|
|
56
|
+
* The label is the text the link was rendered as, which is all a reader saw of
|
|
57
|
+
* it: the destination is not in the document any more. Reference links are not
|
|
58
|
+
* covered -- their destination is written somewhere else and is not resolved
|
|
59
|
+
* yet -- so they render as links and do nothing.
|
|
60
|
+
*
|
|
61
|
+
* Opening the URL is deliberately not done for you: what a link means is the
|
|
62
|
+
* application's to decide, and a message from a stranger is the last place to
|
|
63
|
+
* hand an arbitrary URL to `Linking.openURL` without looking at it first.
|
|
64
|
+
*
|
|
65
|
+
* Every string is always a string: a link written without a title is handed an
|
|
66
|
+
* empty one rather than nothing.
|
|
67
|
+
*/
|
|
68
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
69
|
+
/**
|
|
70
|
+
* The stripped text with the embeds spliced back in and the links wrapped, as
|
|
71
|
+
* the children of one `Text`.
|
|
72
|
+
*
|
|
73
|
+
* A view nested in a `Text` is one character to the platform -- iOS and Android
|
|
74
|
+
* both put a single U+FFFC in the string their formatters index -- and it is
|
|
75
|
+
* the very character the strip left behind, so the ranges need no adjusting and
|
|
76
|
+
* an embed inside a blockquote is laid out inside the quote's indent by the
|
|
77
|
+
* same code that indents the prose around it.
|
|
78
|
+
*
|
|
79
|
+
* A nested `Text` costs no characters at all: its content goes into that same
|
|
80
|
+
* string where it stands. So a link can be wrapped in one to be pressed without
|
|
81
|
+
* moving anything either, and the decorator styles it through the ranges the
|
|
82
|
+
* way it styles a link nobody can press.
|
|
83
|
+
*/
|
|
84
|
+
function textChildren(markdown, renderEmbed, renderSVG, fontSize, color, locale, onLinkPress) {
|
|
85
|
+
const {
|
|
86
|
+
text,
|
|
87
|
+
links
|
|
88
|
+
} = markdown;
|
|
89
|
+
const children = [];
|
|
90
|
+
const atoms = atomsOf(markdown);
|
|
91
|
+
// Atoms are in text order and each is used once, whether it falls inside a
|
|
92
|
+
// link or between two, so one walk covers both.
|
|
93
|
+
let next = 0;
|
|
94
|
+
|
|
95
|
+
/** What stands where one placeholder character is. */
|
|
96
|
+
function draw(atom) {
|
|
97
|
+
if (atom.kind === "embed") {
|
|
98
|
+
return renderEmbed?.(atom.uri, atom.alt, atom.title, atom.inline);
|
|
99
|
+
}
|
|
100
|
+
const drawn = renderMath(atom.tex, atom.display, fontSize, color);
|
|
101
|
+
if (drawn === null) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
const element = renderSVG?.(drawn.svg, drawn.width, drawn.height);
|
|
105
|
+
if (!element) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Wrapped rather than cloned: what came back is the caller's element and
|
|
110
|
+
// its own props are not ours to rewrite.
|
|
111
|
+
//
|
|
112
|
+
// The wrapper does two things. It carries the label -- what the picture
|
|
113
|
+
// says, read out the way a screen reader reads maths on the web, because a
|
|
114
|
+
// drawing is the one thing in a document that cannot be read for itself.
|
|
115
|
+
// And it shifts the picture down by its depth -- both platforms put the
|
|
116
|
+
// *bottom* edge of a view mounted in a `Text` on the baseline, so without
|
|
117
|
+
// this a fraction floats above the line. The shift happens after
|
|
118
|
+
// measurement, so the line keeps the height the maths asked for.
|
|
119
|
+
return /*#__PURE__*/_jsx(View, {
|
|
120
|
+
accessible: true,
|
|
121
|
+
accessibilityLabel: speakMath(atom.tex, atom.display, locale) ?? atom.tex,
|
|
122
|
+
style: drawn.depth ? {
|
|
123
|
+
transform: [{
|
|
124
|
+
translateY: drawn.depth
|
|
125
|
+
}]
|
|
126
|
+
} : undefined,
|
|
127
|
+
children: element
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** The text between two offsets, with any atoms in it spliced in. */
|
|
132
|
+
function content(from, to) {
|
|
133
|
+
const between = [];
|
|
134
|
+
let cursor = from;
|
|
135
|
+
while (next < atoms.length && atoms[next].index < to) {
|
|
136
|
+
const atom = atoms[next];
|
|
137
|
+
if (atom.index > cursor) {
|
|
138
|
+
between.push(text.slice(cursor, atom.index));
|
|
139
|
+
}
|
|
140
|
+
between.push(/*#__PURE__*/_jsx(React.Fragment, {
|
|
141
|
+
children: draw(atom) ?? /*#__PURE__*/_jsx(View, {})
|
|
142
|
+
}, `atom-${atom.index}`));
|
|
143
|
+
cursor = atom.index + 1;
|
|
144
|
+
next++;
|
|
145
|
+
}
|
|
146
|
+
if (cursor < to) {
|
|
147
|
+
between.push(text.slice(cursor, to));
|
|
148
|
+
}
|
|
149
|
+
return between;
|
|
150
|
+
}
|
|
151
|
+
let cursor = 0;
|
|
152
|
+
for (const link of links) {
|
|
153
|
+
if (link.start > cursor) {
|
|
154
|
+
children.push(...content(cursor, link.start));
|
|
155
|
+
}
|
|
156
|
+
const end = link.start + link.length;
|
|
157
|
+
children.push(/*#__PURE__*/_jsx(Text, {
|
|
158
|
+
role: "link",
|
|
159
|
+
onPress: () => onLinkPress.current?.(link.uri, link.label, link.title),
|
|
160
|
+
children: content(link.start, end)
|
|
161
|
+
}, `link-${link.start}`));
|
|
162
|
+
cursor = end;
|
|
163
|
+
}
|
|
164
|
+
children.push(...content(cursor, text.length));
|
|
165
|
+
return children;
|
|
166
|
+
}
|
|
167
|
+
const EMPTY_RANGES = [];
|
|
168
|
+
const NO_SUBSTITUTIONS = [];
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* What maths is sized against when the caller set no size at all, which is
|
|
172
|
+
* React Native's own default for a `Text`.
|
|
173
|
+
*/
|
|
174
|
+
const DEFAULT_FONT_SIZE = 14;
|
|
175
|
+
function toRangeStructs(ranges) {
|
|
176
|
+
return ranges.map(range => ({
|
|
177
|
+
type: range.type,
|
|
178
|
+
start: range.start,
|
|
179
|
+
length: range.length,
|
|
180
|
+
depth: range.depth ?? 0
|
|
181
|
+
}));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* `Text`, with the markdown in its content rendered rather than shown.
|
|
186
|
+
*
|
|
187
|
+
* The syntax is removed in JavaScript before the text ever reaches the shadow
|
|
188
|
+
* tree, so what gets measured, drawn, selected, copied and read out is the
|
|
189
|
+
* finished prose. What is left over -- which run is bold, where a quote starts
|
|
190
|
+
* -- is handed to the native decorator as ranges over that stripped string, and
|
|
191
|
+
* styled by the same formatter the input uses, so a message and the composer it
|
|
192
|
+
* was typed in agree by construction.
|
|
193
|
+
*
|
|
194
|
+
* List markers are the exception that stays: `1.` numbers an item and `-`
|
|
195
|
+
* stands in for a bullet, so they are laid out rather than removed.
|
|
196
|
+
*/
|
|
197
|
+
const MarkdownText = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
198
|
+
const {
|
|
199
|
+
markdownStyle: markdownStyleProp,
|
|
200
|
+
gfm,
|
|
201
|
+
mention,
|
|
202
|
+
math,
|
|
203
|
+
renderEmbed,
|
|
204
|
+
renderSVG,
|
|
205
|
+
mathAccessibilityLocale,
|
|
206
|
+
onLinkPress,
|
|
207
|
+
children,
|
|
208
|
+
...textProps
|
|
209
|
+
} = props;
|
|
210
|
+
const markdownStyle = React.useMemo(() => processMarkdownStyle(markdownStyleProp), [markdownStyleProp]);
|
|
211
|
+
|
|
212
|
+
// Whether there is a handler, not which one: a caller who writes the callback
|
|
213
|
+
// inline would otherwise re-parse the document on every render.
|
|
214
|
+
const withEmbeds = renderEmbed !== undefined;
|
|
215
|
+
// Maths is only taken out of the text when there is both something to draw it
|
|
216
|
+
// with and a backend to typeset it -- see `./math`. Left in, `$$x^2$$` is
|
|
217
|
+
// shown as it was written, which beats an empty box where an equation should
|
|
218
|
+
// be and is the one hint an application gets that its Metro config is a line
|
|
219
|
+
// short.
|
|
220
|
+
const withMath = renderSVG !== undefined && mathAvailable;
|
|
221
|
+
const withLinks = onLinkPress !== undefined;
|
|
222
|
+
|
|
223
|
+
// The same worklet for as long as the flavour is the same one, so the
|
|
224
|
+
// document is only re-parsed when the document itself changes.
|
|
225
|
+
const parser = createParser({
|
|
226
|
+
gfm,
|
|
227
|
+
mention,
|
|
228
|
+
math
|
|
229
|
+
});
|
|
230
|
+
const markdown = React.useMemo(() => {
|
|
231
|
+
const text = flattenText(children);
|
|
232
|
+
return text === null ? null : stripSyntax(text, parser(text), {
|
|
233
|
+
embeds: withEmbeds,
|
|
234
|
+
math: withMath,
|
|
235
|
+
links: withLinks
|
|
236
|
+
});
|
|
237
|
+
}, [children, parser, withEmbeds, withMath, withLinks]);
|
|
238
|
+
|
|
239
|
+
// What the maths has to be sized against. Read off the style the caller gave
|
|
240
|
+
// this element, because that is the only size known here -- a size inherited
|
|
241
|
+
// from an enclosing `Text` is resolved by the platform, long after this.
|
|
242
|
+
const {
|
|
243
|
+
fontSize,
|
|
244
|
+
color
|
|
245
|
+
} = React.useMemo(() => {
|
|
246
|
+
const flattened = StyleSheet.flatten(textProps.style);
|
|
247
|
+
return {
|
|
248
|
+
fontSize: typeof flattened?.fontSize === "number" ? flattened.fontSize : DEFAULT_FONT_SIZE,
|
|
249
|
+
// MathJax paints in `currentColor`, and a view mounted in a `Text`
|
|
250
|
+
// inherits none of its text attributes on either platform, so the colour
|
|
251
|
+
// is painted into the SVG before it is handed over. Left unset, maths is
|
|
252
|
+
// drawn in whatever the SVG renderer makes of `currentColor` -- so a
|
|
253
|
+
// display that means to be readable in the dark should say what colour it
|
|
254
|
+
// is, which it had to do for its own text anyway.
|
|
255
|
+
color: typeof flattened?.color === "string" ? flattened.color : undefined
|
|
256
|
+
};
|
|
257
|
+
}, [textProps.style]);
|
|
258
|
+
|
|
259
|
+
// The handler as the caller last wrote it, kept beside the text rather than
|
|
260
|
+
// baked into it. Written inline -- which is how a handler that reaches for
|
|
261
|
+
// component state has to be written -- it is a different function on every
|
|
262
|
+
// render, and rebuilding the children for each press means rebuilding the
|
|
263
|
+
// string the platform lays out, on the main thread, for every press.
|
|
264
|
+
const pressHandler = React.useRef(onLinkPress);
|
|
265
|
+
React.useEffect(() => {
|
|
266
|
+
pressHandler.current = onLinkPress;
|
|
267
|
+
}, [onLinkPress]);
|
|
268
|
+
|
|
269
|
+
// Rebuilt when the document changes, or when a caller hands over a different
|
|
270
|
+
// renderer -- one that draws from state has to be able to draw again.
|
|
271
|
+
const spliced = React.useMemo(() => markdown === null || markdown.embeds.length === 0 && markdown.maths.length === 0 && markdown.links.length === 0 ? null : textChildren(markdown, renderEmbed, renderSVG, fontSize, color, mathAccessibilityLocale, pressHandler), [markdown, renderEmbed, renderSVG, fontSize, color, mathAccessibilityLocale]);
|
|
272
|
+
|
|
273
|
+
// What the paragraph reads as. A drawing is one U+FFFC in the string the
|
|
274
|
+
// platform lays out -- that is what a view nested in a `Text` costs -- and
|
|
275
|
+
// there is nothing in that character for a screen reader to say, so the whole
|
|
276
|
+
// paragraph is described instead with each placeholder written back out as
|
|
277
|
+
// the alt text or the spoken form of the equation it stands for. Only when
|
|
278
|
+
// the caller has not described it themselves, and only when there is
|
|
279
|
+
// something to describe.
|
|
280
|
+
const accessibilityLabel = React.useMemo(() => textProps.accessibilityLabel ?? (markdown === null || markdown.embeds.length === 0 && markdown.maths.length === 0 ? undefined : describeAtoms(markdown, speakMath, mathAccessibilityLocale)), [markdown, textProps.accessibilityLabel, mathAccessibilityLocale]);
|
|
281
|
+
|
|
282
|
+
// What each of those placeholders copies as, which is the markdown it was
|
|
283
|
+
// written as. Handed to the decorator rather than used here: the copy is the
|
|
284
|
+
// platform's, made from the string it laid out, and only the platform can
|
|
285
|
+
// catch it -- Android at the moment the action mode's copy is pressed, iOS
|
|
286
|
+
// when the paragraph is asked for its own `copy:`.
|
|
287
|
+
const substitutions = React.useMemo(() => markdown === null || markdown.embeds.length === 0 && markdown.maths.length === 0 ? NO_SUBSTITUTIONS : atomsOf(markdown).map(atom => ({
|
|
288
|
+
index: atom.index,
|
|
289
|
+
text: sourceOf(atom)
|
|
290
|
+
})), [markdown]);
|
|
291
|
+
|
|
292
|
+
// The same array while the document is the same one: a new one is a new props
|
|
293
|
+
// object to the mounting layer, and every press that a caller answers with a
|
|
294
|
+
// `setState` would otherwise have the decorator format the paragraph again.
|
|
295
|
+
const ranges = React.useMemo(() => markdown === null ? EMPTY_RANGES : toRangeStructs(markdown.ranges), [markdown]);
|
|
296
|
+
if (markdown === null) {
|
|
297
|
+
if (__DEV__) {
|
|
298
|
+
console.warn("[react-native-marcus] `MarkdownText` was given children other than text and is rendering them unformatted.");
|
|
299
|
+
}
|
|
300
|
+
return /*#__PURE__*/_jsx(Text, {
|
|
301
|
+
...textProps,
|
|
302
|
+
ref: ref,
|
|
303
|
+
children: children
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
return /*#__PURE__*/_jsx(MarcusTextDecoratorViewNativeComponent, {
|
|
307
|
+
style: styles.displayContents,
|
|
308
|
+
markdownStyle: markdownStyle,
|
|
309
|
+
ranges: ranges,
|
|
310
|
+
substitutions: substitutions,
|
|
311
|
+
children: /*#__PURE__*/_jsx(Text, {
|
|
312
|
+
...textProps,
|
|
313
|
+
accessibilityLabel: accessibilityLabel,
|
|
314
|
+
ref: ref,
|
|
315
|
+
children: spliced ?? markdown.text
|
|
316
|
+
})
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
const styles = StyleSheet.create({
|
|
320
|
+
displayContents: {
|
|
321
|
+
display: "contents"
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
export default MarkdownText;
|
|
325
|
+
//# sourceMappingURL=MarkdownText.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["StyleSheet","Text","View","React","MarcusTextDecoratorViewNativeComponent","processMarkdownStyle","stripSyntax","atomsOf","describeAtoms","sourceOf","available","mathAvailable","renderMath","speakMath","flattenText","createParser","jsx","_jsx","textChildren","markdown","renderEmbed","renderSVG","fontSize","color","locale","onLinkPress","text","links","children","atoms","next","draw","atom","kind","uri","alt","title","inline","drawn","tex","display","element","svg","width","height","accessible","accessibilityLabel","style","depth","transform","translateY","undefined","content","from","to","between","cursor","length","index","push","slice","Fragment","link","start","end","role","onPress","current","label","EMPTY_RANGES","NO_SUBSTITUTIONS","DEFAULT_FONT_SIZE","toRangeStructs","ranges","map","range","type","MarkdownText","forwardRef","props","ref","markdownStyle","markdownStyleProp","gfm","mention","math","mathAccessibilityLocale","textProps","useMemo","withEmbeds","withMath","withLinks","parser","embeds","flattened","flatten","pressHandler","useRef","useEffect","spliced","maths","substitutions","__DEV__","console","warn","styles","displayContents","create"],"sourceRoot":"../../src","sources":["MarkdownText.tsx"],"mappings":"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","ignoreList":[]}
|