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.
Files changed (238) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +293 -119
  3. package/android/src/main/cpp/cpp-adapter.cpp +1 -1
  4. package/android/src/main/java/com/margelo/nitro/com/nitromarkdown/HybridMarkdownSession.kt +61 -0
  5. package/android/src/main/java/com/nitromarkdown/NitroMarkdownPackage.kt +5 -1
  6. package/cpp/bindings/HybridMarkdownParser.cpp +2 -2
  7. package/cpp/bindings/HybridMarkdownParser.hpp +2 -2
  8. package/cpp/bindings/HybridMarkdownSession.cpp +0 -0
  9. package/cpp/core/MarkdownSessionCore.cpp +0 -0
  10. package/ios/HybridMarkdownSession.swift +64 -0
  11. package/lib/commonjs/MarkdownContext.js +17 -0
  12. package/lib/commonjs/MarkdownContext.js.map +1 -0
  13. package/lib/commonjs/MarkdownSession.js +11 -0
  14. package/lib/commonjs/MarkdownSession.js.map +1 -0
  15. package/lib/commonjs/default-markdown-renderer.js +217 -0
  16. package/lib/commonjs/default-markdown-renderer.js.map +1 -0
  17. package/lib/commonjs/headless.js +61 -0
  18. package/lib/commonjs/headless.js.map +1 -0
  19. package/lib/commonjs/index.js +220 -13
  20. package/lib/commonjs/index.js.map +1 -1
  21. package/lib/commonjs/markdown-stream.js +32 -0
  22. package/lib/commonjs/markdown-stream.js.map +1 -0
  23. package/lib/commonjs/markdown.js +377 -0
  24. package/lib/commonjs/markdown.js.map +1 -0
  25. package/lib/commonjs/package.json +1 -0
  26. package/lib/commonjs/renderers/blockquote.js +36 -0
  27. package/lib/commonjs/renderers/blockquote.js.map +1 -0
  28. package/lib/commonjs/renderers/code.js +99 -0
  29. package/lib/commonjs/renderers/code.js.map +1 -0
  30. package/lib/commonjs/renderers/heading.js +63 -0
  31. package/lib/commonjs/renderers/heading.js.map +1 -0
  32. package/lib/commonjs/renderers/horizontal-rule.js +29 -0
  33. package/lib/commonjs/renderers/horizontal-rule.js.map +1 -0
  34. package/lib/commonjs/renderers/image.js +163 -0
  35. package/lib/commonjs/renderers/image.js.map +1 -0
  36. package/lib/commonjs/renderers/link.js +35 -0
  37. package/lib/commonjs/renderers/link.js.map +1 -0
  38. package/lib/commonjs/renderers/list.js +118 -0
  39. package/lib/commonjs/renderers/list.js.map +1 -0
  40. package/lib/commonjs/renderers/math.js +127 -0
  41. package/lib/commonjs/renderers/math.js.map +1 -0
  42. package/lib/commonjs/renderers/paragraph.js +39 -0
  43. package/lib/commonjs/renderers/paragraph.js.map +1 -0
  44. package/lib/commonjs/renderers/table.js +290 -0
  45. package/lib/commonjs/renderers/table.js.map +1 -0
  46. package/lib/commonjs/specs/MarkdownSession.nitro.js +6 -0
  47. package/lib/commonjs/specs/MarkdownSession.nitro.js.map +1 -0
  48. package/lib/commonjs/theme.js +191 -0
  49. package/lib/commonjs/theme.js.map +1 -0
  50. package/lib/commonjs/use-markdown-stream.js +71 -0
  51. package/lib/commonjs/use-markdown-stream.js.map +1 -0
  52. package/lib/module/MarkdownContext.js +12 -0
  53. package/lib/module/MarkdownContext.js.map +1 -0
  54. package/lib/module/MarkdownSession.js +7 -0
  55. package/lib/module/MarkdownSession.js.map +1 -0
  56. package/lib/module/default-markdown-renderer.js +212 -0
  57. package/lib/module/default-markdown-renderer.js.map +1 -0
  58. package/lib/module/headless.js +54 -0
  59. package/lib/module/headless.js.map +1 -0
  60. package/lib/module/index.js +18 -10
  61. package/lib/module/index.js.map +1 -1
  62. package/lib/module/markdown-stream.js +27 -0
  63. package/lib/module/markdown-stream.js.map +1 -0
  64. package/lib/module/markdown.js +372 -0
  65. package/lib/module/markdown.js.map +1 -0
  66. package/lib/module/package.json +1 -0
  67. package/lib/module/renderers/blockquote.js +31 -0
  68. package/lib/module/renderers/blockquote.js.map +1 -0
  69. package/lib/module/renderers/code.js +93 -0
  70. package/lib/module/renderers/code.js.map +1 -0
  71. package/lib/module/renderers/heading.js +58 -0
  72. package/lib/module/renderers/heading.js.map +1 -0
  73. package/lib/module/renderers/horizontal-rule.js +24 -0
  74. package/lib/module/renderers/horizontal-rule.js.map +1 -0
  75. package/lib/module/renderers/image.js +158 -0
  76. package/lib/module/renderers/image.js.map +1 -0
  77. package/lib/module/renderers/link.js +30 -0
  78. package/lib/module/renderers/link.js.map +1 -0
  79. package/lib/module/renderers/list.js +111 -0
  80. package/lib/module/renderers/list.js.map +1 -0
  81. package/lib/module/renderers/math.js +121 -0
  82. package/lib/module/renderers/math.js.map +1 -0
  83. package/lib/module/renderers/paragraph.js +34 -0
  84. package/lib/module/renderers/paragraph.js.map +1 -0
  85. package/lib/module/renderers/table.js +285 -0
  86. package/lib/module/renderers/table.js.map +1 -0
  87. package/lib/module/specs/MarkdownSession.nitro.js +4 -0
  88. package/lib/module/specs/MarkdownSession.nitro.js.map +1 -0
  89. package/lib/module/theme.js +186 -0
  90. package/lib/module/theme.js.map +1 -0
  91. package/lib/module/use-markdown-stream.js +66 -0
  92. package/lib/module/use-markdown-stream.js.map +1 -0
  93. package/lib/typescript/commonjs/Markdown.nitro.d.ts.map +1 -0
  94. package/lib/typescript/commonjs/MarkdownContext.d.ts +65 -0
  95. package/lib/typescript/commonjs/MarkdownContext.d.ts.map +1 -0
  96. package/lib/typescript/commonjs/MarkdownSession.d.ts +4 -0
  97. package/lib/typescript/commonjs/MarkdownSession.d.ts.map +1 -0
  98. package/lib/typescript/commonjs/default-markdown-renderer.d.ts +10 -0
  99. package/lib/typescript/commonjs/default-markdown-renderer.d.ts.map +1 -0
  100. package/lib/typescript/commonjs/headless.d.ts +57 -0
  101. package/lib/typescript/commonjs/headless.d.ts.map +1 -0
  102. package/lib/typescript/commonjs/index.d.ts +22 -0
  103. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  104. package/lib/typescript/commonjs/markdown-stream.d.ts +15 -0
  105. package/lib/typescript/commonjs/markdown-stream.d.ts.map +1 -0
  106. package/lib/typescript/commonjs/markdown.d.ts +47 -0
  107. package/lib/typescript/commonjs/markdown.d.ts.map +1 -0
  108. package/lib/typescript/commonjs/package.json +1 -0
  109. package/lib/typescript/commonjs/renderers/blockquote.d.ts +9 -0
  110. package/lib/typescript/commonjs/renderers/blockquote.d.ts.map +1 -0
  111. package/lib/typescript/commonjs/renderers/code.d.ts +19 -0
  112. package/lib/typescript/commonjs/renderers/code.d.ts.map +1 -0
  113. package/lib/typescript/commonjs/renderers/heading.d.ts +10 -0
  114. package/lib/typescript/commonjs/renderers/heading.d.ts.map +1 -0
  115. package/lib/typescript/commonjs/renderers/horizontal-rule.d.ts +8 -0
  116. package/lib/typescript/commonjs/renderers/horizontal-rule.d.ts.map +1 -0
  117. package/lib/typescript/commonjs/renderers/image.d.ts +13 -0
  118. package/lib/typescript/commonjs/renderers/image.d.ts.map +1 -0
  119. package/lib/typescript/commonjs/renderers/link.d.ts +10 -0
  120. package/lib/typescript/commonjs/renderers/link.d.ts.map +1 -0
  121. package/lib/typescript/commonjs/renderers/list.d.ts +26 -0
  122. package/lib/typescript/commonjs/renderers/list.d.ts.map +1 -0
  123. package/lib/typescript/commonjs/renderers/math.d.ts +14 -0
  124. package/lib/typescript/commonjs/renderers/math.d.ts.map +1 -0
  125. package/lib/typescript/commonjs/renderers/paragraph.d.ts +10 -0
  126. package/lib/typescript/commonjs/renderers/paragraph.d.ts.map +1 -0
  127. package/lib/typescript/commonjs/renderers/table.d.ts +12 -0
  128. package/lib/typescript/commonjs/renderers/table.d.ts.map +1 -0
  129. package/lib/typescript/commonjs/specs/MarkdownSession.nitro.d.ts +12 -0
  130. package/lib/typescript/commonjs/specs/MarkdownSession.nitro.d.ts.map +1 -0
  131. package/lib/typescript/commonjs/theme.d.ts +65 -0
  132. package/lib/typescript/commonjs/theme.d.ts.map +1 -0
  133. package/lib/typescript/commonjs/use-markdown-stream.d.ts +22 -0
  134. package/lib/typescript/commonjs/use-markdown-stream.d.ts.map +1 -0
  135. package/lib/typescript/module/Markdown.nitro.d.ts +13 -0
  136. package/lib/typescript/module/Markdown.nitro.d.ts.map +1 -0
  137. package/lib/typescript/module/MarkdownContext.d.ts +65 -0
  138. package/lib/typescript/module/MarkdownContext.d.ts.map +1 -0
  139. package/lib/typescript/module/MarkdownSession.d.ts +4 -0
  140. package/lib/typescript/module/MarkdownSession.d.ts.map +1 -0
  141. package/lib/typescript/module/default-markdown-renderer.d.ts +10 -0
  142. package/lib/typescript/module/default-markdown-renderer.d.ts.map +1 -0
  143. package/lib/typescript/module/headless.d.ts +57 -0
  144. package/lib/typescript/module/headless.d.ts.map +1 -0
  145. package/lib/typescript/module/index.d.ts +22 -0
  146. package/lib/typescript/module/index.d.ts.map +1 -0
  147. package/lib/typescript/module/markdown-stream.d.ts +15 -0
  148. package/lib/typescript/module/markdown-stream.d.ts.map +1 -0
  149. package/lib/typescript/module/markdown.d.ts +47 -0
  150. package/lib/typescript/module/markdown.d.ts.map +1 -0
  151. package/lib/typescript/module/package.json +1 -0
  152. package/lib/typescript/module/renderers/blockquote.d.ts +9 -0
  153. package/lib/typescript/module/renderers/blockquote.d.ts.map +1 -0
  154. package/lib/typescript/module/renderers/code.d.ts +19 -0
  155. package/lib/typescript/module/renderers/code.d.ts.map +1 -0
  156. package/lib/typescript/module/renderers/heading.d.ts +10 -0
  157. package/lib/typescript/module/renderers/heading.d.ts.map +1 -0
  158. package/lib/typescript/module/renderers/horizontal-rule.d.ts +8 -0
  159. package/lib/typescript/module/renderers/horizontal-rule.d.ts.map +1 -0
  160. package/lib/typescript/module/renderers/image.d.ts +13 -0
  161. package/lib/typescript/module/renderers/image.d.ts.map +1 -0
  162. package/lib/typescript/module/renderers/link.d.ts +10 -0
  163. package/lib/typescript/module/renderers/link.d.ts.map +1 -0
  164. package/lib/typescript/module/renderers/list.d.ts +26 -0
  165. package/lib/typescript/module/renderers/list.d.ts.map +1 -0
  166. package/lib/typescript/module/renderers/math.d.ts +14 -0
  167. package/lib/typescript/module/renderers/math.d.ts.map +1 -0
  168. package/lib/typescript/module/renderers/paragraph.d.ts +10 -0
  169. package/lib/typescript/module/renderers/paragraph.d.ts.map +1 -0
  170. package/lib/typescript/module/renderers/table.d.ts +12 -0
  171. package/lib/typescript/module/renderers/table.d.ts.map +1 -0
  172. package/lib/typescript/module/specs/MarkdownSession.nitro.d.ts +12 -0
  173. package/lib/typescript/module/specs/MarkdownSession.nitro.d.ts.map +1 -0
  174. package/lib/typescript/module/theme.d.ts +65 -0
  175. package/lib/typescript/module/theme.d.ts.map +1 -0
  176. package/lib/typescript/module/use-markdown-stream.d.ts +22 -0
  177. package/lib/typescript/module/use-markdown-stream.d.ts.map +1 -0
  178. package/nitro.json +5 -2
  179. package/nitrogen/generated/android/NitroMarkdown+autolinking.cmake +3 -2
  180. package/nitrogen/generated/android/NitroMarkdown+autolinking.gradle +1 -1
  181. package/nitrogen/generated/android/NitroMarkdownOnLoad.cpp +17 -5
  182. package/nitrogen/generated/android/NitroMarkdownOnLoad.hpp +4 -4
  183. package/nitrogen/generated/android/c++/JFunc_void.hpp +75 -0
  184. package/nitrogen/generated/android/c++/JHybridMarkdownSessionSpec.cpp +91 -0
  185. package/nitrogen/generated/android/c++/JHybridMarkdownSessionSpec.hpp +70 -0
  186. package/nitrogen/generated/android/kotlin/com/margelo/nitro/com/nitromarkdown/Func_void.kt +80 -0
  187. package/nitrogen/generated/android/kotlin/com/margelo/nitro/com/nitromarkdown/HybridMarkdownSessionSpec.kt +78 -0
  188. package/nitrogen/generated/android/kotlin/com/margelo/nitro/com/nitromarkdown/NitroMarkdownOnLoad.kt +1 -1
  189. package/nitrogen/generated/ios/NitroMarkdown+autolinking.rb +2 -2
  190. package/nitrogen/generated/ios/NitroMarkdown-Swift-Cxx-Bridge.cpp +28 -4
  191. package/nitrogen/generated/ios/NitroMarkdown-Swift-Cxx-Bridge.hpp +72 -6
  192. package/nitrogen/generated/ios/NitroMarkdown-Swift-Cxx-Umbrella.hpp +11 -4
  193. package/nitrogen/generated/ios/NitroMarkdownAutolinking.mm +11 -3
  194. package/nitrogen/generated/ios/NitroMarkdownAutolinking.swift +16 -3
  195. package/nitrogen/generated/ios/c++/HybridMarkdownSessionSpecSwift.cpp +11 -0
  196. package/nitrogen/generated/ios/c++/HybridMarkdownSessionSpecSwift.hpp +108 -0
  197. package/nitrogen/generated/ios/swift/Func_void.swift +47 -0
  198. package/nitrogen/generated/ios/swift/HybridMarkdownSessionSpec.swift +59 -0
  199. package/nitrogen/generated/ios/swift/HybridMarkdownSessionSpec_cxx.swift +190 -0
  200. package/nitrogen/generated/shared/c++/HybridMarkdownParserSpec.cpp +3 -3
  201. package/nitrogen/generated/shared/c++/HybridMarkdownParserSpec.hpp +4 -4
  202. package/nitrogen/generated/shared/c++/HybridMarkdownSessionSpec.cpp +26 -0
  203. package/nitrogen/generated/shared/c++/HybridMarkdownSessionSpec.hpp +67 -0
  204. package/nitrogen/generated/shared/c++/ParserOptions.hpp +22 -14
  205. package/package.json +45 -7
  206. package/react-native-nitro-markdown.podspec +5 -5
  207. package/src/MarkdownContext.ts +98 -0
  208. package/src/MarkdownSession.ts +8 -0
  209. package/src/default-markdown-renderer.tsx +261 -0
  210. package/src/headless.ts +116 -0
  211. package/src/index.ts +47 -60
  212. package/src/markdown-stream.tsx +32 -0
  213. package/src/markdown.tsx +497 -0
  214. package/src/renderers/blockquote.tsx +30 -0
  215. package/src/renderers/code.tsx +112 -0
  216. package/src/renderers/heading.tsx +66 -0
  217. package/src/renderers/horizontal-rule.tsx +23 -0
  218. package/src/renderers/image.tsx +175 -0
  219. package/src/renderers/link.tsx +33 -0
  220. package/src/renderers/list.tsx +131 -0
  221. package/src/renderers/math.tsx +141 -0
  222. package/src/renderers/paragraph.tsx +47 -0
  223. package/src/renderers/table.tsx +370 -0
  224. package/src/specs/MarkdownSession.nitro.ts +16 -0
  225. package/src/theme.ts +243 -0
  226. package/src/use-markdown-stream.ts +83 -0
  227. package/ios/NitroMarkdown-Bridging-Header.h +0 -14
  228. package/lib/commonjs/MarkdownJS.reference.js +0 -114
  229. package/lib/commonjs/MarkdownJS.reference.js.map +0 -1
  230. package/lib/module/MarkdownJS.reference.js +0 -107
  231. package/lib/module/MarkdownJS.reference.js.map +0 -1
  232. package/lib/typescript/Markdown.nitro.d.ts.map +0 -1
  233. package/lib/typescript/MarkdownJS.reference.d.ts +0 -33
  234. package/lib/typescript/MarkdownJS.reference.d.ts.map +0 -1
  235. package/lib/typescript/index.d.ts +0 -22
  236. package/lib/typescript/index.d.ts.map +0 -1
  237. package/src/MarkdownJS.reference.ts +0 -122
  238. /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,159 +84,330 @@ npx expo prebuild
80
84
 
81
85
  ## 💻 Usage
82
86
 
83
- ### Basic Parsing
87
+ ### Option 1: Batteries Included (Simplest)
84
88
 
85
- The parsing is synchronous and instant. It returns a fully typed JSON AST.
89
+ Use the `Markdown` component with built-in premium dark-mode styling:
86
90
 
87
- ```typescript
88
- import { parseMarkdown } from "react-native-nitro-markdown";
91
+ ```tsx
92
+ import { Markdown } from "react-native-nitro-markdown";
89
93
 
90
- const markdown = `
91
- # Hello World
92
- This is **bold** text and a [link](https://github.com).
93
- `;
94
+ export function MyComponent() {
95
+ return (
96
+ <Markdown options={{ gfm: true }}>
97
+ {"# Hello World\nThis is **bold** text."}
98
+ </Markdown>
99
+ );
100
+ }
101
+ ```
102
+
103
+ ### Option 2: Light Theme / Theme Presets
104
+
105
+ The default theme is optimized for dark mode. For light backgrounds, use the provided `lightMarkdownTheme`:
94
106
 
95
- const ast = parseMarkdown(markdown);
96
- console.log(ast);
97
- // Output: { type: "document", children: [...] }
107
+ ```tsx
108
+ import { Markdown, lightMarkdownTheme } from "react-native-nitro-markdown";
109
+
110
+ <Markdown theme={lightMarkdownTheme}>{"# Light Mode Markdown"}</Markdown>;
98
111
  ```
99
112
 
100
- ### Advanced Options (GFM & Math)
113
+ Available presets:
101
114
 
102
- Enable GitHub Flavored Markdown (Tables, TaskLists) or LaTeX Math support.
115
+ - `defaultMarkdownTheme` / `darkMarkdownTheme` - Modern dark theme
116
+ - `lightMarkdownTheme` - Clean light theme
117
+ - `minimalMarkdownTheme` - Bare minimum styling for a clean slate
103
118
 
104
- ```typescript
105
- import { parseMarkdown } from "react-native-nitro-markdown";
119
+ ### Option 3: Custom Theming
106
120
 
107
- const ast = parseMarkdown(markdown, {
108
- gfm: true, // Tables, Strikethrough, Autolinks, TaskLists
109
- math: true, // $E=mc^2$ and $$block$$
110
- wiki: true, // [[WikiLinks]]
111
- });
121
+ Customize the look and feel by passing a partial `theme` object:
122
+
123
+ ```tsx
124
+ import { Markdown } from "react-native-nitro-markdown";
125
+
126
+ const myTheme = {
127
+ colors: {
128
+ text: "#2D3748",
129
+ heading: "#1A202C",
130
+ link: "#3182CE",
131
+ },
132
+ fontFamilies: {
133
+ regular: "Inter",
134
+ heading: "Inter-Bold",
135
+ mono: "JetBrainsMono",
136
+ },
137
+ borderRadius: {
138
+ s: 4,
139
+ m: 8,
140
+ l: 16,
141
+ },
142
+ showCodeLanguage: true, // Toggle code language labels
143
+ };
144
+
145
+ <Markdown theme={myTheme}>{"# Custom Themed Markdown"}</Markdown>;
112
146
  ```
113
147
 
114
- ---
148
+ **Theme Properties:**
149
+
150
+ - `colors` - All color tokens (text, heading, link, code, codeBackground, codeLanguage, etc.)
151
+ - `spacing` - Spacing tokens (xs, s, m, l, xl)
152
+ - `fontSizes` - Font sizes (xs, s, m, l, xl, h1-h6)
153
+ - `fontFamilies` - Font families for regular, heading, and mono text
154
+ - `borderRadius` - Border radius tokens (s, m, l)
155
+ - `showCodeLanguage` - Show/hide code block language labels
156
+
157
+ ### Option 4: Style Overrides per Node Type
158
+
159
+ Apply quick style overrides to specific node types without writing custom renderers:
160
+
161
+ ```tsx
162
+ <Markdown
163
+ styles={{
164
+ heading: { color: "red", fontWeight: "900" },
165
+ code_block: { backgroundColor: "#1a1a2e", borderRadius: 16 },
166
+ blockquote: { borderLeftColor: "#ff6b6b" },
167
+ }}
168
+ >
169
+ {markdown}
170
+ </Markdown>
171
+ ```
172
+
173
+ ### Option 5: Minimal Styling Strategy
174
+
175
+ Start with a clean slate using the `stylingStrategy` prop:
176
+
177
+ ```tsx
178
+ <Markdown stylingStrategy="minimal" theme={myLightTheme}>
179
+ {content}
180
+ </Markdown>
181
+ ```
182
+
183
+ This zeros out all spacing and removes opinionated colors, letting you build up from scratch.
184
+
185
+ ### Option 6: Custom Renderers
186
+
187
+ Override specific node types with full control. Custom renderers now receive **pre-mapped props** for common values:
188
+
189
+ ```tsx
190
+ import {
191
+ Markdown,
192
+ CodeBlock,
193
+ type HeadingRendererProps,
194
+ type CodeBlockRendererProps,
195
+ } from "react-native-nitro-markdown";
196
+
197
+ const renderers = {
198
+ // Pre-mapped `level` prop - no need for node.level!
199
+ heading: ({ level, children }: HeadingRendererProps) => (
200
+ <MyHeading level={level}>{children}</MyHeading>
201
+ ),
202
+
203
+ // Pre-mapped `content` and `language` - no getTextContent() needed!
204
+ code_block: ({ content, language }: CodeBlockRendererProps) => (
205
+ <CodeBlock
206
+ content={content}
207
+ language={language}
208
+ style={{ borderWidth: 2 }}
209
+ />
210
+ ),
211
+ };
212
+
213
+ <Markdown renderers={renderers} options={{ gfm: true }}>
214
+ {markdown}
215
+ </Markdown>;
216
+ ```
217
+
218
+ **Pre-mapped Props by Node Type:**
115
219
 
116
- ## 🎨 Rendering
220
+ - `heading` → `level` (1-6)
221
+ - `link` → `href`, `title`
222
+ - `image` → `url`, `alt`, `title`
223
+ - `code_block` → `content`, `language`
224
+ - `code_inline` → `content`
225
+ - `list` → `ordered`, `start`
226
+ - `task_list_item` → `checked`
117
227
 
118
- This library is a **Parser Only**. It gives you the raw data (AST) so you can render it with native components (`<Text>`, `<View>`) for maximum performance.
228
+ ### Option 7: Style Props on Individual Renderers
119
229
 
120
- Here is a simple recursive renderer example:
230
+ All built-in renderers accept a `style` prop for fine-grained overrides:
121
231
 
122
232
  ```tsx
123
- import React from "react";
124
- import { Text, View, StyleSheet } from "react-native";
125
- import { parseMarkdown, type MarkdownNode } from "react-native-nitro-markdown";
233
+ import { Heading, CodeBlock, InlineCode } from "react-native-nitro-markdown";
234
+
235
+ // Works in custom renderers
236
+ <Heading level={1} style={{ color: "hotpink" }}>Title</Heading>
237
+ <CodeBlock content={code} style={{ borderRadius: 0 }} />
238
+ <InlineCode style={{ backgroundColor: "#ff0" }}>code</InlineCode>
239
+ ```
240
+
241
+ ### Option 8: Auto Content Extraction for Code
126
242
 
127
- export function MarkdownView({ content }: { content: string }) {
128
- const ast = parseMarkdown(content, { gfm: true });
243
+ The `CodeBlock` and `InlineCode` components now accept a `node` prop for automatic content extraction:
244
+
245
+ ```tsx
246
+ // Before: Manual extraction required
247
+ code_block: ({ node }) => (
248
+ <CodeBlock content={getTextContent(node)} language={node.language} />
249
+ );
250
+
251
+ // After: Just pass the node
252
+ code_block: ({ node }) => <CodeBlock node={node} />;
253
+
254
+ // Or use the pre-mapped content prop (recommended)
255
+ code_block: ({ content, language }) => (
256
+ <CodeBlock content={content} language={language} />
257
+ );
258
+ ```
259
+
260
+ ### Option 9: Headless (Minimal Bundle)
261
+
262
+ For maximum control, data processing, or minimal JS overhead:
263
+
264
+ ```tsx
265
+ import {
266
+ parseMarkdown,
267
+ getTextContent,
268
+ } from "react-native-nitro-markdown/headless";
269
+
270
+ const ast = parseMarkdown("# Hello World");
271
+ const text = getTextContent(ast); // "Hello World"
272
+ ```
273
+
274
+ ### Option 10: High-Performance Streaming (LLMs)
275
+
276
+ When streaming text token-by-token (e.g., from ChatGPT or Gemini):
277
+
278
+ ```tsx
279
+ import {
280
+ MarkdownStream,
281
+ useMarkdownSession,
282
+ } from "react-native-nitro-markdown";
283
+
284
+ export function AIResponseStream() {
285
+ const session = useMarkdownSession();
286
+
287
+ useEffect(() => {
288
+ session.getSession().append("Hello **Nitro**!");
289
+ return () => session.clear();
290
+ }, [session]);
129
291
 
130
292
  return (
131
- <View style={styles.container}>
132
- <Renderer node={ast} />
133
- </View>
293
+ <MarkdownStream session={session.getSession()} options={{ gfm: true }} />
134
294
  );
135
295
  }
296
+ ```
136
297
 
137
- function Renderer({ node }: { node: MarkdownNode }) {
138
- switch (node.type) {
139
- case "document":
140
- return (
141
- <View>
142
- {node.children?.map((child, i) => (
143
- <Renderer key={i} node={child} />
144
- ))}
145
- </View>
146
- );
147
-
148
- case "heading":
149
- return (
150
- <Text style={styles.h1}>
151
- {node.children?.map((c, i) => (
152
- <Renderer key={i} node={c} />
153
- ))}
154
- </Text>
155
- );
156
-
157
- case "paragraph":
158
- return (
159
- <Text style={styles.p}>
160
- {node.children?.map((child, i) => (
161
- <Renderer key={i} node={child} />
162
- ))}
163
- </Text>
164
- );
165
-
166
- case "text":
167
- return <Text>{node.content}</Text>;
168
-
169
- case "bold":
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
- }
298
+ ---
299
+
300
+ ## 🎨 Using Context in Custom Renderers
301
+
302
+ Access theme and context in custom renderers:
303
+
304
+ ```tsx
305
+ import {
306
+ useMarkdownContext,
307
+ MarkdownContext,
308
+ } from "react-native-nitro-markdown";
309
+
310
+ const MyCustomRenderer = ({ children }) => {
311
+ const { theme, stylingStrategy } = useMarkdownContext();
183
312
 
184
- const styles = StyleSheet.create({
185
- container: { padding: 16 },
186
- h1: { fontSize: 24, fontWeight: "bold", marginVertical: 8 },
187
- p: { fontSize: 16, lineHeight: 24, marginBottom: 8 },
188
- bold: { fontWeight: "700" },
189
- });
313
+ return <View style={{ padding: theme.spacing.m }}>{children}</View>;
314
+ };
190
315
  ```
191
316
 
192
317
  ---
193
318
 
319
+ ## 🛠️ Exported Utilities
320
+
321
+ ```tsx
322
+ // Parser and utilities
323
+ export {
324
+ parseMarkdown,
325
+ parseMarkdownWithOptions,
326
+ getTextContent,
327
+ } from "./headless";
328
+
329
+ // Theme presets
330
+ export {
331
+ defaultMarkdownTheme,
332
+ lightMarkdownTheme,
333
+ darkMarkdownTheme,
334
+ minimalMarkdownTheme,
335
+ mergeThemes,
336
+ };
337
+
338
+ // Context
339
+ export { useMarkdownContext, MarkdownContext };
340
+
341
+ // Individual renderers
342
+ export {
343
+ Heading,
344
+ Paragraph,
345
+ Link,
346
+ Blockquote,
347
+ HorizontalRule,
348
+ CodeBlock,
349
+ InlineCode,
350
+ List,
351
+ ListItem,
352
+ TaskListItem,
353
+ TableRenderer,
354
+ Image,
355
+ MathInline,
356
+ MathBlock,
357
+ };
358
+ ```
359
+
360
+ ---
361
+
362
+ ## 🛠️ Headless vs. Non-Headless
363
+
364
+ | Feature | **Headless** (`/headless`) | **Non-Headless** (`default`) |
365
+ | :-------------- | :-------------------------- | :--------------------------------- |
366
+ | **Logic** | Raw C++ md4c Parser | Parser + Full UI Renderer |
367
+ | **Output** | JSON AST Tree | React Native Views |
368
+ | **Best For** | Search Indexing, Custom UIs | Fast Implementation, Documentation |
369
+ | **JS Overhead** | ~4 KB | ~60 KB |
370
+
371
+ ---
372
+
373
+ ### Basic Parsing API
374
+
375
+ The parsing is synchronous and instant. It returns a fully typed JSON AST:
376
+
377
+ ```typescript
378
+ import { parseMarkdown } from "react-native-nitro-markdown/headless";
379
+
380
+ const ast = parseMarkdown(`
381
+ # Hello World
382
+ This is **bold** text and a [link](https://github.com).
383
+ `);
384
+ ```
385
+
386
+ ### Options
387
+
388
+ | Option | Type | Default | Description |
389
+ | :----- | :-------- | :------ | :----------------------------------------------------------------------------- |
390
+ | `gfm` | `boolean` | `false` | Enable GitHub Flavored Markdown (Tables, Strikethrough, Autolinks, TaskLists). |
391
+ | `math` | `boolean` | `false` | Enable LaTeX Math support (`$` and `$$`). |
392
+
393
+ ---
394
+
194
395
  ## 📐 AST Structure
195
396
 
196
- The parser returns a `MarkdownNode` tree. The Types are fully exported for TypeScript support.
397
+ The parser returns a `MarkdownNode` tree:
197
398
 
198
399
  ```typescript
199
400
  export interface MarkdownNode {
200
401
  type: NodeType;
201
- // Content for Text/Code/Math
202
402
  content?: string;
203
- // Hierarchy
204
403
  children?: MarkdownNode[];
205
- // Metadata
206
- level?: number; // Headings (1-6)
207
- href?: string; // Links
208
- checked?: boolean; // Task Lists
209
- language?: string; // Code Blocks
210
- // Table Props
404
+ level?: number;
405
+ href?: string;
406
+ checked?: boolean;
407
+ language?: string;
211
408
  align?: "left" | "center" | "right";
212
409
  isHeader?: boolean;
213
410
  }
214
-
215
- export type NodeType =
216
- | "document"
217
- | "paragraph"
218
- | "text"
219
- | "heading"
220
- | "bold"
221
- | "italic"
222
- | "strikethrough"
223
- | "link"
224
- | "image"
225
- | "code_inline"
226
- | "code_block"
227
- | "blockquote"
228
- | "list"
229
- | "list_item"
230
- | "task_list_item"
231
- | "table"
232
- | "table_row"
233
- | "table_cell"
234
- | "math_inline"
235
- | "math_block";
236
411
  ```
237
412
 
238
413
  ---
@@ -241,16 +416,17 @@ export type NodeType =
241
416
 
242
417
  We parse math delimiters (`$` and `$$`) natively using the `MD_FLAG_LATEXMATHSPANS` flag in `md4c`.
243
418
 
244
- To render the math, you should use a library like `react-native-math-view`, `react-native-mathjax-svg`, or `react-native-katex` inside your renderer:
419
+ To render the math, use a library like `react-native-mathjax-svg`:
245
420
 
246
421
  ```tsx
247
- // Inside your switch(node.type)
248
422
  case 'math_inline':
249
423
  return <MathView math={node.content} style={styles.math} />;
250
424
  case 'math_block':
251
425
  return <MathView math={node.content} style={styles.mathBlock} />;
252
426
  ```
253
427
 
428
+ ---
429
+
254
430
  ## 📊 Package Size
255
431
 
256
432
  | Metric | Size |
@@ -259,8 +435,6 @@ case 'math_block':
259
435
  | **Unpacked** | ~325 kB |
260
436
  | **Total files** | 55 |
261
437
 
262
- > The package includes the [md4c](https://github.com/mity/md4c) C source code (~244 kB) which is compiled natively on iOS and Android. This is a one-time cost that enables the high-performance parsing.
263
-
264
438
  ---
265
439
 
266
440
  ## 🤝 Contributing
@@ -2,6 +2,6 @@
2
2
  #include "NitroMarkdownOnLoad.hpp"
3
3
 
4
4
  JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void*) {
5
- return margelo::nitro::NitroMarkdown::initialize(vm);
5
+ return margelo::nitro::Markdown::initialize(vm);
6
6
  }
7
7
 
@@ -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::NitroMarkdown {
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::NitroMarkdown
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::NitroMarkdown {
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::NitroMarkdown
28
+ } // namespace margelo::nitro::Markdown
File without changes
File without changes