react-native-nitro-markdown 0.1.2 → 0.3.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/LICENSE +21 -0
- package/README.md +293 -119
- package/android/src/main/cpp/cpp-adapter.cpp +1 -1
- package/android/src/main/java/com/margelo/nitro/com/nitromarkdown/HybridMarkdownSession.kt +61 -0
- package/android/src/main/java/com/nitromarkdown/NitroMarkdownPackage.kt +5 -1
- package/cpp/bindings/HybridMarkdownParser.cpp +2 -2
- package/cpp/bindings/HybridMarkdownParser.hpp +2 -2
- package/cpp/bindings/HybridMarkdownSession.cpp +0 -0
- package/cpp/core/MarkdownSessionCore.cpp +0 -0
- package/ios/HybridMarkdownSession.swift +64 -0
- package/lib/commonjs/MarkdownContext.js +17 -0
- package/lib/commonjs/MarkdownContext.js.map +1 -0
- package/lib/commonjs/MarkdownSession.js +11 -0
- package/lib/commonjs/MarkdownSession.js.map +1 -0
- package/lib/commonjs/default-markdown-renderer.js +217 -0
- package/lib/commonjs/default-markdown-renderer.js.map +1 -0
- package/lib/commonjs/headless.js +61 -0
- package/lib/commonjs/headless.js.map +1 -0
- package/lib/commonjs/index.js +220 -13
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/markdown-stream.js +32 -0
- package/lib/commonjs/markdown-stream.js.map +1 -0
- package/lib/commonjs/markdown.js +377 -0
- package/lib/commonjs/markdown.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/renderers/blockquote.js +36 -0
- package/lib/commonjs/renderers/blockquote.js.map +1 -0
- package/lib/commonjs/renderers/code.js +99 -0
- package/lib/commonjs/renderers/code.js.map +1 -0
- package/lib/commonjs/renderers/heading.js +63 -0
- package/lib/commonjs/renderers/heading.js.map +1 -0
- package/lib/commonjs/renderers/horizontal-rule.js +29 -0
- package/lib/commonjs/renderers/horizontal-rule.js.map +1 -0
- package/lib/commonjs/renderers/image.js +163 -0
- package/lib/commonjs/renderers/image.js.map +1 -0
- package/lib/commonjs/renderers/link.js +35 -0
- package/lib/commonjs/renderers/link.js.map +1 -0
- package/lib/commonjs/renderers/list.js +118 -0
- package/lib/commonjs/renderers/list.js.map +1 -0
- package/lib/commonjs/renderers/math.js +127 -0
- package/lib/commonjs/renderers/math.js.map +1 -0
- package/lib/commonjs/renderers/paragraph.js +39 -0
- package/lib/commonjs/renderers/paragraph.js.map +1 -0
- package/lib/commonjs/renderers/table.js +290 -0
- package/lib/commonjs/renderers/table.js.map +1 -0
- package/lib/commonjs/specs/MarkdownSession.nitro.js +6 -0
- package/lib/commonjs/specs/MarkdownSession.nitro.js.map +1 -0
- package/lib/commonjs/theme.js +191 -0
- package/lib/commonjs/theme.js.map +1 -0
- package/lib/commonjs/use-markdown-stream.js +71 -0
- package/lib/commonjs/use-markdown-stream.js.map +1 -0
- package/lib/module/MarkdownContext.js +12 -0
- package/lib/module/MarkdownContext.js.map +1 -0
- package/lib/module/MarkdownSession.js +7 -0
- package/lib/module/MarkdownSession.js.map +1 -0
- package/lib/module/default-markdown-renderer.js +212 -0
- package/lib/module/default-markdown-renderer.js.map +1 -0
- package/lib/module/headless.js +54 -0
- package/lib/module/headless.js.map +1 -0
- package/lib/module/index.js +18 -10
- package/lib/module/index.js.map +1 -1
- package/lib/module/markdown-stream.js +27 -0
- package/lib/module/markdown-stream.js.map +1 -0
- package/lib/module/markdown.js +372 -0
- package/lib/module/markdown.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/renderers/blockquote.js +31 -0
- package/lib/module/renderers/blockquote.js.map +1 -0
- package/lib/module/renderers/code.js +93 -0
- package/lib/module/renderers/code.js.map +1 -0
- package/lib/module/renderers/heading.js +58 -0
- package/lib/module/renderers/heading.js.map +1 -0
- package/lib/module/renderers/horizontal-rule.js +24 -0
- package/lib/module/renderers/horizontal-rule.js.map +1 -0
- package/lib/module/renderers/image.js +158 -0
- package/lib/module/renderers/image.js.map +1 -0
- package/lib/module/renderers/link.js +30 -0
- package/lib/module/renderers/link.js.map +1 -0
- package/lib/module/renderers/list.js +111 -0
- package/lib/module/renderers/list.js.map +1 -0
- package/lib/module/renderers/math.js +121 -0
- package/lib/module/renderers/math.js.map +1 -0
- package/lib/module/renderers/paragraph.js +34 -0
- package/lib/module/renderers/paragraph.js.map +1 -0
- package/lib/module/renderers/table.js +285 -0
- package/lib/module/renderers/table.js.map +1 -0
- package/lib/module/specs/MarkdownSession.nitro.js +4 -0
- package/lib/module/specs/MarkdownSession.nitro.js.map +1 -0
- package/lib/module/theme.js +186 -0
- package/lib/module/theme.js.map +1 -0
- package/lib/module/use-markdown-stream.js +66 -0
- package/lib/module/use-markdown-stream.js.map +1 -0
- package/lib/typescript/commonjs/Markdown.nitro.d.ts.map +1 -0
- package/lib/typescript/commonjs/MarkdownContext.d.ts +65 -0
- package/lib/typescript/commonjs/MarkdownContext.d.ts.map +1 -0
- package/lib/typescript/commonjs/MarkdownSession.d.ts +4 -0
- package/lib/typescript/commonjs/MarkdownSession.d.ts.map +1 -0
- package/lib/typescript/commonjs/default-markdown-renderer.d.ts +10 -0
- package/lib/typescript/commonjs/default-markdown-renderer.d.ts.map +1 -0
- package/lib/typescript/commonjs/headless.d.ts +57 -0
- package/lib/typescript/commonjs/headless.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +22 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/markdown-stream.d.ts +15 -0
- package/lib/typescript/commonjs/markdown-stream.d.ts.map +1 -0
- package/lib/typescript/commonjs/markdown.d.ts +47 -0
- package/lib/typescript/commonjs/markdown.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/renderers/blockquote.d.ts +9 -0
- package/lib/typescript/commonjs/renderers/blockquote.d.ts.map +1 -0
- package/lib/typescript/commonjs/renderers/code.d.ts +19 -0
- package/lib/typescript/commonjs/renderers/code.d.ts.map +1 -0
- package/lib/typescript/commonjs/renderers/heading.d.ts +10 -0
- package/lib/typescript/commonjs/renderers/heading.d.ts.map +1 -0
- package/lib/typescript/commonjs/renderers/horizontal-rule.d.ts +8 -0
- package/lib/typescript/commonjs/renderers/horizontal-rule.d.ts.map +1 -0
- package/lib/typescript/commonjs/renderers/image.d.ts +13 -0
- package/lib/typescript/commonjs/renderers/image.d.ts.map +1 -0
- package/lib/typescript/commonjs/renderers/link.d.ts +10 -0
- package/lib/typescript/commonjs/renderers/link.d.ts.map +1 -0
- package/lib/typescript/commonjs/renderers/list.d.ts +26 -0
- package/lib/typescript/commonjs/renderers/list.d.ts.map +1 -0
- package/lib/typescript/commonjs/renderers/math.d.ts +14 -0
- package/lib/typescript/commonjs/renderers/math.d.ts.map +1 -0
- package/lib/typescript/commonjs/renderers/paragraph.d.ts +10 -0
- package/lib/typescript/commonjs/renderers/paragraph.d.ts.map +1 -0
- package/lib/typescript/commonjs/renderers/table.d.ts +12 -0
- package/lib/typescript/commonjs/renderers/table.d.ts.map +1 -0
- package/lib/typescript/commonjs/specs/MarkdownSession.nitro.d.ts +12 -0
- package/lib/typescript/commonjs/specs/MarkdownSession.nitro.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme.d.ts +65 -0
- package/lib/typescript/commonjs/theme.d.ts.map +1 -0
- package/lib/typescript/commonjs/use-markdown-stream.d.ts +22 -0
- package/lib/typescript/commonjs/use-markdown-stream.d.ts.map +1 -0
- package/lib/typescript/module/Markdown.nitro.d.ts +13 -0
- package/lib/typescript/module/Markdown.nitro.d.ts.map +1 -0
- package/lib/typescript/module/MarkdownContext.d.ts +65 -0
- package/lib/typescript/module/MarkdownContext.d.ts.map +1 -0
- package/lib/typescript/module/MarkdownSession.d.ts +4 -0
- package/lib/typescript/module/MarkdownSession.d.ts.map +1 -0
- package/lib/typescript/module/default-markdown-renderer.d.ts +10 -0
- package/lib/typescript/module/default-markdown-renderer.d.ts.map +1 -0
- package/lib/typescript/module/headless.d.ts +57 -0
- package/lib/typescript/module/headless.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +22 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/markdown-stream.d.ts +15 -0
- package/lib/typescript/module/markdown-stream.d.ts.map +1 -0
- package/lib/typescript/module/markdown.d.ts +47 -0
- package/lib/typescript/module/markdown.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/renderers/blockquote.d.ts +9 -0
- package/lib/typescript/module/renderers/blockquote.d.ts.map +1 -0
- package/lib/typescript/module/renderers/code.d.ts +19 -0
- package/lib/typescript/module/renderers/code.d.ts.map +1 -0
- package/lib/typescript/module/renderers/heading.d.ts +10 -0
- package/lib/typescript/module/renderers/heading.d.ts.map +1 -0
- package/lib/typescript/module/renderers/horizontal-rule.d.ts +8 -0
- package/lib/typescript/module/renderers/horizontal-rule.d.ts.map +1 -0
- package/lib/typescript/module/renderers/image.d.ts +13 -0
- package/lib/typescript/module/renderers/image.d.ts.map +1 -0
- package/lib/typescript/module/renderers/link.d.ts +10 -0
- package/lib/typescript/module/renderers/link.d.ts.map +1 -0
- package/lib/typescript/module/renderers/list.d.ts +26 -0
- package/lib/typescript/module/renderers/list.d.ts.map +1 -0
- package/lib/typescript/module/renderers/math.d.ts +14 -0
- package/lib/typescript/module/renderers/math.d.ts.map +1 -0
- package/lib/typescript/module/renderers/paragraph.d.ts +10 -0
- package/lib/typescript/module/renderers/paragraph.d.ts.map +1 -0
- package/lib/typescript/module/renderers/table.d.ts +12 -0
- package/lib/typescript/module/renderers/table.d.ts.map +1 -0
- package/lib/typescript/module/specs/MarkdownSession.nitro.d.ts +12 -0
- package/lib/typescript/module/specs/MarkdownSession.nitro.d.ts.map +1 -0
- package/lib/typescript/module/theme.d.ts +65 -0
- package/lib/typescript/module/theme.d.ts.map +1 -0
- package/lib/typescript/module/use-markdown-stream.d.ts +22 -0
- package/lib/typescript/module/use-markdown-stream.d.ts.map +1 -0
- package/nitro.json +5 -2
- package/nitrogen/generated/android/NitroMarkdown+autolinking.cmake +3 -2
- package/nitrogen/generated/android/NitroMarkdown+autolinking.gradle +1 -1
- package/nitrogen/generated/android/NitroMarkdownOnLoad.cpp +17 -5
- package/nitrogen/generated/android/NitroMarkdownOnLoad.hpp +4 -4
- package/nitrogen/generated/android/c++/JFunc_void.hpp +75 -0
- package/nitrogen/generated/android/c++/JHybridMarkdownSessionSpec.cpp +91 -0
- package/nitrogen/generated/android/c++/JHybridMarkdownSessionSpec.hpp +70 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/com/nitromarkdown/Func_void.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/com/nitromarkdown/HybridMarkdownSessionSpec.kt +78 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/com/nitromarkdown/NitroMarkdownOnLoad.kt +1 -1
- package/nitrogen/generated/ios/NitroMarkdown+autolinking.rb +2 -2
- package/nitrogen/generated/ios/NitroMarkdown-Swift-Cxx-Bridge.cpp +28 -4
- package/nitrogen/generated/ios/NitroMarkdown-Swift-Cxx-Bridge.hpp +72 -6
- package/nitrogen/generated/ios/NitroMarkdown-Swift-Cxx-Umbrella.hpp +11 -4
- package/nitrogen/generated/ios/NitroMarkdownAutolinking.mm +11 -3
- package/nitrogen/generated/ios/NitroMarkdownAutolinking.swift +16 -3
- package/nitrogen/generated/ios/c++/HybridMarkdownSessionSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridMarkdownSessionSpecSwift.hpp +108 -0
- package/nitrogen/generated/ios/swift/Func_void.swift +47 -0
- package/nitrogen/generated/ios/swift/HybridMarkdownSessionSpec.swift +59 -0
- package/nitrogen/generated/ios/swift/HybridMarkdownSessionSpec_cxx.swift +190 -0
- package/nitrogen/generated/shared/c++/HybridMarkdownParserSpec.cpp +3 -3
- package/nitrogen/generated/shared/c++/HybridMarkdownParserSpec.hpp +4 -4
- package/nitrogen/generated/shared/c++/HybridMarkdownSessionSpec.cpp +26 -0
- package/nitrogen/generated/shared/c++/HybridMarkdownSessionSpec.hpp +67 -0
- package/nitrogen/generated/shared/c++/ParserOptions.hpp +22 -14
- package/package.json +45 -7
- package/react-native-nitro-markdown.podspec +5 -5
- package/src/MarkdownContext.ts +98 -0
- package/src/MarkdownSession.ts +8 -0
- package/src/default-markdown-renderer.tsx +261 -0
- package/src/headless.ts +116 -0
- package/src/index.ts +47 -60
- package/src/markdown-stream.tsx +32 -0
- package/src/markdown.tsx +497 -0
- package/src/renderers/blockquote.tsx +30 -0
- package/src/renderers/code.tsx +112 -0
- package/src/renderers/heading.tsx +66 -0
- package/src/renderers/horizontal-rule.tsx +23 -0
- package/src/renderers/image.tsx +175 -0
- package/src/renderers/link.tsx +33 -0
- package/src/renderers/list.tsx +131 -0
- package/src/renderers/math.tsx +141 -0
- package/src/renderers/paragraph.tsx +47 -0
- package/src/renderers/table.tsx +370 -0
- package/src/specs/MarkdownSession.nitro.ts +16 -0
- package/src/theme.ts +243 -0
- package/src/use-markdown-stream.ts +83 -0
- package/ios/NitroMarkdown-Bridging-Header.h +0 -14
- package/lib/commonjs/MarkdownJS.reference.js +0 -114
- package/lib/commonjs/MarkdownJS.reference.js.map +0 -1
- package/lib/module/MarkdownJS.reference.js +0 -107
- package/lib/module/MarkdownJS.reference.js.map +0 -1
- package/lib/typescript/Markdown.nitro.d.ts.map +0 -1
- package/lib/typescript/MarkdownJS.reference.d.ts +0 -33
- package/lib/typescript/MarkdownJS.reference.d.ts.map +0 -1
- package/lib/typescript/index.d.ts +0 -22
- package/lib/typescript/index.d.ts.map +0 -1
- package/src/MarkdownJS.reference.ts +0 -122
- /package/lib/typescript/{Markdown.nitro.d.ts → commonjs/Markdown.nitro.d.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,12 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-nitro-markdown",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "High-performance Markdown parser for React Native using Nitro Modules and md4c",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
7
|
-
"types": "lib/typescript/index.d.ts",
|
|
7
|
+
"types": "lib/typescript/commonjs/index.d.ts",
|
|
8
8
|
"react-native": "src/index.ts",
|
|
9
9
|
"source": "src/index.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": {
|
|
13
|
+
"types": "./lib/typescript/module/index.d.ts",
|
|
14
|
+
"default": "./lib/module/index.js"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./lib/typescript/commonjs/index.d.ts",
|
|
18
|
+
"default": "./lib/commonjs/index.js"
|
|
19
|
+
},
|
|
20
|
+
"react-native": "./src/index.ts"
|
|
21
|
+
},
|
|
22
|
+
"./headless": {
|
|
23
|
+
"import": {
|
|
24
|
+
"types": "./lib/typescript/module/headless.d.ts",
|
|
25
|
+
"default": "./lib/module/headless.js"
|
|
26
|
+
},
|
|
27
|
+
"require": {
|
|
28
|
+
"types": "./lib/typescript/commonjs/headless.d.ts",
|
|
29
|
+
"default": "./lib/commonjs/headless.js"
|
|
30
|
+
},
|
|
31
|
+
"react-native": "./src/headless.ts"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
10
34
|
"files": [
|
|
11
35
|
"src",
|
|
12
36
|
"lib",
|
|
@@ -34,8 +58,8 @@
|
|
|
34
58
|
"test": "jest",
|
|
35
59
|
"test:coverage": "jest --coverage",
|
|
36
60
|
"benchmark": "node ../../scripts/benchmark-comparison.js",
|
|
37
|
-
"prepack": "node -e \"require('fs').copyFileSync('../../README.md','./README.md')\"",
|
|
38
|
-
"postpack": "node -e \"const fs=require('fs');if(fs.existsSync('./README.md'))fs.unlinkSync('./README.md')\"",
|
|
61
|
+
"prepack": "node -e \"const fs=require('fs'); fs.copyFileSync('../../README.md','./README.md'); fs.copyFileSync('../../LICENSE','./LICENSE')\"",
|
|
62
|
+
"postpack": "node -e \"const fs=require('fs'); if(fs.existsSync('./README.md'))fs.unlinkSync('./README.md'); if(fs.existsSync('./LICENSE'))fs.unlinkSync('./LICENSE')\"",
|
|
39
63
|
"test:cpp": "node scripts/test-cpp.js"
|
|
40
64
|
},
|
|
41
65
|
"keywords": [
|
|
@@ -52,7 +76,7 @@
|
|
|
52
76
|
"type": "git",
|
|
53
77
|
"url": "git+https://github.com/JoaoPauloCMarra/react-native-nitro-markdown.git"
|
|
54
78
|
},
|
|
55
|
-
"author": "",
|
|
79
|
+
"author": "João Paulo C. Marra <joaopaulocmarra@gmail.com>",
|
|
56
80
|
"license": "MIT",
|
|
57
81
|
"bugs": {
|
|
58
82
|
"url": "https://github.com/JoaoPauloCMarra/react-native-nitro-markdown/issues"
|
|
@@ -62,12 +86,26 @@
|
|
|
62
86
|
"registry": "https://registry.npmjs.org/"
|
|
63
87
|
},
|
|
64
88
|
"devDependencies": {
|
|
65
|
-
"react
|
|
89
|
+
"@types/react": "^19.2.7",
|
|
90
|
+
"@types/react-native": "^0.73.0",
|
|
91
|
+
"react-native-builder-bob": "^0.40.17",
|
|
92
|
+
"react-native-nitro-modules": "*",
|
|
93
|
+
"typescript": "^5.9.3"
|
|
66
94
|
},
|
|
67
95
|
"peerDependencies": {
|
|
68
96
|
"react": "*",
|
|
69
97
|
"react-native": ">=0.75.0",
|
|
70
|
-
"react-native-nitro-modules": "
|
|
98
|
+
"react-native-nitro-modules": "*",
|
|
99
|
+
"react-native-mathjax-svg": ">=0.9.0",
|
|
100
|
+
"react-native-svg": ">=13.0.0"
|
|
101
|
+
},
|
|
102
|
+
"peerDependenciesMeta": {
|
|
103
|
+
"react-native-mathjax-svg": {
|
|
104
|
+
"optional": true
|
|
105
|
+
},
|
|
106
|
+
"react-native-svg": {
|
|
107
|
+
"optional": true
|
|
108
|
+
}
|
|
71
109
|
},
|
|
72
110
|
"codegenConfig": {
|
|
73
111
|
"name": "NitroMarkdownSpec",
|
|
@@ -12,19 +12,20 @@ Pod::Spec.new do |s|
|
|
|
12
12
|
|
|
13
13
|
s.platforms = { :ios => "13.0" }
|
|
14
14
|
s.source = { :git => "https://github.com/JoaoPauloCMarra/react-native-nitro-markdown.git", :tag => "#{s.version}" }
|
|
15
|
+
s.module_name = "NitroMarkdown"
|
|
15
16
|
|
|
16
|
-
# All source files including md4c and our C++ implementation
|
|
17
17
|
s.source_files = [
|
|
18
18
|
"ios/**/*.{h,m,mm,swift}",
|
|
19
19
|
"cpp/**/*.{h,hpp,c,cpp}"
|
|
20
20
|
]
|
|
21
21
|
|
|
22
|
-
# Ensure md4c.c is compiled as C, not C++
|
|
23
22
|
s.pod_target_xcconfig = {
|
|
24
23
|
"CLANG_CXX_LANGUAGE_STANDARD" => "c++20",
|
|
25
24
|
"CLANG_CXX_LIBRARY" => "libc++",
|
|
26
25
|
"GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) MD4C_USE_UTF8=1",
|
|
27
26
|
"HEADER_SEARCH_PATHS" => [
|
|
27
|
+
"\"$(inherited)\"",
|
|
28
|
+
"\"$(PODS_ROOT)/Headers/Private/Yoga\"",
|
|
28
29
|
"\"$(PODS_TARGET_SRCROOT)/cpp/md4c\"",
|
|
29
30
|
"\"$(PODS_TARGET_SRCROOT)/cpp/core\"",
|
|
30
31
|
"\"$(PODS_TARGET_SRCROOT)/cpp/bindings\"",
|
|
@@ -33,10 +34,9 @@ Pod::Spec.new do |s|
|
|
|
33
34
|
].join(" ")
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
# React Native dependency
|
|
37
37
|
s.dependency "React-Core"
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
s.dependency "React-Fabric"
|
|
39
|
+
|
|
40
40
|
load 'nitrogen/generated/ios/NitroMarkdown+autolinking.rb'
|
|
41
41
|
add_nitrogen_files(s)
|
|
42
42
|
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
useContext,
|
|
4
|
+
type ReactNode,
|
|
5
|
+
type ComponentType,
|
|
6
|
+
} from "react";
|
|
7
|
+
import {
|
|
8
|
+
defaultMarkdownTheme,
|
|
9
|
+
type MarkdownTheme,
|
|
10
|
+
type NodeStyleOverrides,
|
|
11
|
+
type StylingStrategy,
|
|
12
|
+
} from "./theme";
|
|
13
|
+
import type { MarkdownNode } from "./headless";
|
|
14
|
+
|
|
15
|
+
export interface NodeRendererProps {
|
|
16
|
+
node: MarkdownNode;
|
|
17
|
+
depth: number;
|
|
18
|
+
inListItem: boolean;
|
|
19
|
+
parentIsText?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface BaseCustomRendererProps {
|
|
23
|
+
node: MarkdownNode;
|
|
24
|
+
children: ReactNode;
|
|
25
|
+
Renderer: ComponentType<NodeRendererProps>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface EnhancedRendererProps extends BaseCustomRendererProps {
|
|
29
|
+
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
30
|
+
href?: string;
|
|
31
|
+
title?: string;
|
|
32
|
+
url?: string;
|
|
33
|
+
alt?: string;
|
|
34
|
+
content?: string;
|
|
35
|
+
language?: string;
|
|
36
|
+
ordered?: boolean;
|
|
37
|
+
start?: number;
|
|
38
|
+
checked?: boolean;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface HeadingRendererProps extends BaseCustomRendererProps {
|
|
42
|
+
level: 1 | 2 | 3 | 4 | 5 | 6;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface LinkRendererProps extends BaseCustomRendererProps {
|
|
46
|
+
href: string;
|
|
47
|
+
title?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface ImageRendererProps extends BaseCustomRendererProps {
|
|
51
|
+
url: string;
|
|
52
|
+
alt?: string;
|
|
53
|
+
title?: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface CodeBlockRendererProps extends BaseCustomRendererProps {
|
|
57
|
+
content: string;
|
|
58
|
+
language?: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface InlineCodeRendererProps extends BaseCustomRendererProps {
|
|
62
|
+
content: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface ListRendererProps extends BaseCustomRendererProps {
|
|
66
|
+
ordered: boolean;
|
|
67
|
+
start?: number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface TaskListItemRendererProps extends BaseCustomRendererProps {
|
|
71
|
+
checked: boolean;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface CustomRendererProps extends EnhancedRendererProps {}
|
|
75
|
+
|
|
76
|
+
export type CustomRenderer = (
|
|
77
|
+
props: EnhancedRendererProps
|
|
78
|
+
) => ReactNode | undefined;
|
|
79
|
+
|
|
80
|
+
export type CustomRenderers = Partial<
|
|
81
|
+
Record<MarkdownNode["type"], CustomRenderer>
|
|
82
|
+
>;
|
|
83
|
+
|
|
84
|
+
export interface MarkdownContextValue {
|
|
85
|
+
renderers: CustomRenderers;
|
|
86
|
+
theme: MarkdownTheme;
|
|
87
|
+
styles?: NodeStyleOverrides;
|
|
88
|
+
stylingStrategy: StylingStrategy;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export const MarkdownContext = createContext<MarkdownContextValue>({
|
|
92
|
+
renderers: {},
|
|
93
|
+
theme: defaultMarkdownTheme,
|
|
94
|
+
styles: undefined,
|
|
95
|
+
stylingStrategy: "opinionated",
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
export const useMarkdownContext = () => useContext(MarkdownContext);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { NitroModules } from "react-native-nitro-modules";
|
|
2
|
+
import type { MarkdownSession as MarkdownSessionSpec } from "./specs/MarkdownSession.nitro";
|
|
3
|
+
|
|
4
|
+
export type MarkdownSession = MarkdownSessionSpec;
|
|
5
|
+
|
|
6
|
+
export function createMarkdownSession(): MarkdownSession {
|
|
7
|
+
return NitroModules.createHybridObject<MarkdownSession>("MarkdownSession");
|
|
8
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { type ReactNode, type FC } from "react";
|
|
2
|
+
import { View, Text, StyleSheet } from "react-native";
|
|
3
|
+
import { type MarkdownNode, getTextContent } from "./headless";
|
|
4
|
+
import { Heading } from "./renderers/heading";
|
|
5
|
+
import { Paragraph } from "./renderers/paragraph";
|
|
6
|
+
import { Link } from "./renderers/link";
|
|
7
|
+
import { Blockquote } from "./renderers/blockquote";
|
|
8
|
+
import { HorizontalRule } from "./renderers/horizontal-rule";
|
|
9
|
+
import { CodeBlock, InlineCode } from "./renderers/code";
|
|
10
|
+
import { List, ListItem, TaskListItem } from "./renderers/list";
|
|
11
|
+
import { TableRenderer } from "./renderers/table";
|
|
12
|
+
import { Image } from "./renderers/image";
|
|
13
|
+
import { MathInline, MathBlock } from "./renderers/math";
|
|
14
|
+
import { defaultMarkdownTheme } from "./theme";
|
|
15
|
+
|
|
16
|
+
interface MarkdownRendererProps {
|
|
17
|
+
node: MarkdownNode;
|
|
18
|
+
depth?: number;
|
|
19
|
+
inListItem?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const isInline = (type: MarkdownNode["type"]): boolean => {
|
|
23
|
+
return (
|
|
24
|
+
type === "text" ||
|
|
25
|
+
type === "bold" ||
|
|
26
|
+
type === "italic" ||
|
|
27
|
+
type === "strikethrough" ||
|
|
28
|
+
type === "link" ||
|
|
29
|
+
type === "code_inline" ||
|
|
30
|
+
type === "soft_break" ||
|
|
31
|
+
type === "line_break" ||
|
|
32
|
+
type === "math_inline" ||
|
|
33
|
+
type === "html_inline"
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const DefaultMarkdownRenderer: FC<MarkdownRendererProps> = ({
|
|
38
|
+
node,
|
|
39
|
+
depth = 0,
|
|
40
|
+
inListItem = false,
|
|
41
|
+
}) => {
|
|
42
|
+
const renderChildren = (
|
|
43
|
+
children?: MarkdownNode[],
|
|
44
|
+
childInListItem = false
|
|
45
|
+
) => {
|
|
46
|
+
if (!children || children.length === 0) return null;
|
|
47
|
+
|
|
48
|
+
const elements: ReactNode[] = [];
|
|
49
|
+
let currentInlineGroup: MarkdownNode[] = [];
|
|
50
|
+
|
|
51
|
+
const flushInlineGroup = () => {
|
|
52
|
+
if (currentInlineGroup.length > 0) {
|
|
53
|
+
elements.push(
|
|
54
|
+
<Text key={`inline-group-${elements.length}`} style={styles.text}>
|
|
55
|
+
{currentInlineGroup.map((child, index) => (
|
|
56
|
+
<DefaultMarkdownRenderer
|
|
57
|
+
key={`${child.type}-${index}`}
|
|
58
|
+
node={child}
|
|
59
|
+
depth={depth + 1}
|
|
60
|
+
inListItem={childInListItem}
|
|
61
|
+
/>
|
|
62
|
+
))}
|
|
63
|
+
</Text>
|
|
64
|
+
);
|
|
65
|
+
currentInlineGroup = [];
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
children.forEach((child, index) => {
|
|
70
|
+
if (isInline(child.type)) {
|
|
71
|
+
currentInlineGroup.push(child);
|
|
72
|
+
} else {
|
|
73
|
+
flushInlineGroup();
|
|
74
|
+
elements.push(
|
|
75
|
+
<DefaultMarkdownRenderer
|
|
76
|
+
key={`${child.type}-${index}`}
|
|
77
|
+
node={child}
|
|
78
|
+
depth={depth + 1}
|
|
79
|
+
inListItem={childInListItem}
|
|
80
|
+
/>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
flushInlineGroup();
|
|
86
|
+
return elements;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
switch (node.type) {
|
|
90
|
+
case "document":
|
|
91
|
+
return (
|
|
92
|
+
<View style={styles.document}>
|
|
93
|
+
{renderChildren(node.children, false)}
|
|
94
|
+
</View>
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
case "heading":
|
|
98
|
+
return (
|
|
99
|
+
<Heading level={node.level ?? 1}>
|
|
100
|
+
{renderChildren(node.children, inListItem)}
|
|
101
|
+
</Heading>
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
case "paragraph":
|
|
105
|
+
return (
|
|
106
|
+
<Paragraph inListItem={inListItem}>
|
|
107
|
+
{renderChildren(node.children, inListItem)}
|
|
108
|
+
</Paragraph>
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
case "text":
|
|
112
|
+
return <Text style={styles.text}>{node.content}</Text>;
|
|
113
|
+
|
|
114
|
+
case "bold":
|
|
115
|
+
return (
|
|
116
|
+
<Text style={styles.bold}>
|
|
117
|
+
{renderChildren(node.children, inListItem)}
|
|
118
|
+
</Text>
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
case "italic":
|
|
122
|
+
return (
|
|
123
|
+
<Text style={styles.italic}>
|
|
124
|
+
{renderChildren(node.children, inListItem)}
|
|
125
|
+
</Text>
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
case "strikethrough":
|
|
129
|
+
return (
|
|
130
|
+
<Text style={styles.strikethrough}>
|
|
131
|
+
{renderChildren(node.children, inListItem)}
|
|
132
|
+
</Text>
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
case "link":
|
|
136
|
+
return (
|
|
137
|
+
<Link href={node.href ?? ""}>
|
|
138
|
+
{renderChildren(node.children, inListItem)}
|
|
139
|
+
</Link>
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
case "image":
|
|
143
|
+
return (
|
|
144
|
+
<Image
|
|
145
|
+
url={node.href ?? ""}
|
|
146
|
+
title={node.title}
|
|
147
|
+
alt={node.alt}
|
|
148
|
+
Renderer={DefaultMarkdownRenderer}
|
|
149
|
+
/>
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
case "code_inline":
|
|
153
|
+
return <InlineCode>{node.content}</InlineCode>;
|
|
154
|
+
|
|
155
|
+
case "code_block":
|
|
156
|
+
return (
|
|
157
|
+
<CodeBlock language={node.language} content={getTextContent(node)} />
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
case "blockquote":
|
|
161
|
+
return (
|
|
162
|
+
<Blockquote>{renderChildren(node.children, inListItem)}</Blockquote>
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
case "horizontal_rule":
|
|
166
|
+
return <HorizontalRule />;
|
|
167
|
+
|
|
168
|
+
case "line_break":
|
|
169
|
+
return <Text>{"\n"}</Text>;
|
|
170
|
+
|
|
171
|
+
case "soft_break":
|
|
172
|
+
return <Text> </Text>;
|
|
173
|
+
|
|
174
|
+
case "math_inline": {
|
|
175
|
+
let mathContent = getTextContent(node);
|
|
176
|
+
if (!mathContent) return null;
|
|
177
|
+
mathContent = mathContent.replace(/^\$+|\$+$/g, "").trim();
|
|
178
|
+
return <MathInline content={mathContent} />;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
case "math_block": {
|
|
182
|
+
let mathContent = getTextContent(node);
|
|
183
|
+
if (!mathContent) return null;
|
|
184
|
+
mathContent = mathContent.replace(/^\$+|\$+$/g, "").trim();
|
|
185
|
+
return <MathBlock content={mathContent} />;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
case "list":
|
|
189
|
+
return (
|
|
190
|
+
<List ordered={node.ordered ?? false} start={node.start} depth={depth}>
|
|
191
|
+
{node.children?.map((child, index) => {
|
|
192
|
+
if (child.type === "task_list_item") {
|
|
193
|
+
return (
|
|
194
|
+
<DefaultMarkdownRenderer
|
|
195
|
+
key={index}
|
|
196
|
+
node={child}
|
|
197
|
+
depth={depth + 1}
|
|
198
|
+
inListItem={true}
|
|
199
|
+
/>
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
return (
|
|
203
|
+
<ListItem
|
|
204
|
+
key={index}
|
|
205
|
+
index={index}
|
|
206
|
+
ordered={node.ordered ?? false}
|
|
207
|
+
start={node.start ?? 1}
|
|
208
|
+
>
|
|
209
|
+
<DefaultMarkdownRenderer
|
|
210
|
+
node={child}
|
|
211
|
+
depth={depth + 1}
|
|
212
|
+
inListItem={true}
|
|
213
|
+
/>
|
|
214
|
+
</ListItem>
|
|
215
|
+
);
|
|
216
|
+
})}
|
|
217
|
+
</List>
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
case "list_item":
|
|
221
|
+
return <>{renderChildren(node.children, true)}</>;
|
|
222
|
+
|
|
223
|
+
case "task_list_item":
|
|
224
|
+
return (
|
|
225
|
+
<TaskListItem checked={node.checked ?? false}>
|
|
226
|
+
{renderChildren(node.children, true)}
|
|
227
|
+
</TaskListItem>
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
case "table":
|
|
231
|
+
return <TableRenderer node={node} Renderer={DefaultMarkdownRenderer} />;
|
|
232
|
+
|
|
233
|
+
case "table_head":
|
|
234
|
+
case "table_body":
|
|
235
|
+
case "table_row":
|
|
236
|
+
case "table_cell":
|
|
237
|
+
// Handled by TableRenderer
|
|
238
|
+
return null;
|
|
239
|
+
|
|
240
|
+
default:
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
const styles = StyleSheet.create({
|
|
246
|
+
document: {
|
|
247
|
+
flex: 1,
|
|
248
|
+
},
|
|
249
|
+
text: {
|
|
250
|
+
color: defaultMarkdownTheme.colors.text,
|
|
251
|
+
},
|
|
252
|
+
bold: {
|
|
253
|
+
fontWeight: "700",
|
|
254
|
+
},
|
|
255
|
+
italic: {
|
|
256
|
+
fontStyle: "italic",
|
|
257
|
+
},
|
|
258
|
+
strikethrough: {
|
|
259
|
+
textDecorationLine: "line-through",
|
|
260
|
+
},
|
|
261
|
+
});
|
package/src/headless.ts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Headless entry point for react-native-nitro-markdown.
|
|
3
|
+
* Use this when you want to build your own renderer and minimize bundle size.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```tsx
|
|
7
|
+
* import { parseMarkdown } from 'react-native-nitro-markdown/headless';
|
|
8
|
+
*
|
|
9
|
+
* const ast = parseMarkdown('# Hello World');
|
|
10
|
+
* // Build your own renderer using the AST
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
import { NitroModules } from "react-native-nitro-modules";
|
|
14
|
+
import type { MarkdownParser, ParserOptions } from "./Markdown.nitro";
|
|
15
|
+
|
|
16
|
+
export type { ParserOptions } from "./Markdown.nitro";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Represents a node in the Markdown AST (Abstract Syntax Tree).
|
|
20
|
+
* Each node has a type and optional properties depending on the node type.
|
|
21
|
+
*/
|
|
22
|
+
export interface MarkdownNode {
|
|
23
|
+
/** The type of markdown element this node represents. Used to decide how to render the node. */
|
|
24
|
+
type:
|
|
25
|
+
| "document"
|
|
26
|
+
| "heading"
|
|
27
|
+
| "paragraph"
|
|
28
|
+
| "text"
|
|
29
|
+
| "bold"
|
|
30
|
+
| "italic"
|
|
31
|
+
| "strikethrough"
|
|
32
|
+
| "link"
|
|
33
|
+
| "image"
|
|
34
|
+
| "code_inline"
|
|
35
|
+
| "code_block"
|
|
36
|
+
| "blockquote"
|
|
37
|
+
| "horizontal_rule"
|
|
38
|
+
| "line_break"
|
|
39
|
+
| "soft_break"
|
|
40
|
+
| "table"
|
|
41
|
+
| "table_head"
|
|
42
|
+
| "table_body"
|
|
43
|
+
| "table_row"
|
|
44
|
+
| "table_cell"
|
|
45
|
+
| "list"
|
|
46
|
+
| "list_item"
|
|
47
|
+
| "task_list_item"
|
|
48
|
+
| "math_inline"
|
|
49
|
+
| "math_block"
|
|
50
|
+
| "html_block"
|
|
51
|
+
| "html_inline";
|
|
52
|
+
/** Text content for text, code, and similar nodes. */
|
|
53
|
+
content?: string;
|
|
54
|
+
/** Heading level (1-6) for heading nodes. */
|
|
55
|
+
level?: number;
|
|
56
|
+
/** URL for link and image nodes. */
|
|
57
|
+
href?: string;
|
|
58
|
+
/** Title attribute for link and image nodes. */
|
|
59
|
+
title?: string;
|
|
60
|
+
/** Alt text for image nodes. */
|
|
61
|
+
alt?: string;
|
|
62
|
+
/** Programming language for code blocks (e.g., 'typescript', 'javascript'). */
|
|
63
|
+
language?: string;
|
|
64
|
+
/** Whether a list is ordered (numbered) or unordered. */
|
|
65
|
+
ordered?: boolean;
|
|
66
|
+
/** The starting number for ordered lists. */
|
|
67
|
+
start?: number;
|
|
68
|
+
/** Whether a task list item is currently checked. */
|
|
69
|
+
checked?: boolean;
|
|
70
|
+
/** Whether a table cell is part of the header row. */
|
|
71
|
+
isHeader?: boolean;
|
|
72
|
+
/** Text alignment for table cells: 'left', 'center', or 'right'. */
|
|
73
|
+
align?: string;
|
|
74
|
+
/** Nested child nodes for hierarchical elements like paragraphs, lists, and tables. */
|
|
75
|
+
children?: MarkdownNode[];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const MarkdownParserModule =
|
|
79
|
+
NitroModules.createHybridObject<MarkdownParser>("MarkdownParser");
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Parse markdown text into an AST.
|
|
83
|
+
* @param text - The markdown text to parse
|
|
84
|
+
* @returns The root node of the parsed AST
|
|
85
|
+
*/
|
|
86
|
+
export function parseMarkdown(text: string): MarkdownNode {
|
|
87
|
+
const jsonStr = MarkdownParserModule.parse(text);
|
|
88
|
+
return JSON.parse(jsonStr) as MarkdownNode;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Parse markdown text with custom options.
|
|
93
|
+
* @param text - The markdown text to parse
|
|
94
|
+
* @param options - Parser options (gfm, math)
|
|
95
|
+
* @returns The root node of the parsed AST
|
|
96
|
+
*/
|
|
97
|
+
export function parseMarkdownWithOptions(
|
|
98
|
+
text: string,
|
|
99
|
+
options: ParserOptions
|
|
100
|
+
): MarkdownNode {
|
|
101
|
+
const jsonStr = MarkdownParserModule.parseWithOptions(text, options);
|
|
102
|
+
return JSON.parse(jsonStr) as MarkdownNode;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export type { MarkdownParser };
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Extract text content from a markdown node recursively.
|
|
109
|
+
* Useful for getting plain text from code blocks, headings, etc.
|
|
110
|
+
* @param node - The markdown node to extract text from
|
|
111
|
+
* @returns The concatenated text content
|
|
112
|
+
*/
|
|
113
|
+
export const getTextContent = (node: MarkdownNode): string => {
|
|
114
|
+
if (node.content) return node.content;
|
|
115
|
+
return node.children?.map(getTextContent).join("") ?? "";
|
|
116
|
+
};
|