react-native-nitro-markdown 0.1.1 → 0.2.1
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 +142 -84
- 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 +21 -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 +220 -0
- package/lib/commonjs/default-markdown-renderer.js.map +1 -0
- package/lib/commonjs/headless.js +50 -0
- package/lib/commonjs/headless.js.map +1 -0
- package/lib/commonjs/index.js +185 -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 +326 -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 +92 -0
- package/lib/commonjs/renderers/code.js.map +1 -0
- package/lib/commonjs/renderers/heading.js +62 -0
- package/lib/commonjs/renderers/heading.js.map +1 -0
- package/lib/commonjs/renderers/horizontal-rule.js +27 -0
- package/lib/commonjs/renderers/horizontal-rule.js.map +1 -0
- package/lib/commonjs/renderers/image.js +159 -0
- package/lib/commonjs/renderers/image.js.map +1 -0
- package/lib/commonjs/renderers/link.js +37 -0
- package/lib/commonjs/renderers/link.js.map +1 -0
- package/lib/commonjs/renderers/list.js +114 -0
- package/lib/commonjs/renderers/list.js.map +1 -0
- package/lib/commonjs/renderers/math.js +151 -0
- package/lib/commonjs/renderers/math.js.map +1 -0
- package/lib/commonjs/renderers/paragraph.js +44 -0
- package/lib/commonjs/renderers/paragraph.js.map +1 -0
- package/lib/commonjs/renderers/table.js +283 -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 +58 -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 +17 -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 +215 -0
- package/lib/module/default-markdown-renderer.js.map +1 -0
- package/lib/module/headless.js +44 -0
- package/lib/module/headless.js.map +1 -0
- package/lib/module/index.js +36 -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 +321 -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 +86 -0
- package/lib/module/renderers/code.js.map +1 -0
- package/lib/module/renderers/heading.js +57 -0
- package/lib/module/renderers/heading.js.map +1 -0
- package/lib/module/renderers/horizontal-rule.js +22 -0
- package/lib/module/renderers/horizontal-rule.js.map +1 -0
- package/lib/module/renderers/image.js +154 -0
- package/lib/module/renderers/image.js.map +1 -0
- package/lib/module/renderers/link.js +32 -0
- package/lib/module/renderers/link.js.map +1 -0
- package/lib/module/renderers/list.js +107 -0
- package/lib/module/renderers/list.js.map +1 -0
- package/lib/module/renderers/math.js +145 -0
- package/lib/module/renderers/math.js.map +1 -0
- package/lib/module/renderers/paragraph.js +39 -0
- package/lib/module/renderers/paragraph.js.map +1 -0
- package/lib/module/renderers/table.js +278 -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 +54 -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 +26 -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 +50 -0
- package/lib/typescript/commonjs/headless.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +34 -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 +29 -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 +15 -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 +3 -0
- package/lib/typescript/commonjs/renderers/horizontal-rule.d.ts.map +1 -0
- package/lib/typescript/commonjs/renderers/image.d.ts +11 -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 +22 -0
- package/lib/typescript/commonjs/renderers/list.d.ts.map +1 -0
- package/lib/typescript/commonjs/renderers/math.d.ts +15 -0
- package/lib/typescript/commonjs/renderers/math.d.ts.map +1 -0
- package/lib/typescript/commonjs/renderers/paragraph.d.ts +15 -0
- package/lib/typescript/commonjs/renderers/paragraph.d.ts.map +1 -0
- package/lib/typescript/commonjs/renderers/table.d.ts +10 -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 +52 -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 +26 -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 +50 -0
- package/lib/typescript/module/headless.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +34 -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 +29 -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 +15 -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 +3 -0
- package/lib/typescript/module/renderers/horizontal-rule.d.ts.map +1 -0
- package/lib/typescript/module/renderers/image.d.ts +11 -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 +22 -0
- package/lib/typescript/module/renderers/list.d.ts.map +1 -0
- package/lib/typescript/module/renderers/math.d.ts +15 -0
- package/lib/typescript/module/renderers/math.d.ts.map +1 -0
- package/lib/typescript/module/renderers/paragraph.d.ts +15 -0
- package/lib/typescript/module/renderers/paragraph.d.ts.map +1 -0
- package/lib/typescript/module/renderers/table.d.ts +10 -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 +52 -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 -15
- package/react-native-nitro-markdown.podspec +5 -5
- package/src/MarkdownContext.ts +41 -0
- package/src/MarkdownSession.ts +8 -0
- package/src/default-markdown-renderer.tsx +266 -0
- package/src/headless.ts +106 -0
- package/src/index.ts +41 -59
- package/src/markdown-stream.tsx +32 -0
- package/src/markdown.tsx +415 -0
- package/src/renderers/blockquote.tsx +31 -0
- package/src/renderers/code.tsx +88 -0
- package/src/renderers/heading.tsx +66 -0
- package/src/renderers/horizontal-rule.tsx +20 -0
- package/src/renderers/image.tsx +160 -0
- package/src/renderers/link.tsx +38 -0
- package/src/renderers/list.tsx +125 -0
- package/src/renderers/math.tsx +164 -0
- package/src/renderers/paragraph.tsx +53 -0
- package/src/renderers/table.tsx +345 -0
- package/src/specs/MarkdownSession.nitro.ts +16 -0
- package/src/theme.ts +52 -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/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026 João Paulo C. Marra
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<p align="center">
|
|
2
2
|
<img src="./readme/demo.gif" alt="react-native-nitro-markdown demo" width="300" />
|
|
3
|
+
<img src="./readme/stream-demo.gif" alt="react-native-nitro-markdown stream demo" width="300" />
|
|
3
4
|
</p>
|
|
4
5
|
|
|
5
6
|
# react-native-nitro-markdown 🚀
|
|
@@ -41,6 +42,9 @@ Choose your preferred package manager to install the package and its core depend
|
|
|
41
42
|
npm install react-native-nitro-markdown react-native-nitro-modules
|
|
42
43
|
```
|
|
43
44
|
|
|
45
|
+
> **Note:** If you want to use **Math** (LaTeX) or certain **Image** features, you should also install the optional peer dependencies:
|
|
46
|
+
> `npm install react-native-svg react-native-mathjax-svg`
|
|
47
|
+
|
|
44
48
|
**Yarn**
|
|
45
49
|
|
|
46
50
|
```bash
|
|
@@ -80,112 +84,166 @@ npx expo prebuild
|
|
|
80
84
|
|
|
81
85
|
## 💻 Usage
|
|
82
86
|
|
|
83
|
-
###
|
|
84
|
-
|
|
85
|
-
The parsing is synchronous and instant. It returns a fully typed JSON AST.
|
|
87
|
+
### Option 1: Batteries Included (Simplest)
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
import { parseMarkdown } from "react-native-nitro-markdown";
|
|
89
|
+
Use the `Markdown` component with built-in premium dark-mode styling:
|
|
89
90
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
This is **bold** text and a [link](https://github.com).
|
|
93
|
-
`;
|
|
91
|
+
```tsx
|
|
92
|
+
import { Markdown } from "react-native-nitro-markdown";
|
|
94
93
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
export function MyComponent() {
|
|
95
|
+
return (
|
|
96
|
+
<Markdown options={{ gfm: true }}>
|
|
97
|
+
{"# Hello World\nThis is **bold** text."}
|
|
98
|
+
</Markdown>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
98
101
|
```
|
|
99
102
|
|
|
100
|
-
###
|
|
103
|
+
### Option 2: Custom Renderers
|
|
101
104
|
|
|
102
|
-
|
|
105
|
+
Override specific node types while keeping defaults for everything else:
|
|
103
106
|
|
|
104
|
-
```
|
|
105
|
-
import {
|
|
107
|
+
```tsx
|
|
108
|
+
import {
|
|
109
|
+
Markdown,
|
|
110
|
+
Heading,
|
|
111
|
+
type CustomRenderers,
|
|
112
|
+
} from "react-native-nitro-markdown";
|
|
113
|
+
import MathJax from "react-native-mathjax-svg";
|
|
114
|
+
|
|
115
|
+
const renderers: CustomRenderers = {
|
|
116
|
+
// Custom styled heading
|
|
117
|
+
heading: ({ node, children }) => (
|
|
118
|
+
<Heading level={node.level ?? 1}>
|
|
119
|
+
<Text style={{ color: "pink" }}>{children}</Text>
|
|
120
|
+
</Heading>
|
|
121
|
+
),
|
|
122
|
+
// Custom math renderer
|
|
123
|
+
math_inline: ({ node }) => <MathJax fontSize={16}>{node.content}</MathJax>,
|
|
124
|
+
math_block: ({ node }) => <MathJax fontSize={20}>{node.content}</MathJax>,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
<Markdown renderers={renderers} options={{ gfm: true, math: true }}>
|
|
128
|
+
{markdown}
|
|
129
|
+
</Markdown>;
|
|
130
|
+
```
|
|
106
131
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
132
|
+
### Option 3: Custom Theming
|
|
133
|
+
|
|
134
|
+
You can easily customize the look and feel of the default components by passing a `theme` object. This allows you to match your app's brand without writing custom renderers for everything.
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
import { Markdown } from "react-native-nitro-markdown";
|
|
138
|
+
|
|
139
|
+
const myTheme = {
|
|
140
|
+
colors: {
|
|
141
|
+
text: "#2D3748",
|
|
142
|
+
heading: "#1A202C",
|
|
143
|
+
link: "#3182CE",
|
|
144
|
+
tableBorder: "#E2E8F0",
|
|
145
|
+
tableHeader: "#F7FAFC",
|
|
146
|
+
},
|
|
147
|
+
spacing: {
|
|
148
|
+
m: 16,
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
<Markdown theme={myTheme}>{"# Custom Branded Markdown"}</Markdown>;
|
|
153
|
+
|
|
154
|
+
> **Tip:** The default theme is optimized for Dark Mode. For Light Mode, pass a custom theme object or check out the [theme source](packages/react-native-nitro-markdown/src/theme.ts) to see all available tokens.
|
|
112
155
|
```
|
|
113
156
|
|
|
114
|
-
|
|
157
|
+
### Option 4: Headless (Minimal Bundle)
|
|
115
158
|
|
|
116
|
-
|
|
159
|
+
For maximum control, data processing, or minimal JS overhead:
|
|
117
160
|
|
|
118
|
-
|
|
161
|
+
```tsx
|
|
162
|
+
/**
|
|
163
|
+
* Only imports the parser.
|
|
164
|
+
* Zero UI overhead, purely synchronous AST generation.
|
|
165
|
+
*/
|
|
166
|
+
import { parseMarkdown } from "react-native-nitro-markdown/headless";
|
|
167
|
+
|
|
168
|
+
const ast = parseMarkdown("# Hello World");
|
|
169
|
+
```
|
|
119
170
|
|
|
120
|
-
|
|
171
|
+
### Option 5: High-Performance Streaming (LLMs)
|
|
172
|
+
|
|
173
|
+
When streaming text token-by-token (e.g., from ChatGPT or Gemini), re-parsing the entire document in JavaScript for every token is too slow.
|
|
174
|
+
|
|
175
|
+
**Nitro Markdown** enables **Native Streaming** via JSI. The text buffer is maintained in C++ and updates are pushed directly to the native view, bypassing React completely.
|
|
121
176
|
|
|
122
177
|
```tsx
|
|
123
|
-
import
|
|
124
|
-
|
|
125
|
-
|
|
178
|
+
import {
|
|
179
|
+
MarkdownStream,
|
|
180
|
+
useMarkdownSession,
|
|
181
|
+
} from "react-native-nitro-markdown";
|
|
182
|
+
|
|
183
|
+
export function AIResponseStream() {
|
|
184
|
+
// 1. Create a native session
|
|
185
|
+
const session = useMarkdownSession();
|
|
126
186
|
|
|
127
|
-
|
|
128
|
-
|
|
187
|
+
useEffect(() => {
|
|
188
|
+
// 2. Append chunks directly to C++ (Zero-Latency)
|
|
189
|
+
// Example: Socket.on('data', (chunk) => session.getSession().append(chunk));
|
|
129
190
|
|
|
191
|
+
session.getSession().append("Hello **Nitro**!");
|
|
192
|
+
|
|
193
|
+
return () => session.clear();
|
|
194
|
+
}, [session]);
|
|
195
|
+
|
|
196
|
+
// 3. Render the localized stream component
|
|
130
197
|
return (
|
|
131
|
-
<
|
|
132
|
-
<Renderer node={ast} />
|
|
133
|
-
</View>
|
|
198
|
+
<MarkdownStream session={session.getSession()} options={{ gfm: true }} />
|
|
134
199
|
);
|
|
135
200
|
}
|
|
201
|
+
```
|
|
136
202
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
return (
|
|
171
|
-
<Text style={styles.bold}>
|
|
172
|
-
{node.children?.map((c, i) => (
|
|
173
|
-
<Renderer key={i} node={c} />
|
|
174
|
-
))}
|
|
175
|
-
</Text>
|
|
176
|
-
);
|
|
177
|
-
|
|
178
|
-
// Handle 'table', 'code_block', 'math_inline' etc...
|
|
179
|
-
default:
|
|
180
|
-
return null;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## 🛠️ Headless vs. Non-Headless
|
|
206
|
+
|
|
207
|
+
| Feature | **Headless** (`/headless`) | **Non-Headless** (`default`) |
|
|
208
|
+
| :-------------- | :-------------------------- | :--------------------------------- |
|
|
209
|
+
| **Logic** | Raw C++ md4c Parser | Parser + Full UI Renderer |
|
|
210
|
+
| **Output** | JSON AST Tree | React Native Views |
|
|
211
|
+
| **Best For** | Search Indexing, Custom UIs | Fast Implementation, Documentation |
|
|
212
|
+
| **JS Overhead** | ~4 KB | ~60 KB |
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
### Basic Parsing API
|
|
217
|
+
The parsing is synchronous and instant. It returns a fully typed JSON AST. We recommend using the `/headless` entry point if you only need the parser.
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
import { parseMarkdown } from "react-native-nitro-markdown/headless";
|
|
221
|
+
|
|
222
|
+
const ast = parseMarkdown(`
|
|
223
|
+
# Hello World
|
|
224
|
+
This is **bold** text and a [link](https://github.com).
|
|
225
|
+
`);
|
|
226
|
+
console.log(ast);
|
|
227
|
+
// Output: { type: "document", children: [...] }
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Options
|
|
231
|
+
|
|
232
|
+
| Option | Type | Default | Description |
|
|
233
|
+
| :--- | :--- | :--- | :--- |
|
|
234
|
+
| `gfm` | `boolean` | `false` | Enable GitHub Flavored Markdown (Tables, Strikethrough, Autolinks, TaskLists). |
|
|
235
|
+
| `math` | `boolean` | `false` | Enable LaTeX Math support (`$` and `$$`). |
|
|
183
236
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
237
|
+
### Parser Options (GFM & Math)
|
|
238
|
+
|
|
239
|
+
Enable GitHub Flavored Markdown (Tables, TaskLists) or LaTeX Math support.
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import { parseMarkdownWithOptions } from "react-native-nitro-markdown/headless";
|
|
243
|
+
|
|
244
|
+
const ast = parseMarkdownWithOptions(markdown, {
|
|
245
|
+
gfm: true, // Tables (supports complex nested content!), Strikethrough, Autolinks, TaskLists
|
|
246
|
+
math: true, // $E=mc^2$ and $$block$$
|
|
189
247
|
});
|
|
190
248
|
```
|
|
191
249
|
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
package com.margelo.nitro.com.nitromarkdown
|
|
2
|
+
|
|
3
|
+
class HybridMarkdownSession : HybridMarkdownSessionSpec() {
|
|
4
|
+
private var buffer = StringBuilder()
|
|
5
|
+
private val listeners = mutableMapOf<Long, () -> Unit>()
|
|
6
|
+
private var nextListenerId = 0L
|
|
7
|
+
private val lock = Any()
|
|
8
|
+
|
|
9
|
+
override var highlightPosition: Double = 0.0
|
|
10
|
+
set(value) {
|
|
11
|
+
synchronized(lock) { field = value }
|
|
12
|
+
// No notify for highlighting to avoid flood
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
override val memorySize: Long
|
|
18
|
+
get() = buffer.length.toLong()
|
|
19
|
+
|
|
20
|
+
override fun append(chunk: String) {
|
|
21
|
+
synchronized(lock) {
|
|
22
|
+
buffer.append(chunk)
|
|
23
|
+
}
|
|
24
|
+
notifyListeners()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
override fun clear() {
|
|
28
|
+
synchronized(lock) {
|
|
29
|
+
buffer.clear()
|
|
30
|
+
highlightPosition = 0.0
|
|
31
|
+
}
|
|
32
|
+
notifyListeners()
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
override fun getAllText(): String {
|
|
36
|
+
synchronized(lock) {
|
|
37
|
+
return buffer.toString()
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
override fun addListener(listener: () -> Unit): () -> Unit {
|
|
42
|
+
val id: Long
|
|
43
|
+
synchronized(lock) {
|
|
44
|
+
id = nextListenerId++
|
|
45
|
+
listeners[id] = listener
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
synchronized(lock) {
|
|
49
|
+
listeners.remove(id)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private fun notifyListeners() {
|
|
55
|
+
val currentListeners: Collection<() -> Unit>
|
|
56
|
+
synchronized(lock) {
|
|
57
|
+
currentListeners = listeners.values.toList()
|
|
58
|
+
}
|
|
59
|
+
currentListeners.forEach { it() }
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -4,6 +4,7 @@ import com.facebook.react.TurboReactPackage
|
|
|
4
4
|
import com.facebook.react.bridge.NativeModule
|
|
5
5
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
6
|
import com.facebook.react.module.model.ReactModuleInfoProvider
|
|
7
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
8
|
|
|
8
9
|
class NitroMarkdownPackage : TurboReactPackage() {
|
|
9
10
|
companion object {
|
|
@@ -19,5 +20,8 @@ class NitroMarkdownPackage : TurboReactPackage() {
|
|
|
19
20
|
override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
|
|
20
21
|
return ReactModuleInfoProvider { emptyMap() }
|
|
21
22
|
}
|
|
22
|
-
}
|
|
23
23
|
|
|
24
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
25
|
+
return emptyList()
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
#include <sstream>
|
|
3
3
|
#include <iomanip>
|
|
4
4
|
|
|
5
|
-
namespace margelo::nitro::
|
|
5
|
+
namespace margelo::nitro::Markdown {
|
|
6
6
|
|
|
7
7
|
std::string HybridMarkdownParser::parse(const std::string& text) {
|
|
8
8
|
InternalParserOptions opts;
|
|
@@ -109,4 +109,4 @@ std::string HybridMarkdownParser::nodeToJson(const std::shared_ptr<InternalMarkd
|
|
|
109
109
|
return json.str();
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
} // namespace margelo::nitro::
|
|
112
|
+
} // namespace margelo::nitro::Markdown
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
#include "../core/MD4CParser.hpp"
|
|
5
5
|
#include <memory>
|
|
6
6
|
|
|
7
|
-
namespace margelo::nitro::
|
|
7
|
+
namespace margelo::nitro::Markdown {
|
|
8
8
|
|
|
9
9
|
using InternalMarkdownNode = ::NitroMarkdown::MarkdownNode;
|
|
10
10
|
using InternalParserOptions = ::NitroMarkdown::ParserOptions;
|
|
@@ -25,4 +25,4 @@ private:
|
|
|
25
25
|
std::string nodeToJson(const std::shared_ptr<InternalMarkdownNode>& node);
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
} // namespace margelo::nitro::
|
|
28
|
+
} // namespace margelo::nitro::Markdown
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import NitroModules
|
|
3
|
+
|
|
4
|
+
class HybridMarkdownSession: HybridMarkdownSessionSpec {
|
|
5
|
+
private var buffer = ""
|
|
6
|
+
private var listeners: [UUID: () -> Void] = [:]
|
|
7
|
+
private let lock = NSLock()
|
|
8
|
+
|
|
9
|
+
private(set) var version: Int = 0
|
|
10
|
+
|
|
11
|
+
var highlightPosition: Double = 0
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
var memorySize: Int {
|
|
16
|
+
return buffer.utf8.count + MemoryLayout<HybridMarkdownSession>.size
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
func append(chunk: String) throws {
|
|
20
|
+
lock.lock()
|
|
21
|
+
buffer += chunk
|
|
22
|
+
version += 1
|
|
23
|
+
lock.unlock()
|
|
24
|
+
notifyListeners()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
func clear() throws {
|
|
28
|
+
lock.lock()
|
|
29
|
+
buffer = ""
|
|
30
|
+
highlightPosition = 0
|
|
31
|
+
version += 1
|
|
32
|
+
lock.unlock()
|
|
33
|
+
notifyListeners()
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
func getAllText() throws -> String {
|
|
37
|
+
lock.lock()
|
|
38
|
+
defer { lock.unlock() }
|
|
39
|
+
return buffer
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
func addListener(listener: @escaping () -> Void) throws -> () -> Void {
|
|
43
|
+
let id = UUID()
|
|
44
|
+
lock.lock()
|
|
45
|
+
listeners[id] = listener
|
|
46
|
+
lock.unlock()
|
|
47
|
+
|
|
48
|
+
return { [weak self] in
|
|
49
|
+
self?.lock.lock()
|
|
50
|
+
self?.listeners.removeValue(forKey: id)
|
|
51
|
+
self?.lock.unlock()
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private func notifyListeners() {
|
|
56
|
+
lock.lock()
|
|
57
|
+
let currentListeners = Array(listeners.values)
|
|
58
|
+
lock.unlock()
|
|
59
|
+
|
|
60
|
+
for listener in currentListeners {
|
|
61
|
+
listener()
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useMarkdownContext = exports.MarkdownContext = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _theme = require("./theme.js");
|
|
9
|
+
/**
|
|
10
|
+
* Object mapping node types to custom renderers.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// Context for custom renderers and theme
|
|
14
|
+
|
|
15
|
+
const MarkdownContext = exports.MarkdownContext = /*#__PURE__*/(0, _react.createContext)({
|
|
16
|
+
renderers: {},
|
|
17
|
+
theme: _theme.defaultMarkdownTheme
|
|
18
|
+
});
|
|
19
|
+
const useMarkdownContext = () => (0, _react.useContext)(MarkdownContext);
|
|
20
|
+
exports.useMarkdownContext = useMarkdownContext;
|
|
21
|
+
//# sourceMappingURL=MarkdownContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","require","_theme","MarkdownContext","exports","createContext","renderers","theme","defaultMarkdownTheme","useMarkdownContext","useContext"],"sourceRoot":"../../src","sources":["MarkdownContext.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AAoBA;AACA;AACA;;AAKA;;AAMO,MAAME,eAAe,GAAAC,OAAA,CAAAD,eAAA,gBAAG,IAAAE,oBAAa,EAAuB;EACjEC,SAAS,EAAE,CAAC,CAAC;EACbC,KAAK,EAAEC;AACT,CAAC,CAAC;AAEK,MAAMC,kBAAkB,GAAGA,CAAA,KAAM,IAAAC,iBAAU,EAACP,eAAe,CAAC;AAACC,OAAA,CAAAK,kBAAA,GAAAA,kBAAA","ignoreList":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createMarkdownSession = createMarkdownSession;
|
|
7
|
+
var _reactNativeNitroModules = require("react-native-nitro-modules");
|
|
8
|
+
function createMarkdownSession() {
|
|
9
|
+
return _reactNativeNitroModules.NitroModules.createHybridObject("MarkdownSession");
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=MarkdownSession.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_reactNativeNitroModules","require","createMarkdownSession","NitroModules","createHybridObject"],"sourceRoot":"../../src","sources":["MarkdownSession.ts"],"mappings":";;;;;;AAAA,IAAAA,wBAAA,GAAAC,OAAA;AAKO,SAASC,qBAAqBA,CAAA,EAAoB;EACvD,OAAOC,qCAAY,CAACC,kBAAkB,CAAkB,iBAAiB,CAAC;AAC5E","ignoreList":[]}
|