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
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { StyleSheet, TextInput
|
|
1
|
+
import { StyleSheet, TextInput } from "react-native"
|
|
2
2
|
import React from "react"
|
|
3
3
|
import type { TextInputProps } from "react-native"
|
|
4
4
|
import { createSerializable, createWorkletRuntime } from "react-native-worklets"
|
|
5
5
|
import type { SerializableRef, WorkletFunction, WorkletRuntime } from "react-native-worklets"
|
|
6
6
|
import MarcusTextInputDecoratorViewNativeComponent from "./MarcusTextInputDecoratorViewNativeComponent"
|
|
7
|
-
import type { MarkdownStyle } from "./MarcusTextInputDecoratorViewNativeComponent"
|
|
8
7
|
import NativeMarcusModule from "./NativeMarcusModule"
|
|
9
|
-
import {
|
|
8
|
+
import { processMarkdownStyle } from "./styleUtils"
|
|
10
9
|
import type { PartialMarkdownStyle } from "./styleUtils"
|
|
11
|
-
import
|
|
10
|
+
import { createParser } from "./parser"
|
|
11
|
+
import type { MarkdownParser, MarkdownRange } from "./commonTypes"
|
|
12
12
|
|
|
13
13
|
declare global {
|
|
14
14
|
// eslint-disable-next-line no-var
|
|
@@ -48,7 +48,7 @@ function initializeMarcusIfNeeded() {
|
|
|
48
48
|
initialized = true
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
function registerParser(parser:
|
|
51
|
+
function registerParser(parser: MarkdownParser): number {
|
|
52
52
|
initializeMarcusIfNeeded()
|
|
53
53
|
const serializableWorklet = createSerializable(
|
|
54
54
|
parser as WorkletFunction<[string], MarkdownRange[]>,
|
|
@@ -63,52 +63,56 @@ function unregisterParser(parserId: number) {
|
|
|
63
63
|
|
|
64
64
|
interface MarkdownTextInputProps extends TextInputProps {
|
|
65
65
|
markdownStyle?: PartialMarkdownStyle
|
|
66
|
-
|
|
66
|
+
/**
|
|
67
|
+
* GFM's strikethrough (`~~a~~`) and bare autolinks (`www.example.com`).
|
|
68
|
+
*
|
|
69
|
+
* @default false
|
|
70
|
+
*/
|
|
71
|
+
gfm?: boolean
|
|
72
|
+
/**
|
|
73
|
+
* `@name` mentions, which no flavour of markdown has a notion of.
|
|
74
|
+
*
|
|
75
|
+
* @default false
|
|
76
|
+
*/
|
|
77
|
+
mention?: boolean
|
|
78
|
+
/**
|
|
79
|
+
* LaTeX between double dollar signs: `$$x^2$$` inline, and the same on lines
|
|
80
|
+
* of its own for a block.
|
|
81
|
+
*
|
|
82
|
+
* An input shows what was typed, so the maths stays as written -- what this
|
|
83
|
+
* turns on is recognising it, which greys the dollars as the markup they are
|
|
84
|
+
* and leaves the TeX between them alone.
|
|
85
|
+
*
|
|
86
|
+
* @default false
|
|
87
|
+
*/
|
|
88
|
+
math?: boolean
|
|
67
89
|
}
|
|
68
90
|
|
|
69
91
|
type MarkdownTextInput = TextInput & React.Component<MarkdownTextInputProps>
|
|
70
92
|
|
|
71
|
-
function processColorsInMarkdownStyle(input: MarkdownStyle): MarkdownStyle {
|
|
72
|
-
const output = JSON.parse(JSON.stringify(input))
|
|
73
|
-
|
|
74
|
-
Object.keys(output).forEach((key) => {
|
|
75
|
-
const obj = output[key]
|
|
76
|
-
Object.keys(obj).forEach((prop) => {
|
|
77
|
-
// TODO: use ReactNativeStyleAttributes from 'react-native/Libraries/Components/View/ReactNativeStyleAttributes'
|
|
78
|
-
if (!(prop === "color" || prop.endsWith("Color"))) {
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
obj[prop] = processColor(obj[prop])
|
|
82
|
-
})
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
return output as MarkdownStyle
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function processMarkdownStyle(input: PartialMarkdownStyle | undefined): MarkdownStyle {
|
|
89
|
-
return processColorsInMarkdownStyle(mergeMarkdownStyleWithDefault(input))
|
|
90
|
-
}
|
|
91
|
-
|
|
92
93
|
const MarkdownTextInput = React.forwardRef<MarkdownTextInput, MarkdownTextInputProps>(
|
|
93
94
|
(props, ref) => {
|
|
95
|
+
const { markdownStyle: markdownStyleProp, gfm, mention, math, ...textInputProps } = props
|
|
96
|
+
|
|
94
97
|
const markdownStyle = React.useMemo(
|
|
95
|
-
() => processMarkdownStyle(
|
|
96
|
-
[
|
|
98
|
+
() => processMarkdownStyle(markdownStyleProp),
|
|
99
|
+
[markdownStyleProp],
|
|
97
100
|
)
|
|
98
101
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
+
// The same worklet for as long as the flavour is the same one, so the id
|
|
103
|
+
// below is registered once and the native side keeps the parser it has.
|
|
104
|
+
const parser = createParser({ gfm, mention, math })
|
|
102
105
|
|
|
103
106
|
// eslint-disable-next-line no-underscore-dangle
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
+
if ((parser as { __workletHash?: number }).__workletHash === undefined) {
|
|
108
|
+
throw new Error(
|
|
109
|
+
"[react-native-marcus] the parser is not a worklet. Add `react-native-worklets/plugin` to the project's Babel config.",
|
|
110
|
+
)
|
|
107
111
|
}
|
|
108
112
|
|
|
109
113
|
const parserId = React.useMemo(() => {
|
|
110
|
-
return registerParser(
|
|
111
|
-
}, [
|
|
114
|
+
return registerParser(parser)
|
|
115
|
+
}, [parser])
|
|
112
116
|
|
|
113
117
|
React.useEffect(() => {
|
|
114
118
|
return () => unregisterParser(parserId)
|
|
@@ -120,7 +124,7 @@ const MarkdownTextInput = React.forwardRef<MarkdownTextInput, MarkdownTextInputP
|
|
|
120
124
|
markdownStyle={markdownStyle}
|
|
121
125
|
parserId={parserId}
|
|
122
126
|
>
|
|
123
|
-
<TextInput {...
|
|
127
|
+
<TextInput {...textInputProps} ref={ref} />
|
|
124
128
|
</MarcusTextInputDecoratorViewNativeComponent>
|
|
125
129
|
)
|
|
126
130
|
},
|
|
@@ -33,8 +33,9 @@ import {
|
|
|
33
33
|
removeSelection,
|
|
34
34
|
setCursorPosition,
|
|
35
35
|
} from "./web/utils/cursorUtils"
|
|
36
|
+
import "./web/MarkdownElements.css"
|
|
36
37
|
import "./web/MarkdownTextInput.css"
|
|
37
|
-
import type {
|
|
38
|
+
import type { PartialMarkdownStyle, ResolvedMarkdownStyle } from "./styleUtils"
|
|
38
39
|
import {
|
|
39
40
|
getElementHeight,
|
|
40
41
|
getPlaceholderValue,
|
|
@@ -47,13 +48,36 @@ import {
|
|
|
47
48
|
parseToReactDOMStyle,
|
|
48
49
|
processMarkdownStyle,
|
|
49
50
|
} from "./web/utils/webStyleUtils"
|
|
50
|
-
import
|
|
51
|
+
import { createParser } from "./parser"
|
|
52
|
+
import type { MarkdownParser } from "./commonTypes"
|
|
51
53
|
|
|
52
54
|
const useClientEffect = typeof window === "undefined" ? useEffect : useLayoutEffect
|
|
53
55
|
|
|
54
56
|
interface MarkdownTextInputProps extends TextInputProps {
|
|
55
|
-
markdownStyle?:
|
|
56
|
-
|
|
57
|
+
markdownStyle?: PartialMarkdownStyle
|
|
58
|
+
/**
|
|
59
|
+
* GFM's strikethrough (`~~a~~`) and bare autolinks (`www.example.com`).
|
|
60
|
+
*
|
|
61
|
+
* @default false
|
|
62
|
+
*/
|
|
63
|
+
gfm?: boolean
|
|
64
|
+
/**
|
|
65
|
+
* `@name` mentions, which no flavour of markdown has a notion of.
|
|
66
|
+
*
|
|
67
|
+
* @default false
|
|
68
|
+
*/
|
|
69
|
+
mention?: boolean
|
|
70
|
+
/**
|
|
71
|
+
* LaTeX between double dollar signs: `$$x^2$$` inline, and the same on lines
|
|
72
|
+
* of its own for a block.
|
|
73
|
+
*
|
|
74
|
+
* An input shows what was typed, so the maths stays as written -- what this
|
|
75
|
+
* turns on is recognising it, which greys the dollars as the markup they are
|
|
76
|
+
* and leaves the TeX between them alone.
|
|
77
|
+
*
|
|
78
|
+
* @default false
|
|
79
|
+
*/
|
|
80
|
+
math?: boolean
|
|
57
81
|
onClick?: (e: MouseEvent<HTMLDivElement>) => void
|
|
58
82
|
dir?: string
|
|
59
83
|
disabled?: boolean
|
|
@@ -114,7 +138,9 @@ const MarkdownTextInput = React.forwardRef<MarkdownTextInput, MarkdownTextInputP
|
|
|
114
138
|
numberOfLines,
|
|
115
139
|
multiline = false,
|
|
116
140
|
markdownStyle,
|
|
117
|
-
|
|
141
|
+
gfm,
|
|
142
|
+
mention,
|
|
143
|
+
math,
|
|
118
144
|
onBlur,
|
|
119
145
|
onChange,
|
|
120
146
|
onChangeText,
|
|
@@ -139,12 +165,9 @@ const MarkdownTextInput = React.forwardRef<MarkdownTextInput, MarkdownTextInputP
|
|
|
139
165
|
},
|
|
140
166
|
ref,
|
|
141
167
|
) => {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
if (typeof parser !== "function") {
|
|
146
|
-
throw new Error("[react-native-marcus] `parser` is not a function")
|
|
147
|
-
}
|
|
168
|
+
// The same function for as long as the flavour is the same one, so every
|
|
169
|
+
// callback below that holds on to it keeps its identity too.
|
|
170
|
+
const parser = createParser({ gfm, mention, math })
|
|
148
171
|
|
|
149
172
|
const divRef = useRef<MarkdownTextInputElement | null>(null)
|
|
150
173
|
const currentlyFocusedField = useRef<HTMLDivElement | null>(null)
|
|
@@ -185,10 +208,10 @@ const MarkdownTextInput = React.forwardRef<MarkdownTextInput, MarkdownTextInputP
|
|
|
185
208
|
|
|
186
209
|
const parseText = useCallback(
|
|
187
210
|
(
|
|
188
|
-
parserFunction:
|
|
211
|
+
parserFunction: MarkdownParser,
|
|
189
212
|
target: MarkdownTextInputElement,
|
|
190
213
|
text: string | null,
|
|
191
|
-
customMarkdownStyles:
|
|
214
|
+
customMarkdownStyles: ResolvedMarkdownStyle,
|
|
192
215
|
cursorPosition: number | null = null,
|
|
193
216
|
shouldAddToHistory = true,
|
|
194
217
|
shouldForceDOMUpdate = false,
|
package/src/atomUtils.ts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { MarkdownEmbed, MarkdownMath, StrippedMarkdown } from "./stripUtils"
|
|
2
|
+
|
|
3
|
+
// An image and a maths span are the same problem to a display: a run of
|
|
4
|
+
// markdown that is drawn rather than read, that the strip has already replaced
|
|
5
|
+
// with a single placeholder character, and that something has to be mounted
|
|
6
|
+
// over. `stripSyntax` reports them apart because what a caller needs to know
|
|
7
|
+
// about each is different; the two components need them together, in the one
|
|
8
|
+
// order the placeholders appear in.
|
|
9
|
+
|
|
10
|
+
type Atom = ({ kind: "embed" } & MarkdownEmbed) | ({ kind: "math" } & MarkdownMath)
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* How a maths span is said out loud, or nothing for one that cannot be said.
|
|
14
|
+
*
|
|
15
|
+
* Passed in rather than imported so that this module knows nothing about
|
|
16
|
+
* typesetting: it is `./math`'s `speakMath` at both call sites, and a display
|
|
17
|
+
* with no maths backend passes one that always declines.
|
|
18
|
+
*/
|
|
19
|
+
type SpeakMath = (tex: string, display: boolean, locale?: string) => string | null
|
|
20
|
+
|
|
21
|
+
const NO_ATOMS: Atom[] = []
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Every placeholder in the stripped text, in the order it stands there.
|
|
25
|
+
*
|
|
26
|
+
* Sorting is enough to interleave the two kinds correctly: each index is a
|
|
27
|
+
* distinct character in the same string, so no two atoms can share one.
|
|
28
|
+
*/
|
|
29
|
+
function atomsOf(markdown: StrippedMarkdown): Atom[] {
|
|
30
|
+
const { embeds, maths } = markdown
|
|
31
|
+
|
|
32
|
+
if (embeds.length === 0 && maths.length === 0) {
|
|
33
|
+
return NO_ATOMS
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const atoms: Atom[] = []
|
|
37
|
+
|
|
38
|
+
for (const embed of embeds) {
|
|
39
|
+
atoms.push({ kind: "embed", ...embed })
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (const math of maths) {
|
|
43
|
+
atoms.push({ kind: "math", ...math })
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return atoms.length > 1 ? atoms.sort((a, b) => a.index - b.index) : atoms
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The text as it should be read out, with every placeholder written back out
|
|
51
|
+
* as what it stands for.
|
|
52
|
+
*
|
|
53
|
+
* A drawing costs exactly one character in the string the platform lays out --
|
|
54
|
+
* U+FFFC, the object replacement character -- and there is nothing in that
|
|
55
|
+
* character for a screen reader to say. An image's `alt` is its accessible name
|
|
56
|
+
* by every spec there is, and left empty it declares the image decorative, so
|
|
57
|
+
* it is used as written. A maths span is read as what was drawn, which is what
|
|
58
|
+
* `speak` answers; the TeX behind it is the fallback, because an expression
|
|
59
|
+
* read out as its source is still better than a sentence with a hole in it.
|
|
60
|
+
*
|
|
61
|
+
* `locale` is the language the maths is said in, and is passed straight
|
|
62
|
+
* through: the prose around it is in whatever language it was written in, and
|
|
63
|
+
* nothing here can or should change that.
|
|
64
|
+
*/
|
|
65
|
+
function describeAtoms(markdown: StrippedMarkdown, speak: SpeakMath, locale?: string): string {
|
|
66
|
+
const atoms = atomsOf(markdown)
|
|
67
|
+
|
|
68
|
+
if (atoms.length === 0) {
|
|
69
|
+
return markdown.text
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let described = ""
|
|
73
|
+
let cursor = 0
|
|
74
|
+
|
|
75
|
+
for (const atom of atoms) {
|
|
76
|
+
described += markdown.text.slice(cursor, atom.index)
|
|
77
|
+
described +=
|
|
78
|
+
atom.kind === "embed" ? atom.alt : speak(atom.tex, atom.display, locale) ?? atom.tex
|
|
79
|
+
cursor = atom.index + 1
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return described + markdown.text.slice(cursor)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* What a placeholder puts on the clipboard, which is the markdown it was
|
|
87
|
+
* written as.
|
|
88
|
+
*
|
|
89
|
+
* A copy of rendered text is plain text: `**bold**` comes off the screen as
|
|
90
|
+
* "bold", because that is what a copy of styled text has always been. A drawing
|
|
91
|
+
* has no plain text at all -- it is one U+FFFC, which pastes as a box -- and
|
|
92
|
+
* the source is the only honest thing to put there. Written back out with its
|
|
93
|
+
* dollar signs, a copied paragraph is markdown again and goes back into an
|
|
94
|
+
* editor as the document it came from.
|
|
95
|
+
*
|
|
96
|
+
* An image copies as nothing, the way an `<img>` does on the web: its alt text
|
|
97
|
+
* describes the picture for someone who cannot see it, and pasting a
|
|
98
|
+
* description where a picture was is not what anyone asked for.
|
|
99
|
+
*/
|
|
100
|
+
function sourceOf(atom: Atom): string {
|
|
101
|
+
if (atom.kind === "embed") {
|
|
102
|
+
return ""
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// A display equation is written on lines of its own, and lands in the
|
|
106
|
+
// clipboard that way: pasted back, it is a display equation again.
|
|
107
|
+
return atom.display ? `$$\n${atom.tex}\n$$` : `$$${atom.tex}$$`
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export type { Atom, SpeakMath }
|
|
111
|
+
|
|
112
|
+
export { NO_ATOMS, atomsOf, describeAtoms, sourceOf }
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type React from "react"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Flattens children into the string they render as, or null if they are not
|
|
5
|
+
* text.
|
|
6
|
+
*
|
|
7
|
+
* Only strings and numbers are markdown. An element child is content there are
|
|
8
|
+
* no parser offsets for and no way to strip syntax out of, so a subtree
|
|
9
|
+
* containing one renders unformatted rather than half formatted.
|
|
10
|
+
*/
|
|
11
|
+
function flattenText(children: React.ReactNode): string | null {
|
|
12
|
+
const parts: string[] = []
|
|
13
|
+
|
|
14
|
+
return collect(children, parts) ? parts.join("") : null
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function collect(children: React.ReactNode, parts: string[]): boolean {
|
|
18
|
+
if (children === null || children === undefined || typeof children === "boolean") {
|
|
19
|
+
return true
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (typeof children === "string") {
|
|
23
|
+
parts.push(children)
|
|
24
|
+
return true
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (typeof children === "number") {
|
|
28
|
+
parts.push(String(children))
|
|
29
|
+
return true
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (Array.isArray(children)) {
|
|
33
|
+
return children.every((child) => collect(child, parts))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return false
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export { flattenText }
|
package/src/commonTypes.ts
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
type MarkdownType =
|
|
2
|
-
| "
|
|
3
|
-
| "
|
|
2
|
+
| "strong"
|
|
3
|
+
| "emphasis"
|
|
4
4
|
| "strikethrough"
|
|
5
5
|
| "emoji"
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
| "mention
|
|
6
|
+
// One type. A mention is a name with an `@` in front of it; who it names is
|
|
7
|
+
// the application's business, not the parser's, and nothing here can tell a
|
|
8
|
+
// person from a room from a report.
|
|
9
|
+
| "mention"
|
|
10
10
|
| "link"
|
|
11
|
+
// The text between a link's brackets. Its own type rather than `link`: no
|
|
12
|
+
// formatter styles it, so it stays plain while it is being edited, and only
|
|
13
|
+
// the display renderer -- which has removed the brackets -- turns it into one.
|
|
14
|
+
| "label"
|
|
15
|
+
// The text between an image's brackets. Content rather than text: CommonMark
|
|
16
|
+
// flattens it to a string only when it renders the `alt` attribute, and
|
|
17
|
+
// micromark keeps the structure, so emphasis, code, a link or another image
|
|
18
|
+
// nested in there all arrive as ranges of their own inside this one.
|
|
19
|
+
| "alt"
|
|
20
|
+
// The title a link or image carries after its destination. Metadata rather
|
|
21
|
+
// than content: no formatter styles it, and a display renderer removes it
|
|
22
|
+
// along with the destination it belongs to.
|
|
23
|
+
| "title"
|
|
11
24
|
| "code"
|
|
12
25
|
| "pre"
|
|
13
26
|
| "blockquote"
|
|
@@ -16,15 +29,62 @@ type MarkdownType =
|
|
|
16
29
|
| "block-prefix"
|
|
17
30
|
| "heading"
|
|
18
31
|
| "syntax"
|
|
19
|
-
| "
|
|
32
|
+
| "image"
|
|
20
33
|
| "codeblock"
|
|
34
|
+
// An inline `$$...$$` span, delimiters and all. One range over the whole
|
|
35
|
+
// thing rather than one over its content: what is between the dollars is TeX,
|
|
36
|
+
// not markdown, and nothing downstream has any business styling parts of it.
|
|
37
|
+
| "math"
|
|
38
|
+
// A `$$` block, which is the same thing set on lines of its own.
|
|
39
|
+
| "math-block"
|
|
40
|
+
// The language a fenced block declares. Metadata rather than content: no
|
|
41
|
+
// formatter styles it and the display renderer removes it outright.
|
|
42
|
+
| "language"
|
|
21
43
|
|
|
22
44
|
interface MarkdownRange {
|
|
23
45
|
type: MarkdownType
|
|
24
46
|
start: number
|
|
25
47
|
length: number
|
|
26
48
|
depth?: number
|
|
27
|
-
syntaxType?: "opening" | "closing"
|
|
28
49
|
}
|
|
29
50
|
|
|
30
|
-
|
|
51
|
+
/**
|
|
52
|
+
* What the parser recognises beyond CommonMark.
|
|
53
|
+
*
|
|
54
|
+
* Every one of them is off unless it is asked for. Each changes what an
|
|
55
|
+
* ordinary character means -- a tilde, an `@`, a dollar sign -- and a document
|
|
56
|
+
* written somewhere else, by someone who never heard of this library, is the
|
|
57
|
+
* one place where guessing at that is least recoverable. They are the whole of
|
|
58
|
+
* the parser's configuration: a caller chooses a flavour, not a parser, and the
|
|
59
|
+
* components take these as props of their own.
|
|
60
|
+
*/
|
|
61
|
+
interface ParserOptions {
|
|
62
|
+
/**
|
|
63
|
+
* GFM's strikethrough (`~~a~~`) and bare autolinks (`www.example.com`).
|
|
64
|
+
*
|
|
65
|
+
* @default false
|
|
66
|
+
*/
|
|
67
|
+
gfm?: boolean
|
|
68
|
+
/**
|
|
69
|
+
* `@name` mentions, which no flavour of markdown has a notion of.
|
|
70
|
+
*
|
|
71
|
+
* @default false
|
|
72
|
+
*/
|
|
73
|
+
mention?: boolean
|
|
74
|
+
/**
|
|
75
|
+
* LaTeX between double dollar signs: `$$x^2$$` inline, and the same on lines
|
|
76
|
+
* of its own for a block.
|
|
77
|
+
*
|
|
78
|
+
* Two dollars, never one: `$5 and $6` is a price list in every document that
|
|
79
|
+
* has ever been written, and single-dollar maths would quietly turn it into a
|
|
80
|
+
* picture of the word "and".
|
|
81
|
+
*
|
|
82
|
+
* @default false
|
|
83
|
+
*/
|
|
84
|
+
math?: boolean
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** A parser, as the components hold one: text in, ranges out. */
|
|
88
|
+
type MarkdownParser = (markdown: string) => MarkdownRange[]
|
|
89
|
+
|
|
90
|
+
export type { MarkdownType, MarkdownRange, ParserOptions, MarkdownParser }
|
package/src/index.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { default as MarkdownTextInput, getWorkletRuntime } from "./MarkdownTextInput"
|
|
2
2
|
export type { MarkdownTextInputProps, MarkdownStyle } from "./MarkdownTextInput"
|
|
3
|
+
export { default as MarkdownText } from "./MarkdownText"
|
|
4
|
+
export type { MarkdownTextProps, OnLinkPress, RenderEmbed, RenderSVG } from "./MarkdownText"
|
|
3
5
|
export type { MarkdownType, MarkdownRange } from "./commonTypes"
|
|
4
|
-
export { parse as parser } from "./parser"
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What MathJax and SRE assume about their host that React Native does not
|
|
3
|
+
* provide. Imported before either of them, and first, because `import`
|
|
4
|
+
* statements are hoisted and run in the order they are written.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* MathJax guesses the operating system from `window.navigator.appVersion`,
|
|
9
|
+
* behind nothing but a `typeof window !== "undefined"` check
|
|
10
|
+
* (`@mathjax/src/mjs/util/context.js`). React Native defines `window` and
|
|
11
|
+
* `navigator` but not `appVersion`, so the check passes and the read throws
|
|
12
|
+
* `Cannot read property 'includes' of undefined` before a line of MathJax's own
|
|
13
|
+
* code runs.
|
|
14
|
+
*
|
|
15
|
+
* What it is guessing at is only ever used to rewrite Windows file paths, which
|
|
16
|
+
* nothing here does, so an empty string is both harmless and enough.
|
|
17
|
+
*/
|
|
18
|
+
const nav = (globalThis as unknown as { navigator?: Record<string, unknown> }).navigator
|
|
19
|
+
|
|
20
|
+
for (const key of ["appVersion", "userAgent"]) {
|
|
21
|
+
if (nav && nav[key] === undefined) {
|
|
22
|
+
try {
|
|
23
|
+
nav[key] = ""
|
|
24
|
+
} catch {
|
|
25
|
+
Object.defineProperty(nav, key, { value: "", configurable: true })
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The file system, which SRE reaches for before anything has had a chance to
|
|
32
|
+
* tell it not to.
|
|
33
|
+
*
|
|
34
|
+
* `speech-rule-engine/js/common/system_external.js` decides at import time how
|
|
35
|
+
* it will read its rule tables, and on anything that is not a browser it
|
|
36
|
+
* settles on Node's `fs` and a path worked out from `require.resolve` or
|
|
37
|
+
* `process.cwd()`. React Native has neither: `require` is the bundler's, which
|
|
38
|
+
* throws on a name it was not built with, and `process` is a stub with no
|
|
39
|
+
* `cwd`. Either one is an exception thrown from the top level of a module, so
|
|
40
|
+
* SRE cannot even be imported.
|
|
41
|
+
*
|
|
42
|
+
* None of it is wanted in any case -- the rules are bundled and handed over by
|
|
43
|
+
* a loader of our own -- so both routes are stubbed out here rather than fixed.
|
|
44
|
+
* `__non_webpack_require__` is the escape hatch SRE checks first, and a
|
|
45
|
+
* function that returns nothing for every name satisfies it, leaves `fs` null,
|
|
46
|
+
* and makes the path guessing fail its way harmlessly to the end.
|
|
47
|
+
*/
|
|
48
|
+
const scope = globalThis as unknown as {
|
|
49
|
+
__non_webpack_require__?: unknown
|
|
50
|
+
process?: { cwd?: () => string }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (scope.__non_webpack_require__ === undefined) {
|
|
54
|
+
try {
|
|
55
|
+
scope.__non_webpack_require__ = () => null
|
|
56
|
+
} catch {
|
|
57
|
+
Object.defineProperty(scope, "__non_webpack_require__", {
|
|
58
|
+
value: () => null,
|
|
59
|
+
configurable: true,
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (scope.process !== undefined && scope.process.cwd === undefined) {
|
|
65
|
+
scope.process.cwd = () => ""
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export {}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The maths backend, in its "there isn't one" form.
|
|
3
|
+
*
|
|
4
|
+
* Typesetting TeX takes a library an order of magnitude larger than this one,
|
|
5
|
+
* and most applications will never draw an equation. So the real backend --
|
|
6
|
+
* `./mathjax.ts`, right beside this -- is never imported by anything: a
|
|
7
|
+
* bundler would follow the import and pull MathJax into every app that has
|
|
8
|
+
* ever installed this package, whether or not it renders maths.
|
|
9
|
+
*
|
|
10
|
+
* Instead the two are swapped at build time. `react-native-marcus/metro`'s
|
|
11
|
+
* `withMath()` resolves this module to that one, so an application opts in by
|
|
12
|
+
* editing its `metro.config.js` and the default bundle carries nothing.
|
|
13
|
+
*
|
|
14
|
+
* What the swap has to preserve is this shape and nothing else.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/** One expression, drawn, with the box it needs. */
|
|
18
|
+
interface RenderedMath {
|
|
19
|
+
/**
|
|
20
|
+
* A standalone SVG document: glyph outlines inline, no `<use>`, no `<defs>`,
|
|
21
|
+
* and the colour already substituted in.
|
|
22
|
+
*/
|
|
23
|
+
svg: string
|
|
24
|
+
/** Points, at the font size that was asked for. */
|
|
25
|
+
width: number
|
|
26
|
+
height: number
|
|
27
|
+
/**
|
|
28
|
+
* How far below the baseline the drawing hangs -- zero for `x^2`, real for
|
|
29
|
+
* `\frac{a}{b}`. Part of the picture rather than of the size: `height`
|
|
30
|
+
* already covers it.
|
|
31
|
+
*/
|
|
32
|
+
depth: number
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Whether maths can be drawn at all.
|
|
37
|
+
*
|
|
38
|
+
* Read by the display components, which leave a maths span exactly as it was
|
|
39
|
+
* written when this is false. Showing `$$x^2$$` is a good deal better than
|
|
40
|
+
* showing an empty box where an equation should be, and it is the one hint an
|
|
41
|
+
* application will get that its Metro config is missing a line.
|
|
42
|
+
*/
|
|
43
|
+
const available = false
|
|
44
|
+
|
|
45
|
+
function renderMath(
|
|
46
|
+
_tex: string,
|
|
47
|
+
_display: boolean,
|
|
48
|
+
_fontSize: number,
|
|
49
|
+
_color: string | undefined,
|
|
50
|
+
): RenderedMath | null {
|
|
51
|
+
return null
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The expression as it should be read out, or nothing.
|
|
56
|
+
*
|
|
57
|
+
* A drawn equation is a picture, and the TeX behind it is source code: an
|
|
58
|
+
* author reading `\frac{a}{b}` knows what it means, and a reader who asked
|
|
59
|
+
* for a document rather than for its markup hears three words of punctuation.
|
|
60
|
+
* So a display says what it drew -- "StartFraction a Over b EndFraction" --
|
|
61
|
+
* while an input, where the TeX is what is on the screen and what the caret
|
|
62
|
+
* moves through, keeps the TeX.
|
|
63
|
+
*
|
|
64
|
+
* `locale` is the language it should be said in, as a name the backend knows;
|
|
65
|
+
* nothing means the backend's own default. What a document is written in and
|
|
66
|
+
* what its reader speaks are two different questions, and only the application
|
|
67
|
+
* knows the answer to the second.
|
|
68
|
+
*
|
|
69
|
+
* Returning nothing means the caller falls back to the TeX, which is what the
|
|
70
|
+
* stub does and what a backend does for an expression it cannot say.
|
|
71
|
+
*/
|
|
72
|
+
function speakMath(_tex: string, _display: boolean, _locale?: string): string | null {
|
|
73
|
+
return null
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export type { RenderedMath }
|
|
77
|
+
|
|
78
|
+
export { available, renderMath, speakMath }
|