react-native-nitro-markdown 0.2.1 → 0.3.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/README.md +237 -103
- package/cpp/bindings/HybridMarkdownParser.cpp +2 -0
- package/cpp/core/MD4CParser.cpp +73 -39
- package/cpp/core/MarkdownTypes.hpp +6 -1
- package/cpp/md4c/md4c.c +79 -56
- package/cpp/md4c/md4c.h +7 -4
- package/lib/commonjs/MarkdownContext.js +3 -7
- package/lib/commonjs/MarkdownContext.js.map +1 -1
- package/lib/commonjs/default-markdown-renderer.js +4 -7
- package/lib/commonjs/default-markdown-renderer.js.map +1 -1
- package/lib/commonjs/headless.js +49 -1
- package/lib/commonjs/headless.js.map +1 -1
- package/lib/commonjs/index.js +35 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/markdown.js +100 -41
- package/lib/commonjs/markdown.js.map +1 -1
- package/lib/commonjs/renderers/blockquote.js +1 -1
- package/lib/commonjs/renderers/blockquote.js.map +1 -1
- package/lib/commonjs/renderers/code.js +15 -8
- package/lib/commonjs/renderers/code.js.map +1 -1
- package/lib/commonjs/renderers/heading.js +2 -1
- package/lib/commonjs/renderers/heading.js.map +1 -1
- package/lib/commonjs/renderers/horizontal-rule.js +4 -2
- package/lib/commonjs/renderers/horizontal-rule.js.map +1 -1
- package/lib/commonjs/renderers/image.js +39 -14
- package/lib/commonjs/renderers/image.js.map +1 -1
- package/lib/commonjs/renderers/link.js +1 -3
- package/lib/commonjs/renderers/link.js.map +1 -1
- package/lib/commonjs/renderers/list.js +12 -10
- package/lib/commonjs/renderers/list.js.map +1 -1
- package/lib/commonjs/renderers/math.js +33 -47
- package/lib/commonjs/renderers/math.js.map +1 -1
- package/lib/commonjs/renderers/paragraph.js +0 -6
- package/lib/commonjs/renderers/paragraph.js.map +1 -1
- package/lib/commonjs/renderers/table.js +127 -120
- package/lib/commonjs/renderers/table.js.map +1 -1
- package/lib/commonjs/theme.js +146 -13
- package/lib/commonjs/theme.js.map +1 -1
- package/lib/module/MarkdownContext.js +3 -8
- package/lib/module/MarkdownContext.js.map +1 -1
- package/lib/module/default-markdown-renderer.js +1 -4
- package/lib/module/default-markdown-renderer.js.map +1 -1
- package/lib/module/headless.js +46 -0
- package/lib/module/headless.js.map +1 -1
- package/lib/module/index.js +2 -20
- package/lib/module/index.js.map +1 -1
- package/lib/module/markdown.js +101 -42
- package/lib/module/markdown.js.map +1 -1
- package/lib/module/renderers/blockquote.js +1 -1
- package/lib/module/renderers/blockquote.js.map +1 -1
- package/lib/module/renderers/code.js +15 -8
- package/lib/module/renderers/code.js.map +1 -1
- package/lib/module/renderers/heading.js +2 -1
- package/lib/module/renderers/heading.js.map +1 -1
- package/lib/module/renderers/horizontal-rule.js +4 -2
- package/lib/module/renderers/horizontal-rule.js.map +1 -1
- package/lib/module/renderers/image.js +40 -15
- package/lib/module/renderers/image.js.map +1 -1
- package/lib/module/renderers/link.js +1 -3
- package/lib/module/renderers/link.js.map +1 -1
- package/lib/module/renderers/list.js +12 -10
- package/lib/module/renderers/list.js.map +1 -1
- package/lib/module/renderers/math.js +34 -48
- package/lib/module/renderers/math.js.map +1 -1
- package/lib/module/renderers/paragraph.js +0 -6
- package/lib/module/renderers/paragraph.js.map +1 -1
- package/lib/module/renderers/table.js +128 -121
- package/lib/module/renderers/table.js.map +1 -1
- package/lib/module/theme.js +144 -12
- package/lib/module/theme.js.map +1 -1
- package/lib/typescript/commonjs/MarkdownContext.d.ts +45 -6
- package/lib/typescript/commonjs/MarkdownContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/default-markdown-renderer.d.ts +1 -1
- package/lib/typescript/commonjs/default-markdown-renderer.d.ts.map +1 -1
- package/lib/typescript/commonjs/headless.d.ts +12 -1
- package/lib/typescript/commonjs/headless.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +4 -16
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/markdown.d.ts +33 -2
- package/lib/typescript/commonjs/markdown.d.ts.map +1 -1
- package/lib/typescript/commonjs/renderers/code.d.ts +6 -2
- package/lib/typescript/commonjs/renderers/code.d.ts.map +1 -1
- package/lib/typescript/commonjs/renderers/heading.d.ts.map +1 -1
- package/lib/typescript/commonjs/renderers/horizontal-rule.d.ts +6 -1
- package/lib/typescript/commonjs/renderers/horizontal-rule.d.ts.map +1 -1
- package/lib/typescript/commonjs/renderers/image.d.ts +2 -0
- 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 +4 -0
- package/lib/typescript/commonjs/renderers/list.d.ts.map +1 -1
- package/lib/typescript/commonjs/renderers/math.d.ts +3 -4
- package/lib/typescript/commonjs/renderers/math.d.ts.map +1 -1
- package/lib/typescript/commonjs/renderers/paragraph.d.ts +0 -5
- package/lib/typescript/commonjs/renderers/paragraph.d.ts.map +1 -1
- package/lib/typescript/commonjs/renderers/table.d.ts +2 -0
- package/lib/typescript/commonjs/renderers/table.d.ts.map +1 -1
- package/lib/typescript/commonjs/specs/MarkdownSession.nitro.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme.d.ts +41 -28
- package/lib/typescript/commonjs/theme.d.ts.map +1 -1
- package/lib/typescript/module/MarkdownContext.d.ts +45 -6
- package/lib/typescript/module/MarkdownContext.d.ts.map +1 -1
- package/lib/typescript/module/default-markdown-renderer.d.ts +1 -1
- package/lib/typescript/module/default-markdown-renderer.d.ts.map +1 -1
- package/lib/typescript/module/headless.d.ts +12 -1
- package/lib/typescript/module/headless.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +4 -16
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/markdown.d.ts +33 -2
- package/lib/typescript/module/markdown.d.ts.map +1 -1
- package/lib/typescript/module/renderers/code.d.ts +6 -2
- package/lib/typescript/module/renderers/code.d.ts.map +1 -1
- package/lib/typescript/module/renderers/heading.d.ts.map +1 -1
- package/lib/typescript/module/renderers/horizontal-rule.d.ts +6 -1
- package/lib/typescript/module/renderers/horizontal-rule.d.ts.map +1 -1
- package/lib/typescript/module/renderers/image.d.ts +2 -0
- 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 +4 -0
- package/lib/typescript/module/renderers/list.d.ts.map +1 -1
- package/lib/typescript/module/renderers/math.d.ts +3 -4
- package/lib/typescript/module/renderers/math.d.ts.map +1 -1
- package/lib/typescript/module/renderers/paragraph.d.ts +0 -5
- package/lib/typescript/module/renderers/paragraph.d.ts.map +1 -1
- package/lib/typescript/module/renderers/table.d.ts +2 -0
- package/lib/typescript/module/renderers/table.d.ts.map +1 -1
- package/lib/typescript/module/specs/MarkdownSession.nitro.d.ts.map +1 -1
- package/lib/typescript/module/theme.d.ts +41 -28
- package/lib/typescript/module/theme.d.ts.map +1 -1
- package/nitrogen/generated/ios/NitroMarkdownAutolinking.swift +8 -7
- package/nitrogen/generated/ios/swift/HybridMarkdownSessionSpec.swift +2 -2
- package/package.json +1 -1
- package/src/MarkdownContext.ts +66 -9
- package/src/default-markdown-renderer.tsx +1 -6
- package/src/headless.ts +67 -2
- package/src/index.ts +24 -19
- package/src/markdown.tsx +158 -52
- package/src/renderers/blockquote.tsx +1 -2
- package/src/renderers/code.tsx +36 -12
- package/src/renderers/heading.tsx +1 -1
- package/src/renderers/horizontal-rule.tsx +7 -4
- package/src/renderers/image.tsx +59 -15
- package/src/renderers/link.tsx +1 -6
- package/src/renderers/list.tsx +15 -15
- package/src/renderers/math.tsx +28 -45
- package/src/renderers/paragraph.tsx +1 -8
- package/src/renderers/table.tsx +185 -160
- package/src/specs/MarkdownSession.nitro.ts +4 -6
- package/src/theme.ts +203 -12
package/src/renderers/image.tsx
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
useState,
|
|
3
|
+
useEffect,
|
|
4
|
+
useLayoutEffect,
|
|
5
|
+
useMemo,
|
|
6
|
+
type ReactNode,
|
|
7
|
+
type FC,
|
|
8
|
+
type ComponentType,
|
|
9
|
+
} from "react";
|
|
10
|
+
import {
|
|
11
|
+
View,
|
|
12
|
+
Text,
|
|
13
|
+
Image as RNImage,
|
|
14
|
+
StyleSheet,
|
|
15
|
+
type ViewStyle,
|
|
16
|
+
} from "react-native";
|
|
3
17
|
|
|
4
18
|
import { parseMarkdownWithOptions, type MarkdownNode } from "../headless";
|
|
5
19
|
import type { NodeRendererProps } from "../MarkdownContext";
|
|
@@ -7,7 +21,7 @@ import { useMarkdownContext } from "../MarkdownContext";
|
|
|
7
21
|
|
|
8
22
|
const renderInlineContent = (
|
|
9
23
|
node: MarkdownNode,
|
|
10
|
-
Renderer: ComponentType<NodeRendererProps
|
|
24
|
+
Renderer: ComponentType<NodeRendererProps>,
|
|
11
25
|
): ReactNode => {
|
|
12
26
|
if (node.type === "paragraph" && node.children) {
|
|
13
27
|
return (
|
|
@@ -25,13 +39,14 @@ interface ImageProps {
|
|
|
25
39
|
url: string;
|
|
26
40
|
title?: string;
|
|
27
41
|
alt?: string;
|
|
28
|
-
|
|
29
42
|
Renderer?: ComponentType<NodeRendererProps>;
|
|
43
|
+
style?: ViewStyle;
|
|
30
44
|
}
|
|
31
45
|
|
|
32
|
-
export const Image: FC<ImageProps> = ({ url, title, alt, Renderer }) => {
|
|
46
|
+
export const Image: FC<ImageProps> = ({ url, title, alt, Renderer, style }) => {
|
|
33
47
|
const [loading, setLoading] = useState(true);
|
|
34
48
|
const [error, setError] = useState(false);
|
|
49
|
+
const [aspectRatio, setAspectRatio] = useState<number | undefined>(undefined);
|
|
35
50
|
const { theme } = useMarkdownContext();
|
|
36
51
|
|
|
37
52
|
const styles = useMemo(
|
|
@@ -43,8 +58,10 @@ export const Image: FC<ImageProps> = ({ url, title, alt, Renderer }) => {
|
|
|
43
58
|
},
|
|
44
59
|
image: {
|
|
45
60
|
width: "100%",
|
|
46
|
-
|
|
47
|
-
|
|
61
|
+
// If we have an aspect ratio, use it. Otherwise, use minHeight as fallback.
|
|
62
|
+
aspectRatio: aspectRatio,
|
|
63
|
+
minHeight: aspectRatio ? undefined : 200,
|
|
64
|
+
borderRadius: theme.borderRadius.m,
|
|
48
65
|
backgroundColor: theme.colors.surface,
|
|
49
66
|
},
|
|
50
67
|
imageHidden: {
|
|
@@ -53,8 +70,10 @@ export const Image: FC<ImageProps> = ({ url, title, alt, Renderer }) => {
|
|
|
53
70
|
},
|
|
54
71
|
imageLoading: {
|
|
55
72
|
width: "100%",
|
|
56
|
-
|
|
57
|
-
|
|
73
|
+
// Match the image size if possible
|
|
74
|
+
aspectRatio: aspectRatio,
|
|
75
|
+
height: aspectRatio ? undefined : 200,
|
|
76
|
+
borderRadius: theme.borderRadius.m,
|
|
58
77
|
backgroundColor: theme.colors.surface,
|
|
59
78
|
justifyContent: "center",
|
|
60
79
|
alignItems: "center",
|
|
@@ -62,11 +81,12 @@ export const Image: FC<ImageProps> = ({ url, title, alt, Renderer }) => {
|
|
|
62
81
|
imageLoadingText: {
|
|
63
82
|
color: theme.colors.textMuted,
|
|
64
83
|
fontSize: theme.fontSizes.s,
|
|
84
|
+
fontFamily: theme.fontFamilies.regular,
|
|
65
85
|
},
|
|
66
86
|
imageError: {
|
|
67
87
|
width: "100%",
|
|
68
88
|
padding: theme.spacing.l,
|
|
69
|
-
borderRadius:
|
|
89
|
+
borderRadius: theme.borderRadius.m,
|
|
70
90
|
backgroundColor: theme.colors.surface,
|
|
71
91
|
alignItems: "center",
|
|
72
92
|
marginVertical: theme.spacing.m,
|
|
@@ -74,6 +94,7 @@ export const Image: FC<ImageProps> = ({ url, title, alt, Renderer }) => {
|
|
|
74
94
|
imageErrorText: {
|
|
75
95
|
color: theme.colors.textMuted,
|
|
76
96
|
fontSize: theme.fontSizes.s,
|
|
97
|
+
fontFamily: theme.fontFamilies.regular,
|
|
77
98
|
},
|
|
78
99
|
imageCaption: {
|
|
79
100
|
color: theme.colors.textMuted,
|
|
@@ -81,11 +102,34 @@ export const Image: FC<ImageProps> = ({ url, title, alt, Renderer }) => {
|
|
|
81
102
|
marginTop: theme.spacing.s,
|
|
82
103
|
fontStyle: "italic",
|
|
83
104
|
textAlign: "center",
|
|
105
|
+
fontFamily: theme.fontFamilies.regular,
|
|
84
106
|
},
|
|
85
107
|
}),
|
|
86
|
-
[theme]
|
|
108
|
+
[theme, aspectRatio],
|
|
87
109
|
);
|
|
88
110
|
|
|
111
|
+
useLayoutEffect(() => {
|
|
112
|
+
// Fast path for consistent aspect ratios if checking picsum
|
|
113
|
+
const picsumMatch = url.match(/picsum\.photos\/.*\/(\d+)\/(\d+)/);
|
|
114
|
+
if (picsumMatch) {
|
|
115
|
+
const w = parseInt(picsumMatch[1], 10);
|
|
116
|
+
const h = parseInt(picsumMatch[2], 10);
|
|
117
|
+
if (!isNaN(w) && !isNaN(h) && h !== 0) {
|
|
118
|
+
setAspectRatio(w / h);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
RNImage.getSize(
|
|
123
|
+
url,
|
|
124
|
+
(width, height) => {
|
|
125
|
+
if (width > 0 && height > 0) {
|
|
126
|
+
setAspectRatio(width / height);
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
() => {},
|
|
130
|
+
);
|
|
131
|
+
}, [url]);
|
|
132
|
+
|
|
89
133
|
const altContent = useMemo(() => {
|
|
90
134
|
if (!alt || !Renderer) return null;
|
|
91
135
|
if (
|
|
@@ -117,7 +161,7 @@ export const Image: FC<ImageProps> = ({ url, title, alt, Renderer }) => {
|
|
|
117
161
|
|
|
118
162
|
if (error) {
|
|
119
163
|
return (
|
|
120
|
-
<View style={styles.imageError}>
|
|
164
|
+
<View style={[styles.imageError, style]}>
|
|
121
165
|
<View
|
|
122
166
|
style={{
|
|
123
167
|
flexDirection: "row",
|
|
@@ -138,15 +182,15 @@ export const Image: FC<ImageProps> = ({ url, title, alt, Renderer }) => {
|
|
|
138
182
|
}
|
|
139
183
|
|
|
140
184
|
return (
|
|
141
|
-
<View style={styles.imageContainer}>
|
|
142
|
-
{loading && (
|
|
185
|
+
<View style={[styles.imageContainer, style]}>
|
|
186
|
+
{loading && !aspectRatio && (
|
|
143
187
|
<View style={styles.imageLoading}>
|
|
144
188
|
<Text style={styles.imageLoadingText}>Loading image...</Text>
|
|
145
189
|
</View>
|
|
146
190
|
)}
|
|
147
191
|
<RNImage
|
|
148
192
|
source={{ uri: url }}
|
|
149
|
-
style={[styles.image, loading && styles.imageHidden]}
|
|
193
|
+
style={[styles.image, loading && !aspectRatio && styles.imageHidden]}
|
|
150
194
|
resizeMode="contain"
|
|
151
195
|
onLoad={() => setLoading(false)}
|
|
152
196
|
onError={() => {
|
package/src/renderers/link.tsx
CHANGED
|
@@ -22,11 +22,7 @@ export const Link: FC<LinkProps> = ({ href, children, style }) => {
|
|
|
22
22
|
);
|
|
23
23
|
|
|
24
24
|
const handlePress = () => {
|
|
25
|
-
if (href)
|
|
26
|
-
Linking.openURL(href).catch((err) =>
|
|
27
|
-
console.error("Failed to open URL:", err)
|
|
28
|
-
);
|
|
29
|
-
}
|
|
25
|
+
if (href) Linking.openURL(href);
|
|
30
26
|
};
|
|
31
27
|
|
|
32
28
|
return (
|
|
@@ -35,4 +31,3 @@ export const Link: FC<LinkProps> = ({ href, children, style }) => {
|
|
|
35
31
|
</Text>
|
|
36
32
|
);
|
|
37
33
|
};
|
|
38
|
-
|
package/src/renderers/list.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode, useMemo, type FC } from "react";
|
|
2
|
-
import { View, Text, StyleSheet } from "react-native";
|
|
2
|
+
import { View, Text, StyleSheet, type ViewStyle } from "react-native";
|
|
3
3
|
import { useMarkdownContext } from "../MarkdownContext";
|
|
4
4
|
|
|
5
5
|
interface ListProps {
|
|
@@ -7,14 +7,10 @@ interface ListProps {
|
|
|
7
7
|
start?: number;
|
|
8
8
|
depth: number;
|
|
9
9
|
children: ReactNode;
|
|
10
|
+
style?: ViewStyle;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
export const List: FC<ListProps> = ({
|
|
13
|
-
ordered,
|
|
14
|
-
start = 1,
|
|
15
|
-
depth,
|
|
16
|
-
children,
|
|
17
|
-
}) => {
|
|
13
|
+
export const List: FC<ListProps> = ({ depth, children, style }) => {
|
|
18
14
|
const { theme } = useMarkdownContext();
|
|
19
15
|
const styles = useMemo(
|
|
20
16
|
() =>
|
|
@@ -23,14 +19,14 @@ export const List: FC<ListProps> = ({
|
|
|
23
19
|
marginBottom: theme.spacing.m,
|
|
24
20
|
},
|
|
25
21
|
listNested: {
|
|
26
|
-
marginLeft: theme.spacing.
|
|
22
|
+
marginLeft: theme.spacing.s,
|
|
27
23
|
marginBottom: 0,
|
|
28
24
|
},
|
|
29
25
|
}),
|
|
30
|
-
[theme]
|
|
26
|
+
[theme],
|
|
31
27
|
);
|
|
32
28
|
return (
|
|
33
|
-
<View style={[styles.list, depth > 0 && styles.listNested]}>
|
|
29
|
+
<View style={[styles.list, depth > 0 && styles.listNested, style]}>
|
|
34
30
|
{children}
|
|
35
31
|
</View>
|
|
36
32
|
);
|
|
@@ -41,6 +37,7 @@ interface ListItemProps {
|
|
|
41
37
|
index: number;
|
|
42
38
|
ordered: boolean;
|
|
43
39
|
start: number;
|
|
40
|
+
style?: ViewStyle;
|
|
44
41
|
}
|
|
45
42
|
|
|
46
43
|
export const ListItem: FC<ListItemProps> = ({
|
|
@@ -48,6 +45,7 @@ export const ListItem: FC<ListItemProps> = ({
|
|
|
48
45
|
index,
|
|
49
46
|
ordered,
|
|
50
47
|
start,
|
|
48
|
+
style,
|
|
51
49
|
}) => {
|
|
52
50
|
const { theme } = useMarkdownContext();
|
|
53
51
|
const styles = useMemo(
|
|
@@ -65,6 +63,7 @@ export const ListItem: FC<ListItemProps> = ({
|
|
|
65
63
|
marginRight: theme.spacing.s,
|
|
66
64
|
minWidth: 20,
|
|
67
65
|
textAlign: "center",
|
|
66
|
+
fontFamily: theme.fontFamilies.regular,
|
|
68
67
|
},
|
|
69
68
|
listItemContent: {
|
|
70
69
|
flex: 1,
|
|
@@ -72,11 +71,11 @@ export const ListItem: FC<ListItemProps> = ({
|
|
|
72
71
|
minWidth: 0,
|
|
73
72
|
},
|
|
74
73
|
}),
|
|
75
|
-
[theme]
|
|
74
|
+
[theme],
|
|
76
75
|
);
|
|
77
76
|
const bullet = ordered ? `${start + index}.` : "•";
|
|
78
77
|
return (
|
|
79
|
-
<View style={styles.listItem}>
|
|
78
|
+
<View style={[styles.listItem, style]}>
|
|
80
79
|
<Text style={styles.listBullet}>{bullet}</Text>
|
|
81
80
|
<View style={styles.listItemContent}>{children}</View>
|
|
82
81
|
</View>
|
|
@@ -86,11 +85,13 @@ export const ListItem: FC<ListItemProps> = ({
|
|
|
86
85
|
interface TaskListItemProps {
|
|
87
86
|
children: ReactNode;
|
|
88
87
|
checked: boolean;
|
|
88
|
+
style?: ViewStyle;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
export const TaskListItem: FC<TaskListItemProps> = ({
|
|
92
92
|
children,
|
|
93
93
|
checked,
|
|
94
|
+
style,
|
|
94
95
|
}) => {
|
|
95
96
|
const { theme } = useMarkdownContext();
|
|
96
97
|
const styles = useMemo(
|
|
@@ -113,13 +114,12 @@ export const TaskListItem: FC<TaskListItemProps> = ({
|
|
|
113
114
|
minWidth: 0,
|
|
114
115
|
},
|
|
115
116
|
}),
|
|
116
|
-
[theme]
|
|
117
|
+
[theme],
|
|
117
118
|
);
|
|
118
119
|
return (
|
|
119
|
-
<View style={styles.taskListItem}>
|
|
120
|
+
<View style={[styles.taskListItem, style]}>
|
|
120
121
|
<Text style={styles.taskCheckbox}>{checked ? "☑" : "☐"}</Text>
|
|
121
122
|
<View style={styles.taskContent}>{children}</View>
|
|
122
123
|
</View>
|
|
123
124
|
);
|
|
124
125
|
};
|
|
125
|
-
|
package/src/renderers/math.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
View,
|
|
4
4
|
Text,
|
|
5
5
|
StyleSheet,
|
|
6
|
+
Platform,
|
|
6
7
|
type StyleProp,
|
|
7
8
|
type ViewStyle,
|
|
8
9
|
} from "react-native";
|
|
@@ -27,41 +28,27 @@ try {
|
|
|
27
28
|
|
|
28
29
|
interface MathInlineProps {
|
|
29
30
|
content?: string;
|
|
31
|
+
style?: ViewStyle;
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
/**
|
|
33
|
-
* Inline math renderer.
|
|
34
|
-
* Uses react-native-mathjax-svg if installed, otherwise shows raw LaTeX.
|
|
35
|
-
* Note: Renders as a View since SVG can't be nested in Text.
|
|
36
|
-
*/
|
|
37
|
-
|
|
38
34
|
const createMathStyles = (theme: MarkdownTheme) =>
|
|
39
35
|
StyleSheet.create({
|
|
40
36
|
mathInlineContainer: {
|
|
41
|
-
flexDirection: "row",
|
|
42
|
-
alignItems: "baseline",
|
|
43
|
-
alignSelf: "baseline",
|
|
44
|
-
justifyContent: "flex-start",
|
|
45
|
-
flexShrink: 1,
|
|
46
37
|
marginHorizontal: 2,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
paddingVertical: 0,
|
|
50
|
-
},
|
|
51
|
-
mathJaxInline: {
|
|
52
|
-
marginTop: 0,
|
|
53
|
-
marginBottom: 0,
|
|
38
|
+
// Ensure the inline view has layout alignment
|
|
39
|
+
justifyContent: "center",
|
|
54
40
|
},
|
|
55
41
|
mathInlineFallbackContainer: {
|
|
56
42
|
backgroundColor: theme.colors.codeBackground,
|
|
57
|
-
paddingHorizontal:
|
|
43
|
+
paddingHorizontal: theme.spacing.xs,
|
|
58
44
|
paddingVertical: 2,
|
|
59
|
-
borderRadius:
|
|
60
|
-
alignSelf: "baseline",
|
|
45
|
+
borderRadius: theme.borderRadius.s,
|
|
61
46
|
marginHorizontal: 2,
|
|
62
47
|
},
|
|
63
48
|
mathInlineFallback: {
|
|
64
|
-
fontFamily:
|
|
49
|
+
fontFamily:
|
|
50
|
+
theme.fontFamilies.mono ??
|
|
51
|
+
Platform.select({ ios: "Courier", android: "monospace" }),
|
|
65
52
|
fontSize: theme.fontSizes.s,
|
|
66
53
|
color: theme.colors.code,
|
|
67
54
|
},
|
|
@@ -70,49 +57,48 @@ const createMathStyles = (theme: MarkdownTheme) =>
|
|
|
70
57
|
paddingVertical: theme.spacing.l,
|
|
71
58
|
paddingHorizontal: theme.spacing.l,
|
|
72
59
|
backgroundColor: theme.colors.surface,
|
|
73
|
-
borderRadius:
|
|
60
|
+
borderRadius: theme.borderRadius.l,
|
|
74
61
|
alignItems: "center",
|
|
75
62
|
borderWidth: 1,
|
|
76
63
|
borderColor: theme.colors.border,
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
shadowOpacity: 0.05,
|
|
80
|
-
shadowRadius: 2,
|
|
81
|
-
elevation: 1,
|
|
64
|
+
// Ensure we don't collapse if MathJax fails to report size immediately
|
|
65
|
+
minHeight: 48,
|
|
82
66
|
},
|
|
83
67
|
mathBlockFallbackContainer: {
|
|
84
68
|
marginVertical: theme.spacing.m,
|
|
85
69
|
paddingVertical: theme.spacing.m,
|
|
86
70
|
paddingHorizontal: theme.spacing.l,
|
|
87
71
|
backgroundColor: theme.colors.codeBackground,
|
|
88
|
-
borderRadius:
|
|
72
|
+
borderRadius: theme.borderRadius.m,
|
|
89
73
|
alignItems: "center",
|
|
90
74
|
borderWidth: 1,
|
|
91
75
|
borderColor: theme.colors.border,
|
|
92
76
|
},
|
|
93
77
|
mathBlockFallback: {
|
|
94
|
-
fontFamily:
|
|
78
|
+
fontFamily:
|
|
79
|
+
theme.fontFamilies.mono ??
|
|
80
|
+
Platform.select({ ios: "Courier", android: "monospace" }),
|
|
95
81
|
fontSize: theme.fontSizes.m,
|
|
96
82
|
color: theme.colors.code,
|
|
97
83
|
textAlign: "center",
|
|
98
84
|
},
|
|
99
85
|
});
|
|
100
86
|
|
|
101
|
-
export const MathInline: FC<MathInlineProps> = ({ content }) => {
|
|
87
|
+
export const MathInline: FC<MathInlineProps> = ({ content, style }) => {
|
|
102
88
|
const { theme } = useMarkdownContext();
|
|
103
89
|
const styles = useMemo(() => createMathStyles(theme), [theme]);
|
|
104
90
|
|
|
105
91
|
if (!content) return null;
|
|
106
92
|
|
|
107
93
|
if (MathJaxComponent) {
|
|
108
|
-
const fontSize = theme.fontSizes.
|
|
94
|
+
const fontSize = theme.fontSizes.s;
|
|
109
95
|
return (
|
|
110
|
-
<View style={styles.mathInlineContainer}>
|
|
96
|
+
<View style={[styles.mathInlineContainer, style]}>
|
|
111
97
|
<MathJaxComponent
|
|
112
98
|
fontSize={fontSize}
|
|
113
99
|
color={theme.colors.text}
|
|
114
|
-
fontCache={
|
|
115
|
-
style={
|
|
100
|
+
fontCache={false}
|
|
101
|
+
style={{ backgroundColor: "transparent" }}
|
|
116
102
|
>
|
|
117
103
|
{content}
|
|
118
104
|
</MathJaxComponent>
|
|
@@ -121,7 +107,7 @@ export const MathInline: FC<MathInlineProps> = ({ content }) => {
|
|
|
121
107
|
}
|
|
122
108
|
|
|
123
109
|
return (
|
|
124
|
-
<View style={styles.mathInlineFallbackContainer}>
|
|
110
|
+
<View style={[styles.mathInlineFallbackContainer, style]}>
|
|
125
111
|
<Text style={styles.mathInlineFallback}>{content}</Text>
|
|
126
112
|
</View>
|
|
127
113
|
);
|
|
@@ -129,13 +115,10 @@ export const MathInline: FC<MathInlineProps> = ({ content }) => {
|
|
|
129
115
|
|
|
130
116
|
interface MathBlockProps {
|
|
131
117
|
content?: string;
|
|
118
|
+
style?: ViewStyle;
|
|
132
119
|
}
|
|
133
120
|
|
|
134
|
-
|
|
135
|
-
* Block math renderer.
|
|
136
|
-
* Uses react-native-mathjax-svg if installed, otherwise shows raw LaTeX.
|
|
137
|
-
*/
|
|
138
|
-
export const MathBlock: FC<MathBlockProps> = ({ content }) => {
|
|
121
|
+
export const MathBlock: FC<MathBlockProps> = ({ content, style }) => {
|
|
139
122
|
const { theme } = useMarkdownContext();
|
|
140
123
|
const styles = useMemo(() => createMathStyles(theme), [theme]);
|
|
141
124
|
|
|
@@ -143,11 +126,12 @@ export const MathBlock: FC<MathBlockProps> = ({ content }) => {
|
|
|
143
126
|
|
|
144
127
|
if (MathJaxComponent) {
|
|
145
128
|
return (
|
|
146
|
-
<View style={styles.mathBlockContainer}>
|
|
129
|
+
<View style={[styles.mathBlockContainer, style]}>
|
|
147
130
|
<MathJaxComponent
|
|
148
131
|
fontSize={theme.fontSizes.l}
|
|
149
132
|
color={theme.colors.text}
|
|
150
|
-
fontCache={
|
|
133
|
+
fontCache={false}
|
|
134
|
+
style={{ backgroundColor: "transparent" }}
|
|
151
135
|
>
|
|
152
136
|
{`\\displaystyle ${content}`}
|
|
153
137
|
</MathJaxComponent>
|
|
@@ -156,9 +140,8 @@ export const MathBlock: FC<MathBlockProps> = ({ content }) => {
|
|
|
156
140
|
}
|
|
157
141
|
|
|
158
142
|
return (
|
|
159
|
-
<View style={styles.mathBlockFallbackContainer}>
|
|
143
|
+
<View style={[styles.mathBlockFallbackContainer, style]}>
|
|
160
144
|
<Text style={styles.mathBlockFallback}>{content}</Text>
|
|
161
145
|
</View>
|
|
162
146
|
);
|
|
163
147
|
};
|
|
164
|
-
|
|
@@ -8,11 +8,6 @@ interface ParagraphProps {
|
|
|
8
8
|
style?: StyleProp<ViewStyle>;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
/**
|
|
12
|
-
* Paragraph component that supports mixed content (Text and View elements).
|
|
13
|
-
* Uses View with flexDirection: 'row' and flexWrap: 'wrap' to allow inline flow
|
|
14
|
-
* of both text and non-text elements (like inline math).
|
|
15
|
-
*/
|
|
16
11
|
export const Paragraph: FC<ParagraphProps> = ({
|
|
17
12
|
children,
|
|
18
13
|
inListItem,
|
|
@@ -25,7 +20,6 @@ export const Paragraph: FC<ParagraphProps> = ({
|
|
|
25
20
|
paragraph: {
|
|
26
21
|
flexDirection: "row",
|
|
27
22
|
flexWrap: "wrap",
|
|
28
|
-
alignItems: "baseline",
|
|
29
23
|
marginBottom: theme.spacing.l,
|
|
30
24
|
gap: 0,
|
|
31
25
|
},
|
|
@@ -35,7 +29,7 @@ export const Paragraph: FC<ParagraphProps> = ({
|
|
|
35
29
|
flexShrink: 1,
|
|
36
30
|
},
|
|
37
31
|
}),
|
|
38
|
-
[theme]
|
|
32
|
+
[theme],
|
|
39
33
|
);
|
|
40
34
|
|
|
41
35
|
return (
|
|
@@ -50,4 +44,3 @@ export const Paragraph: FC<ParagraphProps> = ({
|
|
|
50
44
|
</View>
|
|
51
45
|
);
|
|
52
46
|
};
|
|
53
|
-
|