react-native-marked 6.0.7 → 7.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -53
- package/dist/commonjs/components/MDTable.js +60 -0
- package/dist/commonjs/components/MDTable.js.map +1 -0
- package/dist/commonjs/hooks/useMarkdown.js +1 -1
- package/dist/commonjs/hooks/useMarkdown.js.map +1 -1
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/lib/Parser.js +5 -9
- package/dist/commonjs/lib/Parser.js.map +1 -1
- package/dist/commonjs/lib/Renderer.js +12 -42
- package/dist/commonjs/lib/Renderer.js.map +1 -1
- package/dist/commonjs/theme/styles.js +2 -1
- package/dist/commonjs/theme/styles.js.map +1 -1
- package/dist/module/components/MDTable.js +54 -0
- package/dist/module/components/MDTable.js.map +1 -0
- package/dist/module/hooks/useMarkdown.js +2 -2
- package/dist/module/hooks/useMarkdown.js.map +1 -1
- package/dist/module/index.js +2 -2
- package/dist/module/index.js.map +1 -1
- package/dist/module/lib/Parser.js +5 -9
- package/dist/module/lib/Parser.js.map +1 -1
- package/dist/module/lib/Renderer.js +12 -42
- package/dist/module/lib/Renderer.js.map +1 -1
- package/dist/module/theme/styles.js +2 -1
- package/dist/module/theme/styles.js.map +1 -1
- package/dist/typescript/components/MDTable.d.ts +15 -0
- package/dist/typescript/components/MDTable.d.ts.map +1 -0
- package/dist/typescript/hooks/useMarkdown.d.ts +2 -2
- package/dist/typescript/hooks/useMarkdown.d.ts.map +1 -1
- package/dist/typescript/index.d.ts +6 -5
- package/dist/typescript/index.d.ts.map +1 -1
- package/dist/typescript/lib/Parser.d.ts +3 -2
- package/dist/typescript/lib/Parser.d.ts.map +1 -1
- package/dist/typescript/lib/Renderer.d.ts +0 -1
- package/dist/typescript/lib/Renderer.d.ts.map +1 -1
- package/dist/typescript/lib/types.d.ts +2 -11
- package/dist/typescript/lib/types.d.ts.map +1 -1
- package/package.json +25 -28
- package/src/components/MDTable.tsx +60 -0
- package/src/hooks/useMarkdown.ts +5 -5
- package/src/index.ts +6 -4
- package/src/lib/Parser.tsx +18 -22
- package/src/lib/Renderer.tsx +12 -45
- package/src/lib/types.ts +2 -40
- package/src/theme/styles.ts +1 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React, { memo, type FunctionComponent, type ReactNode } from "react";
|
|
2
|
+
import { View, ScrollView, type ViewStyle } from "react-native";
|
|
3
|
+
import { Table, TableWrapper, Cell } from "react-native-reanimated-table";
|
|
4
|
+
|
|
5
|
+
type MDTableProps = {
|
|
6
|
+
header: ReactNode[][];
|
|
7
|
+
rows: ReactNode[][][];
|
|
8
|
+
widthArr: number[];
|
|
9
|
+
rowStyle?: ViewStyle;
|
|
10
|
+
cellStyle?: ViewStyle;
|
|
11
|
+
borderColor?: string;
|
|
12
|
+
borderWidth?: number;
|
|
13
|
+
tableStyle?: ViewStyle;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const MDTable: FunctionComponent<MDTableProps> = ({
|
|
17
|
+
header,
|
|
18
|
+
rows,
|
|
19
|
+
widthArr,
|
|
20
|
+
cellStyle,
|
|
21
|
+
rowStyle,
|
|
22
|
+
tableStyle,
|
|
23
|
+
borderColor,
|
|
24
|
+
borderWidth,
|
|
25
|
+
}) => {
|
|
26
|
+
return (
|
|
27
|
+
<ScrollView horizontal={true}>
|
|
28
|
+
<Table borderStyle={{ borderColor, borderWidth }} style={tableStyle}>
|
|
29
|
+
<TableWrapper style={rowStyle}>
|
|
30
|
+
{header.map((headerCol, index) => {
|
|
31
|
+
return (
|
|
32
|
+
<Cell
|
|
33
|
+
width={widthArr[index]}
|
|
34
|
+
key={`${index}`}
|
|
35
|
+
data={<View style={cellStyle}>{headerCol}</View>}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
})}
|
|
39
|
+
</TableWrapper>
|
|
40
|
+
{rows.map((rowData, index) => {
|
|
41
|
+
return (
|
|
42
|
+
<TableWrapper key={`${index}`} style={rowStyle}>
|
|
43
|
+
{rowData.map((cellData, cellIndex) => {
|
|
44
|
+
return (
|
|
45
|
+
<Cell
|
|
46
|
+
width={widthArr[cellIndex]}
|
|
47
|
+
key={`${cellIndex}`}
|
|
48
|
+
data={<View style={cellStyle}>{cellData}</View>}
|
|
49
|
+
/>
|
|
50
|
+
);
|
|
51
|
+
})}
|
|
52
|
+
</TableWrapper>
|
|
53
|
+
);
|
|
54
|
+
})}
|
|
55
|
+
</Table>
|
|
56
|
+
</ScrollView>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export default memo(MDTable);
|
package/src/hooks/useMarkdown.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { useMemo, type ReactNode } from "react";
|
|
2
|
-
import { type Tokenizer
|
|
2
|
+
import { lexer, type Tokenizer } from "marked";
|
|
3
3
|
import type { MarkedStyles, UserTheme } from "./../theme/types";
|
|
4
4
|
import Parser from "../lib/Parser";
|
|
5
5
|
import Renderer from "../lib/Renderer";
|
|
6
6
|
import getStyles from "./../theme/styles";
|
|
7
7
|
import type { ColorSchemeName } from "react-native";
|
|
8
|
-
import type {
|
|
8
|
+
import type { RendererInterface } from "../lib/types";
|
|
9
9
|
|
|
10
10
|
export interface useMarkdownHookOptions {
|
|
11
11
|
colorScheme?: ColorSchemeName;
|
|
@@ -13,7 +13,7 @@ export interface useMarkdownHookOptions {
|
|
|
13
13
|
theme?: UserTheme;
|
|
14
14
|
styles?: MarkedStyles;
|
|
15
15
|
baseUrl?: string;
|
|
16
|
-
tokenizer?: Tokenizer
|
|
16
|
+
tokenizer?: Tokenizer;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
const useMarkdown = (
|
|
@@ -36,9 +36,9 @@ const useMarkdown = (
|
|
|
36
36
|
);
|
|
37
37
|
|
|
38
38
|
const elements = useMemo(() => {
|
|
39
|
-
const tokens =
|
|
39
|
+
const tokens = lexer(value, {
|
|
40
40
|
gfm: true,
|
|
41
|
-
tokenizer: options?.tokenizer
|
|
41
|
+
tokenizer: options?.tokenizer,
|
|
42
42
|
});
|
|
43
43
|
return parser.parse(tokens);
|
|
44
44
|
}, [value, parser, options?.tokenizer]);
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Tokenizer, marked } from "marked";
|
|
1
|
+
import { Tokenizer as MarkedTokenizer, marked } from "marked";
|
|
2
|
+
import type { Token, Tokens } from "marked";
|
|
2
3
|
import Markdown from "./lib/Markdown";
|
|
3
4
|
import Renderer from "./lib/Renderer";
|
|
4
5
|
import useMarkdown, { type useMarkdownHookOptions } from "./hooks/useMarkdown";
|
|
@@ -6,7 +7,6 @@ import type {
|
|
|
6
7
|
MarkdownProps,
|
|
7
8
|
ParserOptions,
|
|
8
9
|
RendererInterface,
|
|
9
|
-
CustomToken,
|
|
10
10
|
} from "./lib/types";
|
|
11
11
|
|
|
12
12
|
const MarkedLexer = marked.lexer;
|
|
@@ -16,8 +16,10 @@ export type {
|
|
|
16
16
|
ParserOptions,
|
|
17
17
|
RendererInterface,
|
|
18
18
|
useMarkdownHookOptions,
|
|
19
|
-
|
|
19
|
+
Token,
|
|
20
|
+
Tokens,
|
|
20
21
|
};
|
|
21
22
|
|
|
22
|
-
export {
|
|
23
|
+
export { useMarkdown, MarkedLexer, Renderer, MarkedTokenizer };
|
|
24
|
+
|
|
23
25
|
export default Markdown;
|
package/src/lib/Parser.tsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import type { TextStyle, ViewStyle, ImageStyle } from "react-native";
|
|
3
|
-
import type {
|
|
3
|
+
import type { Token, Tokens } from "marked";
|
|
4
4
|
import { decode } from "html-entities";
|
|
5
5
|
import type { MarkedStyles } from "../theme/types";
|
|
6
|
-
import type { RendererInterface, ParserOptions
|
|
6
|
+
import type { RendererInterface, ParserOptions } from "./types";
|
|
7
7
|
import { getValidURL } from "./../utils/url";
|
|
8
8
|
import { getTableColAlignmentStyle } from "./../utils/table";
|
|
9
9
|
|
|
@@ -27,11 +27,16 @@ class Parser {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
parse(tokens
|
|
30
|
+
parse(tokens?: Token[]) {
|
|
31
31
|
return this._parse(tokens);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
private _parse(
|
|
34
|
+
private _parse(
|
|
35
|
+
tokens?: Token[],
|
|
36
|
+
styles?: ViewStyle | TextStyle | ImageStyle,
|
|
37
|
+
): ReactNode[] {
|
|
38
|
+
if (!tokens) return [];
|
|
39
|
+
|
|
35
40
|
const elements: ReactNode[] = tokens.map((token) => {
|
|
36
41
|
return this._parseToken(token, styles);
|
|
37
42
|
});
|
|
@@ -45,7 +50,7 @@ class Parser {
|
|
|
45
50
|
switch (token.type) {
|
|
46
51
|
case "paragraph": {
|
|
47
52
|
const children = this.getNormalizedSiblingNodesForBlockAndInlineTokens(
|
|
48
|
-
token.tokens,
|
|
53
|
+
token.tokens ?? [],
|
|
49
54
|
this.styles.text,
|
|
50
55
|
);
|
|
51
56
|
|
|
@@ -81,11 +86,11 @@ class Parser {
|
|
|
81
86
|
if (Number.isNaN(startIndex)) {
|
|
82
87
|
startIndex = 1;
|
|
83
88
|
}
|
|
84
|
-
const li = token.items.map((item) => {
|
|
89
|
+
const li = (token as Tokens.List).items.map((item) => {
|
|
85
90
|
const children = item.tokens.flatMap((cItem) => {
|
|
86
91
|
if (cItem.type === "text") {
|
|
87
92
|
/* getViewNode since tokens could contain a block like elements (i.e. img) */
|
|
88
|
-
const childTokens = (cItem as
|
|
93
|
+
const childTokens = (cItem as Tokens.Text).tokens || [];
|
|
89
94
|
const listChildren =
|
|
90
95
|
this.getNormalizedSiblingNodesForBlockAndInlineTokens(
|
|
91
96
|
childTokens,
|
|
@@ -118,7 +123,7 @@ class Parser {
|
|
|
118
123
|
}
|
|
119
124
|
case "link": {
|
|
120
125
|
// Don't render anchors without text and children
|
|
121
|
-
if (token.text.trim.length < 1
|
|
126
|
+
if (token.text.trim().length < 1 || !token.tokens) {
|
|
122
127
|
return null;
|
|
123
128
|
}
|
|
124
129
|
|
|
@@ -207,13 +212,13 @@ class Parser {
|
|
|
207
212
|
});
|
|
208
213
|
}
|
|
209
214
|
case "table": {
|
|
210
|
-
const header = token.header.map((row, i) =>
|
|
215
|
+
const header = (token as Tokens.Table).header.map((row, i) =>
|
|
211
216
|
this._parse(row.tokens, {
|
|
212
217
|
...getTableColAlignmentStyle(token.align[i]),
|
|
213
218
|
}),
|
|
214
219
|
);
|
|
215
220
|
|
|
216
|
-
const rows = token.rows.map((cols) =>
|
|
221
|
+
const rows = (token as Tokens.Table).rows.map((cols) =>
|
|
217
222
|
cols.map((col, i) =>
|
|
218
223
|
this._parse(col.tokens, {
|
|
219
224
|
...getTableColAlignmentStyle(token.align[i]),
|
|
@@ -229,15 +234,6 @@ class Parser {
|
|
|
229
234
|
this.styles.tableCell,
|
|
230
235
|
);
|
|
231
236
|
}
|
|
232
|
-
case "custom": {
|
|
233
|
-
const children = this._parse(token.tokens ?? []);
|
|
234
|
-
return this.renderer.custom(
|
|
235
|
-
token.identifier,
|
|
236
|
-
token.raw,
|
|
237
|
-
children,
|
|
238
|
-
token.args,
|
|
239
|
-
);
|
|
240
|
-
}
|
|
241
237
|
default: {
|
|
242
238
|
return null;
|
|
243
239
|
}
|
|
@@ -272,14 +268,14 @@ class Parser {
|
|
|
272
268
|
// Render the current block token
|
|
273
269
|
if (t.type === "image") {
|
|
274
270
|
siblingNodes.push(this._parseToken(t));
|
|
275
|
-
} else if (t.type === "link") {
|
|
276
|
-
const imageToken = t.tokens[0] as
|
|
271
|
+
} else if (t.type === "link" && t.tokens && t.tokens[0]) {
|
|
272
|
+
const imageToken = t.tokens[0] as Tokens.Image;
|
|
277
273
|
const href = getValidURL(this.baseUrl, t.href);
|
|
278
274
|
siblingNodes.push(
|
|
279
275
|
this.renderer.linkImage(
|
|
280
276
|
href,
|
|
281
277
|
imageToken.href,
|
|
282
|
-
imageToken.text
|
|
278
|
+
imageToken.text ?? imageToken.title ?? "",
|
|
283
279
|
this.styles.image,
|
|
284
280
|
),
|
|
285
281
|
);
|
package/src/lib/Renderer.tsx
CHANGED
|
@@ -12,13 +12,13 @@ import {
|
|
|
12
12
|
import MarkedList from "@jsamr/react-native-li";
|
|
13
13
|
import Disc from "@jsamr/counter-style/presets/disc";
|
|
14
14
|
import Decimal from "@jsamr/counter-style/presets/decimal";
|
|
15
|
-
import
|
|
16
|
-
import { Table, Cell, TableWrapper } from "react-native-table-component";
|
|
15
|
+
import Slugger from "github-slugger";
|
|
17
16
|
import MDImage from "./../components/MDImage";
|
|
18
17
|
import { onLinkPress } from "../utils/handlers";
|
|
19
18
|
import type { RendererInterface } from "./types";
|
|
20
19
|
import { getTableWidthArr } from "../utils/table";
|
|
21
20
|
import MDSvg from "./../components/MDSvg";
|
|
21
|
+
import MDTable from "./../components/MDTable";
|
|
22
22
|
|
|
23
23
|
class Renderer implements RendererInterface {
|
|
24
24
|
private slugPrefix = "react-native-marked-ele";
|
|
@@ -178,53 +178,20 @@ class Renderer implements RendererInterface {
|
|
|
178
178
|
cellStyle?: ViewStyle,
|
|
179
179
|
): React.ReactNode {
|
|
180
180
|
const widthArr = getTableWidthArr(header.length, this.windowWidth);
|
|
181
|
-
const { borderWidth, borderColor
|
|
181
|
+
const { borderWidth, borderColor } = tableStyle || {};
|
|
182
182
|
return (
|
|
183
|
-
<
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
width={widthArr[index]}
|
|
193
|
-
key={`${index}`}
|
|
194
|
-
data={<View style={cellStyle}>{headerCol}</View>}
|
|
195
|
-
/>
|
|
196
|
-
);
|
|
197
|
-
})}
|
|
198
|
-
</TableWrapper>
|
|
199
|
-
{rows.map((rowData, index) => {
|
|
200
|
-
return (
|
|
201
|
-
<TableWrapper key={`${index}`} style={rowStyle}>
|
|
202
|
-
{rowData.map((cellData, cellIndex) => {
|
|
203
|
-
return (
|
|
204
|
-
<Cell
|
|
205
|
-
width={widthArr[cellIndex]}
|
|
206
|
-
key={`${cellIndex}`}
|
|
207
|
-
data={<View style={cellStyle}>{cellData}</View>}
|
|
208
|
-
/>
|
|
209
|
-
);
|
|
210
|
-
})}
|
|
211
|
-
</TableWrapper>
|
|
212
|
-
);
|
|
213
|
-
})}
|
|
214
|
-
</Table>
|
|
215
|
-
</ScrollView>
|
|
183
|
+
<MDTable
|
|
184
|
+
header={header}
|
|
185
|
+
rows={rows}
|
|
186
|
+
widthArr={widthArr}
|
|
187
|
+
rowStyle={rowStyle}
|
|
188
|
+
cellStyle={cellStyle}
|
|
189
|
+
borderColor={borderColor as string}
|
|
190
|
+
borderWidth={borderWidth}
|
|
191
|
+
/>
|
|
216
192
|
);
|
|
217
193
|
}
|
|
218
194
|
|
|
219
|
-
custom(
|
|
220
|
-
_identifier: string,
|
|
221
|
-
_raw: string,
|
|
222
|
-
_children: ReactNode[],
|
|
223
|
-
_args: Record<string, unknown>,
|
|
224
|
-
): ReactNode {
|
|
225
|
-
return null;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
195
|
getKey(): string {
|
|
229
196
|
return this.slugger.slug(this.slugPrefix);
|
|
230
197
|
}
|
package/src/lib/types.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type {
|
|
|
6
6
|
ImageStyle,
|
|
7
7
|
} from "react-native";
|
|
8
8
|
import type { MarkedStyles, UserTheme } from "./../theme/types";
|
|
9
|
-
import type { Tokenizer
|
|
9
|
+
import type { Tokenizer } from "marked";
|
|
10
10
|
|
|
11
11
|
export interface ParserOptions {
|
|
12
12
|
styles?: MarkedStyles;
|
|
@@ -21,7 +21,7 @@ export interface MarkdownProps extends Partial<ParserOptions> {
|
|
|
21
21
|
"data" | "renderItem" | "horizontal"
|
|
22
22
|
>;
|
|
23
23
|
theme?: UserTheme;
|
|
24
|
-
tokenizer?:
|
|
24
|
+
tokenizer?: Tokenizer;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export type TableColAlignment = "center" | "left" | "right" | null;
|
|
@@ -76,42 +76,4 @@ export interface RendererInterface {
|
|
|
76
76
|
rowStyle?: ViewStyle,
|
|
77
77
|
cellStyle?: ViewStyle,
|
|
78
78
|
): ReactNode;
|
|
79
|
-
custom(
|
|
80
|
-
identifier: string,
|
|
81
|
-
raw: string,
|
|
82
|
-
children?: ReactNode[],
|
|
83
|
-
args?: Record<string, unknown>,
|
|
84
|
-
): ReactNode;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export interface CustomToken {
|
|
88
|
-
type: "custom";
|
|
89
|
-
identifier: string;
|
|
90
|
-
raw: string;
|
|
91
|
-
tokens?: Token[];
|
|
92
|
-
args?: Record<string, unknown>;
|
|
93
79
|
}
|
|
94
|
-
|
|
95
|
-
export type Token =
|
|
96
|
-
| marked.Tokens.Space
|
|
97
|
-
| marked.Tokens.Code
|
|
98
|
-
| marked.Tokens.Heading
|
|
99
|
-
| marked.Tokens.Table
|
|
100
|
-
| marked.Tokens.Hr
|
|
101
|
-
| marked.Tokens.Blockquote
|
|
102
|
-
| marked.Tokens.List
|
|
103
|
-
| marked.Tokens.ListItem
|
|
104
|
-
| marked.Tokens.Paragraph
|
|
105
|
-
| marked.Tokens.HTML
|
|
106
|
-
| marked.Tokens.Text
|
|
107
|
-
| marked.Tokens.Def
|
|
108
|
-
| marked.Tokens.Escape
|
|
109
|
-
| marked.Tokens.Tag
|
|
110
|
-
| marked.Tokens.Image
|
|
111
|
-
| marked.Tokens.Link
|
|
112
|
-
| marked.Tokens.Strong
|
|
113
|
-
| marked.Tokens.Em
|
|
114
|
-
| marked.Tokens.Codespan
|
|
115
|
-
| marked.Tokens.Br
|
|
116
|
-
| marked.Tokens.Del
|
|
117
|
-
| CustomToken;
|
package/src/theme/styles.ts
CHANGED
|
@@ -51,7 +51,6 @@ const getStyles = (
|
|
|
51
51
|
]),
|
|
52
52
|
text: StyleSheet.flatten([fontStyle.regular, userStyles?.text]),
|
|
53
53
|
paragraph: StyleSheet.flatten([
|
|
54
|
-
fontStyle.regular,
|
|
55
54
|
{
|
|
56
55
|
paddingVertical: mdSpacing.m,
|
|
57
56
|
},
|
|
@@ -160,6 +159,7 @@ const getStyles = (
|
|
|
160
159
|
},
|
|
161
160
|
userStyles?.hr,
|
|
162
161
|
]),
|
|
162
|
+
list: StyleSheet.flatten([userStyles?.list]),
|
|
163
163
|
li: StyleSheet.flatten([
|
|
164
164
|
fontStyle.regular,
|
|
165
165
|
{
|