react-native-nitro-markdown 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +257 -682
- package/android/CMakeLists.txt +8 -1
- package/android/build.gradle +9 -2
- package/android/consumer-rules.pro +31 -0
- package/android/gradle.properties +2 -0
- package/android/src/main/cpp/cpp-adapter.cpp +4 -1
- package/android/src/main/java/com/margelo/nitro/com/nitromarkdown/HybridMarkdownSession.kt +61 -21
- package/android/src/main/java/com/nitromarkdown/NitroMarkdownPackage.kt +6 -18
- package/cpp/bindings/HybridMarkdownParser.cpp +38 -12
- package/cpp/bindings/HybridMarkdownParser.hpp +4 -4
- package/cpp/bindings/HybridMarkdownSession.cpp +2 -0
- package/cpp/core/MD4CParser.cpp +128 -85
- package/cpp/core/MarkdownSessionCore.cpp +2 -0
- package/ios/HybridMarkdownSession.swift +89 -46
- package/lib/commonjs/headless.js +33 -7
- package/lib/commonjs/headless.js.map +1 -1
- package/lib/commonjs/index.js +48 -38
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/markdown-stream.js +1 -1
- package/lib/commonjs/markdown-stream.js.map +1 -1
- package/lib/commonjs/markdown.js +47 -10
- package/lib/commonjs/markdown.js.map +1 -1
- package/lib/commonjs/renderers/code.js +1 -1
- package/lib/commonjs/renderers/code.js.map +1 -1
- package/lib/commonjs/renderers/image.js +6 -1
- package/lib/commonjs/renderers/image.js.map +1 -1
- package/lib/commonjs/renderers/link.js +7 -2
- package/lib/commonjs/renderers/link.js.map +1 -1
- package/lib/commonjs/renderers/list.js +2 -0
- package/lib/commonjs/renderers/list.js.map +1 -1
- package/lib/commonjs/renderers/math.js +4 -2
- package/lib/commonjs/renderers/math.js.map +1 -1
- package/lib/commonjs/renderers/table/cell-content.js +1 -1
- package/lib/commonjs/renderers/table/cell-content.js.map +1 -1
- package/lib/commonjs/renderers/table/index.js +10 -2
- package/lib/commonjs/renderers/table/index.js.map +1 -1
- package/lib/commonjs/theme.js +7 -7
- package/lib/commonjs/theme.js.map +1 -1
- package/lib/commonjs/utils/code-highlight.js +24 -25
- package/lib/commonjs/utils/code-highlight.js.map +1 -1
- package/lib/module/headless.js +34 -6
- package/lib/module/headless.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/markdown-stream.js +1 -1
- package/lib/module/markdown-stream.js.map +1 -1
- package/lib/module/markdown.js +48 -11
- package/lib/module/markdown.js.map +1 -1
- package/lib/module/renderers/code.js +1 -1
- package/lib/module/renderers/code.js.map +1 -1
- package/lib/module/renderers/image.js +6 -1
- package/lib/module/renderers/image.js.map +1 -1
- package/lib/module/renderers/link.js +7 -2
- package/lib/module/renderers/link.js.map +1 -1
- package/lib/module/renderers/list.js +2 -0
- package/lib/module/renderers/list.js.map +1 -1
- package/lib/module/renderers/math.js +4 -2
- package/lib/module/renderers/math.js.map +1 -1
- package/lib/module/renderers/table/cell-content.js +1 -1
- package/lib/module/renderers/table/cell-content.js.map +1 -1
- package/lib/module/renderers/table/index.js +10 -2
- package/lib/module/renderers/table/index.js.map +1 -1
- package/lib/module/theme.js +7 -7
- package/lib/module/theme.js.map +1 -1
- package/lib/module/utils/code-highlight.js +24 -25
- package/lib/module/utils/code-highlight.js.map +1 -1
- package/lib/typescript/commonjs/headless.d.ts +9 -1
- package/lib/typescript/commonjs/headless.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +3 -2
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/markdown-stream.d.ts.map +1 -1
- package/lib/typescript/commonjs/markdown.d.ts +7 -2
- package/lib/typescript/commonjs/markdown.d.ts.map +1 -1
- package/lib/typescript/commonjs/renderers/code.d.ts.map +1 -1
- package/lib/typescript/commonjs/renderers/image.d.ts.map +1 -1
- package/lib/typescript/commonjs/renderers/link.d.ts.map +1 -1
- package/lib/typescript/commonjs/renderers/list.d.ts.map +1 -1
- package/lib/typescript/commonjs/renderers/math.d.ts.map +1 -1
- package/lib/typescript/commonjs/renderers/table/cell-content.d.ts +4 -3
- package/lib/typescript/commonjs/renderers/table/cell-content.d.ts.map +1 -1
- package/lib/typescript/commonjs/renderers/table/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme.d.ts.map +1 -1
- package/lib/typescript/commonjs/utils/code-highlight.d.ts +1 -1
- package/lib/typescript/commonjs/utils/code-highlight.d.ts.map +1 -1
- package/lib/typescript/module/headless.d.ts +9 -1
- package/lib/typescript/module/headless.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +3 -2
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/markdown-stream.d.ts.map +1 -1
- package/lib/typescript/module/markdown.d.ts +7 -2
- package/lib/typescript/module/markdown.d.ts.map +1 -1
- package/lib/typescript/module/renderers/code.d.ts.map +1 -1
- package/lib/typescript/module/renderers/image.d.ts.map +1 -1
- package/lib/typescript/module/renderers/link.d.ts.map +1 -1
- package/lib/typescript/module/renderers/list.d.ts.map +1 -1
- package/lib/typescript/module/renderers/math.d.ts.map +1 -1
- package/lib/typescript/module/renderers/table/cell-content.d.ts +4 -3
- package/lib/typescript/module/renderers/table/cell-content.d.ts.map +1 -1
- package/lib/typescript/module/renderers/table/index.d.ts.map +1 -1
- package/lib/typescript/module/theme.d.ts.map +1 -1
- package/lib/typescript/module/utils/code-highlight.d.ts +1 -1
- package/lib/typescript/module/utils/code-highlight.d.ts.map +1 -1
- package/package.json +5 -3
- package/src/headless.ts +57 -7
- package/src/index.ts +16 -2
- package/src/markdown-stream.tsx +1 -0
- package/src/markdown.tsx +98 -31
- package/src/renderers/code.tsx +23 -16
- package/src/renderers/image.tsx +9 -1
- package/src/renderers/link.tsx +8 -2
- package/src/renderers/list.tsx +2 -0
- package/src/renderers/math.tsx +6 -2
- package/src/renderers/table/cell-content.tsx +15 -4
- package/src/renderers/table/index.tsx +15 -3
- package/src/theme.ts +34 -14
- package/src/utils/code-highlight.ts +133 -44
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../../src/markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../../src/markdown.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code.d.ts","sourceRoot":"","sources":["../../../../src/renderers/code.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAML,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"code.d.ts","sourceRoot":"","sources":["../../../../src/renderers/code.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAML,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAOtB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,KAAK,cAAc,GAAG;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,cAAc,CAwFxC,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CA8B1C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../../src/renderers/image.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,EAAE,EACP,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AACf,OAAO,EAML,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAGtB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAkB5D,KAAK,UAAU,GAAG;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAC5C,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC,UAAU,
|
|
1
|
+
{"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../../src/renderers/image.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,EAAE,EACP,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AACf,OAAO,EAML,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAGtB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAkB5D,KAAK,UAAU,GAAG;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAC5C,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,EAAE,CAAC,UAAU,CA6KhC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../../src/renderers/link.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAOtB,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,EAAE,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../../../src/renderers/link.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAOtB,KAAK,SAAS,GAAG;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,IAAI,EAAE,EAAE,CAAC,SAAS,CA6C9B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/renderers/list.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAGhF,KAAK,SAAS,GAAG;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../../src/renderers/list.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,EAAE,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAGhF,KAAK,SAAS,GAAG;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAIF,eAAO,MAAM,IAAI,EAAE,EAAE,CAAC,SAAS,CAoB9B,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,EAAE,CAAC,aAAa,CAwCtC,CAAC;AAEF,KAAK,iBAAiB,GAAG;IACvB,QAAQ,EAAE,SAAS,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAqD9C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../../../../src/renderers/math.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,EAAE,EAAsB,MAAM,OAAO,CAAC;AAC7D,OAAO,EAML,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../../../../src/renderers/math.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,EAAE,EAAsB,MAAM,OAAO,CAAC;AAC7D,OAAO,EAML,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAyBtB,KAAK,eAAe,GAAG;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAwDF,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,eAAe,CA2B1C,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,EAAE,CAAC,cAAc,CA0BxC,CAAC"}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { type StyleProp, type TextStyle } from "react-native";
|
|
1
|
+
import type { FC, ComponentType } from "react";
|
|
2
|
+
import { type StyleProp, type TextStyle, type ViewStyle } from "react-native";
|
|
3
3
|
import type { MarkdownNode } from "../../headless";
|
|
4
4
|
import type { NodeRendererProps } from "../../MarkdownContext";
|
|
5
5
|
type CellContentProps = {
|
|
6
6
|
node: MarkdownNode;
|
|
7
7
|
Renderer: ComponentType<NodeRendererProps>;
|
|
8
8
|
styles: {
|
|
9
|
-
cellContentWrapper:
|
|
9
|
+
cellContentWrapper: StyleProp<ViewStyle>;
|
|
10
|
+
[key: string]: StyleProp<ViewStyle | TextStyle> | undefined;
|
|
10
11
|
};
|
|
11
12
|
textStyle?: StyleProp<TextStyle>;
|
|
12
13
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cell-content.d.ts","sourceRoot":"","sources":["../../../../../src/renderers/table/cell-content.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"cell-content.d.ts","sourceRoot":"","sources":["../../../../../src/renderers/table/cell-content.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAGL,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAC3C,MAAM,EAAE;QACN,kBAAkB,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;QACzC,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;KAC7D,CAAC;IACF,SAAS,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CA2B5C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/renderers/table/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,EAAE,EACP,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AACf,OAAO,EAKL,KAAK,SAAS,EAEf,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/renderers/table/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,EAAE,EACP,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AACf,OAAO,EAKL,KAAK,SAAS,EAEf,MAAM,cAAc,CAAC;AAQtB,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,uBAAuB,CAAC;AAG/B,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,OAAO,gBAAgB,EAAE,YAAY,CAAC;IAC5C,QAAQ,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAC3C,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAQF,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,kBAAkB,CAwShD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../../src/theme.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../../src/theme.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type TokenType =
|
|
1
|
+
export type TokenType = "keyword" | "string" | "comment" | "number" | "operator" | "punctuation" | "type" | "default";
|
|
2
2
|
export type HighlightedToken = {
|
|
3
3
|
text: string;
|
|
4
4
|
type: TokenType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-highlight.d.ts","sourceRoot":"","sources":["../../../../src/utils/code-highlight.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,UAAU,GACV,aAAa,GACb,MAAM,GACN,SAAS,CAAC;AAEd,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AACjE,MAAM,MAAM,eAAe,GAAG,
|
|
1
|
+
{"version":3,"file":"code-highlight.d.ts","sourceRoot":"","sources":["../../../../src/utils/code-highlight.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,UAAU,GACV,aAAa,GACb,MAAM,GACN,SAAS,CAAC;AAEd,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AACjE,MAAM,MAAM,eAAe,GAAG,CAC5B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,KACT,gBAAgB,EAAE,CAAC;AA8JxB,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,gBAAgB,EAAE,CAepB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-nitro-markdown",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
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",
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"!cpp/build",
|
|
48
48
|
"!android/build",
|
|
49
49
|
"!android/.cxx",
|
|
50
|
+
"!ios/build",
|
|
50
51
|
"!scripts"
|
|
51
52
|
],
|
|
52
53
|
"scripts": {
|
|
@@ -54,7 +55,7 @@
|
|
|
54
55
|
"build": "bob build",
|
|
55
56
|
"clean": "rimraf lib nitrogen/generated",
|
|
56
57
|
"codegen": "nitrogen --logLevel=\"debug\"",
|
|
57
|
-
"lint": "eslint src --max-warnings=0 --ignore-pattern 'src/**/__tests__/**' --ignore-pattern 'src/**/*.nitro.ts'",
|
|
58
|
+
"lint": "bunx eslint src --max-warnings=0 --ignore-pattern 'src/**/__tests__/**' --ignore-pattern 'src/**/*.nitro.ts'",
|
|
58
59
|
"typecheck": "tsc --noEmit",
|
|
59
60
|
"test": "jest",
|
|
60
61
|
"test:coverage": "jest --coverage",
|
|
@@ -80,6 +81,7 @@
|
|
|
80
81
|
},
|
|
81
82
|
"author": "João Paulo C. Marra <joaopaulocmarra@gmail.com>",
|
|
82
83
|
"license": "MIT",
|
|
84
|
+
"sideEffects": false,
|
|
83
85
|
"bugs": {
|
|
84
86
|
"url": "https://github.com/JoaoPauloCMarra/react-native-nitro-markdown/issues"
|
|
85
87
|
},
|
|
@@ -89,7 +91,7 @@
|
|
|
89
91
|
},
|
|
90
92
|
"devDependencies": {
|
|
91
93
|
"@size-limit/preset-small-lib": "^11.0.0",
|
|
92
|
-
"@types/react": "
|
|
94
|
+
"@types/react": "~19.2.10",
|
|
93
95
|
"@types/react-native": "^0.73.0",
|
|
94
96
|
"@types/react-test-renderer": "^19.1.0",
|
|
95
97
|
"react-native-builder-bob": "^0.40.18",
|
package/src/headless.ts
CHANGED
|
@@ -79,20 +79,55 @@ export type MarkdownNode = {
|
|
|
79
79
|
children?: MarkdownNode[];
|
|
80
80
|
};
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
let MarkdownParserModule: MarkdownParser | null = null;
|
|
83
|
+
try {
|
|
84
|
+
MarkdownParserModule =
|
|
85
|
+
NitroModules.createHybridObject<MarkdownParser>("MarkdownParser");
|
|
86
|
+
} catch (e) {
|
|
87
|
+
if (__DEV__) {
|
|
88
|
+
// eslint-disable-next-line no-console
|
|
89
|
+
console.error("[NitroMarkdown] Failed to create native MarkdownParser:", e);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export { MarkdownParserModule };
|
|
84
93
|
|
|
85
94
|
/**
|
|
86
95
|
* Parse markdown text into an AST.
|
|
87
96
|
* @param text - The markdown text to parse
|
|
88
97
|
* @returns The root node of the parsed AST
|
|
89
98
|
*/
|
|
90
|
-
export function parseMarkdown(text: string): MarkdownNode
|
|
91
|
-
|
|
99
|
+
export function parseMarkdown(text: string): MarkdownNode;
|
|
100
|
+
/**
|
|
101
|
+
* Parse markdown text with custom options.
|
|
102
|
+
* @param text - The markdown text to parse
|
|
103
|
+
* @param options - Parser options (gfm, math)
|
|
104
|
+
* @returns The root node of the parsed AST
|
|
105
|
+
*/
|
|
106
|
+
export function parseMarkdown(
|
|
107
|
+
text: string,
|
|
108
|
+
options: ParserOptions,
|
|
109
|
+
): MarkdownNode;
|
|
110
|
+
export function parseMarkdown(
|
|
111
|
+
text: string,
|
|
112
|
+
options?: ParserOptions,
|
|
113
|
+
): MarkdownNode {
|
|
114
|
+
if (options != null) {
|
|
115
|
+
return parseMarkdownWithOptions(text, options);
|
|
116
|
+
}
|
|
117
|
+
if (
|
|
118
|
+
MarkdownParserModule != null &&
|
|
119
|
+
typeof MarkdownParserModule.parse === "function"
|
|
120
|
+
) {
|
|
92
121
|
const jsonStr = MarkdownParserModule.parse(text);
|
|
93
122
|
return JSON.parse(jsonStr) as MarkdownNode;
|
|
94
123
|
}
|
|
95
124
|
|
|
125
|
+
if (__DEV__) {
|
|
126
|
+
// eslint-disable-next-line no-console
|
|
127
|
+
console.error(
|
|
128
|
+
"[NitroMarkdown] parseMarkdown: native parser unavailable — check installation.",
|
|
129
|
+
);
|
|
130
|
+
}
|
|
96
131
|
return { type: "document", children: [] };
|
|
97
132
|
}
|
|
98
133
|
|
|
@@ -106,11 +141,20 @@ export function parseMarkdownWithOptions(
|
|
|
106
141
|
text: string,
|
|
107
142
|
options: ParserOptions,
|
|
108
143
|
): MarkdownNode {
|
|
109
|
-
if (
|
|
144
|
+
if (
|
|
145
|
+
MarkdownParserModule != null &&
|
|
146
|
+
typeof MarkdownParserModule.parseWithOptions === "function"
|
|
147
|
+
) {
|
|
110
148
|
const jsonStr = MarkdownParserModule.parseWithOptions(text, options);
|
|
111
149
|
return JSON.parse(jsonStr) as MarkdownNode;
|
|
112
150
|
}
|
|
113
151
|
|
|
152
|
+
if (__DEV__) {
|
|
153
|
+
// eslint-disable-next-line no-console
|
|
154
|
+
console.error(
|
|
155
|
+
"[NitroMarkdown] parseMarkdownWithOptions: native parser unavailable — check installation.",
|
|
156
|
+
);
|
|
157
|
+
}
|
|
114
158
|
return { type: "document", children: [] };
|
|
115
159
|
}
|
|
116
160
|
|
|
@@ -119,7 +163,10 @@ export function parseMarkdownWithOptions(
|
|
|
119
163
|
* Useful for search/indexing flows that don't need full AST rendering.
|
|
120
164
|
*/
|
|
121
165
|
export function extractPlainText(text: string): string {
|
|
122
|
-
if (
|
|
166
|
+
if (
|
|
167
|
+
MarkdownParserModule != null &&
|
|
168
|
+
typeof MarkdownParserModule.extractPlainText === "function"
|
|
169
|
+
) {
|
|
123
170
|
return MarkdownParserModule.extractPlainText(text);
|
|
124
171
|
}
|
|
125
172
|
|
|
@@ -133,7 +180,10 @@ export function extractPlainTextWithOptions(
|
|
|
133
180
|
text: string,
|
|
134
181
|
options: ParserOptions,
|
|
135
182
|
): string {
|
|
136
|
-
if (
|
|
183
|
+
if (
|
|
184
|
+
MarkdownParserModule != null &&
|
|
185
|
+
typeof MarkdownParserModule.extractPlainTextWithOptions === "function"
|
|
186
|
+
) {
|
|
137
187
|
return MarkdownParserModule.extractPlainTextWithOptions(text, options);
|
|
138
188
|
}
|
|
139
189
|
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
export
|
|
1
|
+
export {
|
|
2
|
+
MarkdownParserModule,
|
|
3
|
+
parseMarkdown,
|
|
4
|
+
parseMarkdownWithOptions,
|
|
5
|
+
extractPlainText,
|
|
6
|
+
extractPlainTextWithOptions,
|
|
7
|
+
getTextContent,
|
|
8
|
+
getFlattenedText,
|
|
9
|
+
stripSourceOffsets,
|
|
10
|
+
} from "./headless";
|
|
11
|
+
export type { MarkdownNode, ParserOptions, MarkdownParser } from "./headless";
|
|
2
12
|
|
|
3
13
|
export { Markdown } from "./markdown";
|
|
4
14
|
export type {
|
|
@@ -56,5 +66,9 @@ export { createMarkdownSession } from "./MarkdownSession";
|
|
|
56
66
|
export type { MarkdownSession } from "./MarkdownSession";
|
|
57
67
|
export { useMarkdownSession, useStream } from "./use-markdown-stream";
|
|
58
68
|
|
|
59
|
-
export type {
|
|
69
|
+
export type {
|
|
70
|
+
HighlightedToken,
|
|
71
|
+
TokenType,
|
|
72
|
+
CodeHighlighter,
|
|
73
|
+
} from "./utils/code-highlight";
|
|
60
74
|
export { defaultHighlighter } from "./utils/code-highlight";
|
package/src/markdown-stream.tsx
CHANGED
package/src/markdown.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
useCallback,
|
|
4
4
|
useEffect,
|
|
5
5
|
useMemo,
|
|
6
|
+
useRef,
|
|
6
7
|
type FC,
|
|
7
8
|
Fragment,
|
|
8
9
|
type ReactElement,
|
|
@@ -56,6 +57,49 @@ import {
|
|
|
56
57
|
} from "./theme";
|
|
57
58
|
import type { CodeHighlighter } from "./utils/code-highlight";
|
|
58
59
|
|
|
60
|
+
function hashString(str: string): number {
|
|
61
|
+
let hash = 0;
|
|
62
|
+
for (let i = 0; i < str.length; i++) {
|
|
63
|
+
const char = str.charCodeAt(i);
|
|
64
|
+
hash = (hash << 5) - hash + char;
|
|
65
|
+
hash = hash & hash; // Convert to 32bit int
|
|
66
|
+
}
|
|
67
|
+
return hash;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const ERROR_PHASE = {
|
|
71
|
+
PARSE: "parse",
|
|
72
|
+
BEFORE_PLUGIN: "before-plugin",
|
|
73
|
+
AFTER_PLUGIN: "after-plugin",
|
|
74
|
+
} as const;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Safely invoke the onError callback, preventing callback exceptions from
|
|
78
|
+
* propagating and breaking the render cycle.
|
|
79
|
+
*/
|
|
80
|
+
function safeOnError<P extends string>(
|
|
81
|
+
onError: ((error: Error, phase: P, pluginName?: string) => void) | undefined,
|
|
82
|
+
error: unknown,
|
|
83
|
+
phase: P,
|
|
84
|
+
pluginName?: string,
|
|
85
|
+
): void {
|
|
86
|
+
try {
|
|
87
|
+
onError?.(
|
|
88
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
89
|
+
phase,
|
|
90
|
+
pluginName,
|
|
91
|
+
);
|
|
92
|
+
} catch (callbackError) {
|
|
93
|
+
if (__DEV__) {
|
|
94
|
+
// eslint-disable-next-line no-console
|
|
95
|
+
console.warn(
|
|
96
|
+
"[NitroMarkdown] onError callback threw an exception:",
|
|
97
|
+
callbackError,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
59
103
|
const baseStylesCache = new WeakMap<MarkdownTheme, BaseStyles>();
|
|
60
104
|
const parseAstCache = new Map<string, MarkdownNode>();
|
|
61
105
|
const MAX_PARSE_CACHE_ENTRIES = 32;
|
|
@@ -166,7 +210,7 @@ const getCachedParsedAst = (
|
|
|
166
210
|
return parseWithNativeParser(text, options);
|
|
167
211
|
}
|
|
168
212
|
|
|
169
|
-
const cacheKey = `${getParserOptionsKey(options)}|${text}`;
|
|
213
|
+
const cacheKey = `${getParserOptionsKey(options)}|${text.length}|${hashString(text)}`;
|
|
170
214
|
const cachedNode = parseAstCache.get(cacheKey);
|
|
171
215
|
if (cachedNode) {
|
|
172
216
|
parseAstCache.delete(cacheKey);
|
|
@@ -189,13 +233,15 @@ const getCachedParsedAst = (
|
|
|
189
233
|
const applyBeforeParsePlugins = (
|
|
190
234
|
markdown: string,
|
|
191
235
|
plugins?: MarkdownPlugin[],
|
|
192
|
-
onError?: (error: Error, phase:
|
|
236
|
+
onError?: (error: Error, phase: "before-plugin", pluginName?: string) => void,
|
|
193
237
|
): string => {
|
|
194
238
|
if (!plugins || plugins.length === 0) {
|
|
195
239
|
return markdown;
|
|
196
240
|
}
|
|
197
241
|
|
|
198
|
-
const sorted = [...plugins].sort(
|
|
242
|
+
const sorted = [...plugins].sort(
|
|
243
|
+
(a, b) => (b.priority ?? 0) - (a.priority ?? 0),
|
|
244
|
+
);
|
|
199
245
|
let nextMarkdown = markdown;
|
|
200
246
|
for (const plugin of sorted) {
|
|
201
247
|
if (!plugin.beforeParse) continue;
|
|
@@ -211,7 +257,7 @@ const applyBeforeParsePlugins = (
|
|
|
211
257
|
`[react-native-nitro-markdown] plugin beforeParse${pluginLabel} threw; using previous markdown.`,
|
|
212
258
|
error,
|
|
213
259
|
);
|
|
214
|
-
onError
|
|
260
|
+
safeOnError(onError, error, ERROR_PHASE.BEFORE_PLUGIN, plugin.name);
|
|
215
261
|
}
|
|
216
262
|
}
|
|
217
263
|
|
|
@@ -221,13 +267,15 @@ const applyBeforeParsePlugins = (
|
|
|
221
267
|
const applyAfterParsePlugins = (
|
|
222
268
|
ast: MarkdownNode,
|
|
223
269
|
plugins?: MarkdownPlugin[],
|
|
224
|
-
onError?: (error: Error, phase:
|
|
270
|
+
onError?: (error: Error, phase: "after-plugin", pluginName?: string) => void,
|
|
225
271
|
): MarkdownNode => {
|
|
226
272
|
if (!plugins || plugins.length === 0) {
|
|
227
273
|
return ast;
|
|
228
274
|
}
|
|
229
275
|
|
|
230
|
-
const sorted = [...plugins].sort(
|
|
276
|
+
const sorted = [...plugins].sort(
|
|
277
|
+
(a, b) => (b.priority ?? 0) - (a.priority ?? 0),
|
|
278
|
+
);
|
|
231
279
|
let nextAst = ast;
|
|
232
280
|
for (const plugin of sorted) {
|
|
233
281
|
if (!plugin.afterParse) continue;
|
|
@@ -243,7 +291,7 @@ const applyAfterParsePlugins = (
|
|
|
243
291
|
`[react-native-nitro-markdown] plugin afterParse${pluginLabel} threw; using previous AST.`,
|
|
244
292
|
error,
|
|
245
293
|
);
|
|
246
|
-
onError
|
|
294
|
+
safeOnError(onError, error, ERROR_PHASE.AFTER_PLUGIN, plugin.name);
|
|
247
295
|
}
|
|
248
296
|
}
|
|
249
297
|
|
|
@@ -274,7 +322,12 @@ export type MarkdownProps = {
|
|
|
274
322
|
*/
|
|
275
323
|
astTransform?: AstTransform;
|
|
276
324
|
/**
|
|
277
|
-
* Callback fired
|
|
325
|
+
* Callback fired after the current parse cycle completes and the component
|
|
326
|
+
* has re-rendered with new content. Because the native parser runs
|
|
327
|
+
* synchronously inside `useMemo`, there is no observable "in-progress"
|
|
328
|
+
* window — this callback fires in the `useEffect` commit phase, after the
|
|
329
|
+
* new AST is already rendered. Use `onParseComplete` for post-parse
|
|
330
|
+
* inspection of results.
|
|
278
331
|
*/
|
|
279
332
|
onParsingInProgress?: () => void;
|
|
280
333
|
/**
|
|
@@ -291,7 +344,11 @@ export type MarkdownProps = {
|
|
|
291
344
|
* @param phase - Where the error occurred.
|
|
292
345
|
* @param pluginName - The plugin name, if applicable.
|
|
293
346
|
*/
|
|
294
|
-
onError?: (
|
|
347
|
+
onError?: (
|
|
348
|
+
error: Error,
|
|
349
|
+
phase: "parse" | "before-plugin" | "after-plugin",
|
|
350
|
+
pluginName?: string,
|
|
351
|
+
) => void;
|
|
295
352
|
/**
|
|
296
353
|
* Custom renderers for specific markdown node types.
|
|
297
354
|
* Each renderer receives { node, children, Renderer } plus type-specific props.
|
|
@@ -382,9 +439,20 @@ export const Markdown: FC<MarkdownProps> = ({
|
|
|
382
439
|
const parserOptionGfm = options?.gfm;
|
|
383
440
|
const parserOptionMath = options?.math;
|
|
384
441
|
|
|
442
|
+
/* eslint-disable react-hooks/refs -- Refs updated/read intentionally to avoid re-parsing on callback identity changes */
|
|
443
|
+
const onErrorRef = useRef(onError);
|
|
444
|
+
onErrorRef.current = onError;
|
|
445
|
+
|
|
446
|
+
const pluginsRef = useRef(plugins);
|
|
447
|
+
pluginsRef.current = plugins;
|
|
448
|
+
|
|
385
449
|
const parseResult = useMemo(() => {
|
|
386
450
|
try {
|
|
387
|
-
const markdownToParse = applyBeforeParsePlugins(
|
|
451
|
+
const markdownToParse = applyBeforeParsePlugins(
|
|
452
|
+
children,
|
|
453
|
+
pluginsRef.current,
|
|
454
|
+
onErrorRef.current,
|
|
455
|
+
);
|
|
388
456
|
const parserOptions = normalizeParserOptions({
|
|
389
457
|
gfm: parserOptionGfm,
|
|
390
458
|
math: parserOptionMath,
|
|
@@ -392,7 +460,11 @@ export const Markdown: FC<MarkdownProps> = ({
|
|
|
392
460
|
let parsedAst = sourceAst
|
|
393
461
|
? cloneMarkdownNode(sourceAst)
|
|
394
462
|
: getCachedParsedAst(markdownToParse, parserOptions);
|
|
395
|
-
parsedAst = applyAfterParsePlugins(
|
|
463
|
+
parsedAst = applyAfterParsePlugins(
|
|
464
|
+
parsedAst,
|
|
465
|
+
pluginsRef.current,
|
|
466
|
+
onErrorRef.current,
|
|
467
|
+
);
|
|
396
468
|
|
|
397
469
|
let ast = parsedAst;
|
|
398
470
|
if (astTransform) {
|
|
@@ -414,30 +486,17 @@ export const Markdown: FC<MarkdownProps> = ({
|
|
|
414
486
|
ast,
|
|
415
487
|
};
|
|
416
488
|
} catch (parseError) {
|
|
417
|
-
|
|
489
|
+
safeOnError(onErrorRef.current, parseError, ERROR_PHASE.PARSE);
|
|
418
490
|
return {
|
|
419
491
|
ast: null,
|
|
420
492
|
};
|
|
421
493
|
}
|
|
422
|
-
}, [
|
|
423
|
-
|
|
424
|
-
parserOptionGfm,
|
|
425
|
-
parserOptionMath,
|
|
426
|
-
plugins,
|
|
427
|
-
sourceAst,
|
|
428
|
-
astTransform,
|
|
429
|
-
onError,
|
|
430
|
-
]);
|
|
494
|
+
}, [children, parserOptionGfm, parserOptionMath, sourceAst, astTransform]);
|
|
495
|
+
/* eslint-enable react-hooks/refs */
|
|
431
496
|
|
|
432
497
|
useEffect(() => {
|
|
433
498
|
onParsingInProgress?.();
|
|
434
|
-
}, [
|
|
435
|
-
children,
|
|
436
|
-
parserOptionGfm,
|
|
437
|
-
parserOptionMath,
|
|
438
|
-
plugins,
|
|
439
|
-
onParsingInProgress,
|
|
440
|
-
]);
|
|
499
|
+
}, [children, parserOptionGfm, parserOptionMath, onParsingInProgress]);
|
|
441
500
|
|
|
442
501
|
useEffect(() => {
|
|
443
502
|
if (!parseResult.ast || !onParseComplete) return;
|
|
@@ -468,7 +527,15 @@ export const Markdown: FC<MarkdownProps> = ({
|
|
|
468
527
|
tableOptions,
|
|
469
528
|
highlightCode,
|
|
470
529
|
}),
|
|
471
|
-
[
|
|
530
|
+
[
|
|
531
|
+
renderers,
|
|
532
|
+
theme,
|
|
533
|
+
nodeStyles,
|
|
534
|
+
stylingStrategy,
|
|
535
|
+
onLinkPress,
|
|
536
|
+
tableOptions,
|
|
537
|
+
highlightCode,
|
|
538
|
+
],
|
|
472
539
|
);
|
|
473
540
|
|
|
474
541
|
const topLevelBlocks =
|
|
@@ -887,13 +954,13 @@ const getBaseStyles = (theme: MarkdownTheme): BaseStyles => {
|
|
|
887
954
|
const createBaseStyles = (theme: MarkdownTheme) =>
|
|
888
955
|
StyleSheet.create({
|
|
889
956
|
container: {
|
|
890
|
-
|
|
957
|
+
flexShrink: 1,
|
|
891
958
|
},
|
|
892
959
|
virtualizedList: {
|
|
893
960
|
flex: 1,
|
|
894
961
|
},
|
|
895
962
|
document: {
|
|
896
|
-
|
|
963
|
+
flexShrink: 1,
|
|
897
964
|
},
|
|
898
965
|
errorText: {
|
|
899
966
|
color: "#f87171",
|
package/src/renderers/code.tsx
CHANGED
|
@@ -10,8 +10,11 @@ import {
|
|
|
10
10
|
} from "react-native";
|
|
11
11
|
import { getTextContent } from "../headless";
|
|
12
12
|
import { useMarkdownContext } from "../MarkdownContext";
|
|
13
|
+
import {
|
|
14
|
+
defaultHighlighter,
|
|
15
|
+
type HighlightedToken,
|
|
16
|
+
} from "../utils/code-highlight";
|
|
13
17
|
import type { MarkdownNode } from "../headless";
|
|
14
|
-
import { defaultHighlighter, type HighlightedToken } from "../utils/code-highlight";
|
|
15
18
|
|
|
16
19
|
type CodeBlockProps = {
|
|
17
20
|
language?: string;
|
|
@@ -29,11 +32,12 @@ export const CodeBlock: FC<CodeBlockProps> = ({
|
|
|
29
32
|
const ctx = useMarkdownContext();
|
|
30
33
|
const { theme } = ctx;
|
|
31
34
|
|
|
32
|
-
const highlighter =
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
const highlighter =
|
|
36
|
+
ctx.highlightCode === true
|
|
37
|
+
? defaultHighlighter
|
|
38
|
+
: typeof ctx.highlightCode === "function"
|
|
39
|
+
? ctx.highlightCode
|
|
40
|
+
: null;
|
|
37
41
|
|
|
38
42
|
const displayContent = content ?? (node ? getTextContent(node) : "");
|
|
39
43
|
|
|
@@ -85,16 +89,19 @@ export const CodeBlock: FC<CodeBlockProps> = ({
|
|
|
85
89
|
>
|
|
86
90
|
{highlighter && language ? (
|
|
87
91
|
<Text style={styles.codeBlockText} selectable>
|
|
88
|
-
{highlighter(language, displayContent).map(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
92
|
+
{highlighter(language, displayContent).map(
|
|
93
|
+
(token: HighlightedToken, i: number) => {
|
|
94
|
+
const tokenColor =
|
|
95
|
+
ctx.theme.colors.codeTokenColors?.[token.type];
|
|
96
|
+
return tokenColor ? (
|
|
97
|
+
<Text key={i} style={{ color: tokenColor }}>
|
|
98
|
+
{token.text}
|
|
99
|
+
</Text>
|
|
100
|
+
) : (
|
|
101
|
+
<Text key={i}>{token.text}</Text>
|
|
102
|
+
);
|
|
103
|
+
},
|
|
104
|
+
)}
|
|
98
105
|
</Text>
|
|
99
106
|
) : (
|
|
100
107
|
<Text style={styles.codeBlockText} selectable>
|
package/src/renderers/image.tsx
CHANGED
|
@@ -128,7 +128,15 @@ export const Image: FC<ImageProps> = ({ url, title, alt, Renderer, style }) => {
|
|
|
128
128
|
setAspectRatio(width / height);
|
|
129
129
|
}
|
|
130
130
|
},
|
|
131
|
-
() => {
|
|
131
|
+
(error) => {
|
|
132
|
+
if (__DEV__) {
|
|
133
|
+
// eslint-disable-next-line no-console
|
|
134
|
+
console.warn(
|
|
135
|
+
"[NitroMarkdown] Failed to get image dimensions:",
|
|
136
|
+
error,
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
},
|
|
132
140
|
);
|
|
133
141
|
}, [url]);
|
|
134
142
|
|
package/src/renderers/link.tsx
CHANGED
|
@@ -39,7 +39,8 @@ export const Link: FC<LinkProps> = ({ href, children, style }) => {
|
|
|
39
39
|
if (!normalizedHref) return;
|
|
40
40
|
|
|
41
41
|
try {
|
|
42
|
-
const shouldOpen =
|
|
42
|
+
const shouldOpen =
|
|
43
|
+
(await Promise.resolve(onLinkPress?.(normalizedHref))) !== false;
|
|
43
44
|
if (!shouldOpen) return;
|
|
44
45
|
|
|
45
46
|
const allowedExternalHref = getAllowedExternalHref(normalizedHref);
|
|
@@ -49,7 +50,12 @@ export const Link: FC<LinkProps> = ({ href, children, style }) => {
|
|
|
49
50
|
if (!canOpen) return;
|
|
50
51
|
|
|
51
52
|
await Linking.openURL(allowedExternalHref);
|
|
52
|
-
} catch {
|
|
53
|
+
} catch (error) {
|
|
54
|
+
if (__DEV__) {
|
|
55
|
+
// eslint-disable-next-line no-console
|
|
56
|
+
console.warn("[NitroMarkdown] Link press handler failed:", error);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
53
59
|
};
|
|
54
60
|
|
|
55
61
|
return (
|
package/src/renderers/list.tsx
CHANGED
|
@@ -10,6 +10,8 @@ type ListProps = {
|
|
|
10
10
|
style?: ViewStyle;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
+
// Note: ordered and start are accepted for API consistency but layout is
|
|
14
|
+
// handled at the ListItem level — the List container is style-only.
|
|
13
15
|
export const List: FC<ListProps> = ({ depth, children, style }) => {
|
|
14
16
|
const { theme } = useMarkdownContext();
|
|
15
17
|
const styles = useMemo(
|