react-native-marked 1.0.1 → 1.1.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 +2 -0
- package/dist/commonjs/lib/Markdown.js.map +1 -1
- package/dist/commonjs/lib/Parser.js +35 -14
- package/dist/commonjs/lib/Parser.js.map +1 -1
- package/dist/commonjs/lib/Renderer.js +1 -4
- package/dist/commonjs/lib/Renderer.js.map +1 -1
- package/dist/commonjs/lib/types.js +6 -0
- package/dist/commonjs/lib/types.js.map +1 -0
- package/dist/module/lib/Markdown.js.map +1 -1
- package/dist/module/lib/Parser.js +35 -14
- package/dist/module/lib/Parser.js.map +1 -1
- package/dist/module/lib/Renderer.js +2 -6
- package/dist/module/lib/Renderer.js.map +1 -1
- package/dist/module/lib/types.js +2 -0
- package/dist/module/lib/types.js.map +1 -0
- package/dist/typescript/lib/Markdown.d.ts +2 -8
- package/dist/typescript/lib/Parser.d.ts +2 -6
- package/dist/typescript/lib/Renderer.d.ts +7 -8
- package/dist/typescript/lib/types.d.ts +14 -0
- package/package.json +5 -4
- package/src/lib/Markdown.tsx +2 -11
- package/src/lib/Parser.tsx +36 -29
- package/src/lib/Renderer.tsx +12 -20
- package/src/lib/types.ts +25 -0
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# react-native-marked
|
|
2
2
|
|
|
3
|
+
[](https://github.com/gmsgowtham/react-native-marked/actions/workflows/build.yml)
|
|
4
|
+
|
|
3
5
|
Markdown renderer for React Native powered by [marked.js](https://marked.js.org/)
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Markdown","value","flatListProps","styles","userStyles","systemTheme","useColorScheme","useMemo","getStyles","rnElements","parser","Parser","tokens","marked","lexer","trim","parse","renderItem","useCallback","item","keyExtractor","_","index","toString","container","memo"],"sources":["Markdown.tsx"],"sourcesContent":["import React, { memo, ReactNode, useCallback, useMemo } from 'react';\nimport { FlatList,
|
|
1
|
+
{"version":3,"names":["Markdown","value","flatListProps","styles","userStyles","systemTheme","useColorScheme","useMemo","getStyles","rnElements","parser","Parser","tokens","marked","lexer","trim","parse","renderItem","useCallback","item","keyExtractor","_","index","toString","container","memo"],"sources":["Markdown.tsx"],"sourcesContent":["import React, { memo, ReactNode, useCallback, useMemo } from 'react';\nimport { FlatList, useColorScheme } from 'react-native';\nimport { marked } from 'marked';\nimport Parser from './Parser';\nimport getStyles from '../theme/styles';\nimport type { MarkdownProps } from './types';\n\nconst Markdown = ({\n value,\n flatListProps,\n styles: userStyles,\n}: MarkdownProps) => {\n const systemTheme = useColorScheme();\n const styles = useMemo(\n () => getStyles(userStyles, systemTheme),\n [userStyles, systemTheme]\n );\n\n const rnElements = useMemo(() => {\n const parser = new Parser({\n styles,\n });\n const tokens = marked.lexer(value.trim());\n\n return parser.parse(tokens);\n }, [value, styles]);\n\n const renderItem = useCallback(({ item }: { item: ReactNode }) => {\n return <>{item}</>;\n }, []);\n\n const keyExtractor = useCallback((_, index) => index.toString(), []);\n\n return (\n <FlatList\n keyExtractor={keyExtractor}\n maxToRenderPerBatch={8}\n initialNumToRender={8}\n removeClippedSubviews\n style={styles.container}\n {...flatListProps}\n data={rnElements}\n renderItem={renderItem}\n />\n );\n};\n\nexport default memo(Markdown);\n"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;;;;;;;;;AAGA,MAAMA,QAAQ,GAAG,QAII;EAAA,IAJH;IAChBC,KADgB;IAEhBC,aAFgB;IAGhBC,MAAM,EAAEC;EAHQ,CAIG;EACnB,MAAMC,WAAW,GAAG,IAAAC,2BAAA,GAApB;EACA,MAAMH,MAAM,GAAG,IAAAI,cAAA,EACb,MAAM,IAAAC,eAAA,EAAUJ,UAAV,EAAsBC,WAAtB,CADO,EAEb,CAACD,UAAD,EAAaC,WAAb,CAFa,CAAf;EAKA,MAAMI,UAAU,GAAG,IAAAF,cAAA,EAAQ,MAAM;IAC/B,MAAMG,MAAM,GAAG,IAAIC,eAAJ,CAAW;MACxBR;IADwB,CAAX,CAAf;;IAGA,MAAMS,MAAM,GAAGC,cAAA,CAAOC,KAAP,CAAab,KAAK,CAACc,IAAN,EAAb,CAAf;;IAEA,OAAOL,MAAM,CAACM,KAAP,CAAaJ,MAAb,CAAP;EACD,CAPkB,EAOhB,CAACX,KAAD,EAAQE,MAAR,CAPgB,CAAnB;EASA,MAAMc,UAAU,GAAG,IAAAC,kBAAA,EAAY,SAAmC;IAAA,IAAlC;MAAEC;IAAF,CAAkC;IAChE,oBAAO,4DAAGA,IAAH,CAAP;EACD,CAFkB,EAEhB,EAFgB,CAAnB;EAIA,MAAMC,YAAY,GAAG,IAAAF,kBAAA,EAAY,CAACG,CAAD,EAAIC,KAAJ,KAAcA,KAAK,CAACC,QAAN,EAA1B,EAA4C,EAA5C,CAArB;EAEA,oBACE,6BAAC,qBAAD;IACE,YAAY,EAAEH,YADhB;IAEE,mBAAmB,EAAE,CAFvB;IAGE,kBAAkB,EAAE,CAHtB;IAIE,qBAAqB,MAJvB;IAKE,KAAK,EAAEjB,MAAM,CAACqB;EALhB,GAMMtB,aANN;IAOE,IAAI,EAAEO,UAPR;IAQE,UAAU,EAAEQ;EARd,GADF;AAYD,CAtCD;;4BAwCe,IAAAQ,WAAA,EAAKzB,QAAL,C"}
|
|
@@ -45,6 +45,7 @@ class Parser {
|
|
|
45
45
|
let tempTokens = [];
|
|
46
46
|
const paragraphChildren = [];
|
|
47
47
|
token.tokens.forEach(t => {
|
|
48
|
+
/* To avoid inlining of image */
|
|
48
49
|
if (t.type === 'image') {
|
|
49
50
|
paragraphChildren.push(this.renderer.getTextNode(this.parseInline(tempTokens), this.styles.text));
|
|
50
51
|
paragraphChildren.push(this.parseInline([t]));
|
|
@@ -85,10 +86,27 @@ class Parser {
|
|
|
85
86
|
|
|
86
87
|
case 'list':
|
|
87
88
|
{
|
|
88
|
-
const li = token.items.map(item =>
|
|
89
|
+
const li = token.items.map(item => {
|
|
90
|
+
var _item$tokens$, _item$tokens$2;
|
|
91
|
+
|
|
92
|
+
if (item.tokens.length > 0 && ((_item$tokens$ = item.tokens[0]) === null || _item$tokens$ === void 0 ? void 0 : _item$tokens$.type) === 'text' && // @ts-ignore
|
|
93
|
+
Array.isArray((_item$tokens$2 = item.tokens[0]) === null || _item$tokens$2 === void 0 ? void 0 : _item$tokens$2.tokens)) {
|
|
94
|
+
var _item$tokens$3;
|
|
95
|
+
|
|
96
|
+
return this.renderer.getTextNode( // @ts-ignore
|
|
97
|
+
this.parseInline((_item$tokens$3 = item.tokens[0]) === null || _item$tokens$3 === void 0 ? void 0 : _item$tokens$3.tokens), this.styles.li);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return this.renderer.getTextNode(item.text, this.styles.li);
|
|
101
|
+
});
|
|
89
102
|
return this.renderer.getListNode(token.ordered, li, this.styles.list, this.styles.li);
|
|
90
103
|
}
|
|
91
104
|
|
|
105
|
+
case 'html':
|
|
106
|
+
{
|
|
107
|
+
return this.renderer.getTextNode(token.text.trim(), this.styles.text);
|
|
108
|
+
}
|
|
109
|
+
|
|
92
110
|
default:
|
|
93
111
|
console.warn(`Token with '${token.type}' type was not found.`);
|
|
94
112
|
return null;
|
|
@@ -97,26 +115,23 @@ class Parser {
|
|
|
97
115
|
return elements;
|
|
98
116
|
}
|
|
99
117
|
|
|
100
|
-
parseInline(tokens) {
|
|
101
|
-
let styles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
118
|
+
parseInline(tokens, styles) {
|
|
102
119
|
const elements = tokens.map(token => {
|
|
103
120
|
if (!token) return null;
|
|
104
121
|
|
|
105
122
|
switch (token.type) {
|
|
106
123
|
case 'escape':
|
|
107
124
|
{
|
|
108
|
-
return this.renderer.getTextNode(token.text,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
case 'html':
|
|
112
|
-
{
|
|
113
|
-
console.log('html', token);
|
|
114
|
-
return null;
|
|
125
|
+
return this.renderer.getTextNode(token.text, { ...styles,
|
|
126
|
+
...this.styles.text
|
|
127
|
+
});
|
|
115
128
|
}
|
|
116
129
|
|
|
117
130
|
case 'link':
|
|
118
131
|
{
|
|
119
|
-
return this.renderer.getLinkNode(token.text, token.href,
|
|
132
|
+
return this.renderer.getLinkNode(token.text, token.href, { ...styles,
|
|
133
|
+
...this.styles.link
|
|
134
|
+
});
|
|
120
135
|
}
|
|
121
136
|
|
|
122
137
|
case 'image':
|
|
@@ -126,12 +141,16 @@ class Parser {
|
|
|
126
141
|
|
|
127
142
|
case 'strong':
|
|
128
143
|
{
|
|
129
|
-
return this.renderer.getTextNode(this.parseInline(token.tokens, this.styles.strong),
|
|
144
|
+
return this.renderer.getTextNode(this.parseInline(token.tokens, this.styles.strong), { ...styles,
|
|
145
|
+
...this.styles.strong
|
|
146
|
+
});
|
|
130
147
|
}
|
|
131
148
|
|
|
132
149
|
case 'em':
|
|
133
150
|
{
|
|
134
|
-
return this.renderer.getTextNode(this.parseInline(token.tokens, this.styles.em),
|
|
151
|
+
return this.renderer.getTextNode(this.parseInline(token.tokens, this.styles.em), { ...styles,
|
|
152
|
+
...this.styles.em
|
|
153
|
+
});
|
|
135
154
|
}
|
|
136
155
|
|
|
137
156
|
case 'codespan':
|
|
@@ -151,7 +170,9 @@ class Parser {
|
|
|
151
170
|
|
|
152
171
|
case 'text':
|
|
153
172
|
{
|
|
154
|
-
return this.renderer.getTextNode(token.raw,
|
|
173
|
+
return this.renderer.getTextNode(token.raw, { ...styles,
|
|
174
|
+
...this.styles.text
|
|
175
|
+
});
|
|
155
176
|
}
|
|
156
177
|
|
|
157
178
|
default:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Parser","constructor","options","styles","renderer","Renderer","headingStylesMap","h1","h2","h3","h4","h5","h6","parse","tokens","elements","map","token","type","tempTokens","paragraphChildren","forEach","t","push","getTextNode","parseInline","text","length","getViewNode","paragraph","getBlockquoteNode","blockquote","depth","getCodeBlockNode","code","em","hr","li","items","item","getListNode","ordered","list","console","warn","log","getLinkNode","href","link","getImageNode","strong","codespan","raw"],"sources":["Parser.tsx"],"sourcesContent":["import type { marked } from 'marked';\nimport type { ImageStyle, StyleProp, TextStyle, ViewStyle } from 'react-native';\nimport Renderer from './Renderer';\nimport type { MarkedStyles } from '../theme/types';\n\ninterface ParserOptions {\n styles?: MarkedStyles;\n}\n\nclass Parser {\n private renderer;\n private styles: MarkedStyles;\n private headingStylesMap: Record<number, TextStyle | undefined>;\n constructor(options: ParserOptions) {\n this.styles = { ...options.styles };\n this.renderer = new Renderer();\n this.headingStylesMap = {\n 1: this.styles.h1,\n 2: this.styles.h2,\n 3: this.styles.h3,\n 4: this.styles.h4,\n 5: this.styles.h5,\n 6: this.styles.h6,\n };\n }\n\n parse(tokens: marked.Token[]) {\n const elements: React.ReactNode[] = tokens.map((token) => {\n switch (token.type) {\n case 'space': {\n return null;\n }\n case 'paragraph': {\n let tempTokens: marked.Token[] = [];\n const paragraphChildren: React.ReactNode[] = [];\n token.tokens.forEach((t) => {\n if (t.type === 'image') {\n paragraphChildren.push(\n this.renderer.getTextNode(\n this.parseInline(tempTokens),\n this.styles.text\n )\n );\n paragraphChildren.push(this.parseInline([t]));\n tempTokens = [];\n return;\n }\n tempTokens = [...tempTokens, t];\n });\n\n if (tempTokens.length > 0) {\n paragraphChildren.push(\n this.renderer.getTextNode(this.parseInline(tempTokens), {})\n );\n }\n\n return this.renderer.getViewNode(\n paragraphChildren,\n this.styles.paragraph\n );\n }\n case 'blockquote': {\n return this.renderer.getBlockquoteNode(\n this.parse(token.tokens),\n this.styles.blockquote\n );\n }\n case 'heading': {\n const styles = this.headingStylesMap[token.depth] ?? this.styles.text;\n return this.renderer.getTextNode(token.text, styles);\n }\n case 'code': {\n return this.renderer.getCodeBlockNode(\n token.text,\n this.styles.code,\n this.styles.em\n );\n }\n case 'hr': {\n return this.renderer.getViewNode(null, this.styles.hr);\n }\n case 'list': {\n const li = token.items.map((item) => item.text);\n return this.renderer.getListNode(\n token.ordered,\n li,\n this.styles.list,\n this.styles.li\n );\n }\n default:\n console.warn(`Token with '${token.type}' type was not found.`);\n return null;\n }\n });\n return elements;\n }\n\n parseInline(\n tokens: marked.Token[],\n styles: StyleProp<ViewStyle | TextStyle | ImageStyle> = {}\n ) {\n const elements: React.ReactNode[] = tokens.map((token) => {\n if (!token) return null;\n\n switch (token.type) {\n case 'escape': {\n return this.renderer.getTextNode(token.text, [\n styles,\n this.styles.text,\n ]);\n }\n case 'html': {\n console.log('html', token);\n return null;\n }\n case 'link': {\n return this.renderer.getLinkNode(token.text, token.href, [\n styles,\n this.styles.link,\n ]);\n }\n case 'image': {\n return this.renderer.getImageNode(token.href);\n }\n case 'strong': {\n return this.renderer.getTextNode(\n this.parseInline(token.tokens, this.styles.strong),\n [styles, this.styles.strong]\n );\n }\n case 'em': {\n return this.renderer.getTextNode(\n this.parseInline(token.tokens, this.styles.em),\n [styles, this.styles.em]\n );\n }\n case 'codespan': {\n return this.renderer.getTextNode(token.text, this.styles.codespan);\n }\n case 'br': {\n return this.renderer.getTextNode('\\n', {});\n }\n case 'del': {\n return null;\n }\n case 'text': {\n return this.renderer.getTextNode(token.raw, [\n styles,\n this.styles.text,\n ]);\n }\n default: {\n console.warn(`Token with '${token.type}' type was not found.`);\n return null;\n }\n }\n });\n return elements;\n }\n}\n\nexport default Parser;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["Parser","constructor","options","styles","renderer","Renderer","headingStylesMap","h1","h2","h3","h4","h5","h6","parse","tokens","elements","map","token","type","tempTokens","paragraphChildren","forEach","t","push","getTextNode","parseInline","text","length","getViewNode","paragraph","getBlockquoteNode","blockquote","depth","getCodeBlockNode","code","em","hr","li","items","item","Array","isArray","getListNode","ordered","list","trim","console","warn","getLinkNode","href","link","getImageNode","strong","codespan","raw"],"sources":["Parser.tsx"],"sourcesContent":["import type { marked } from 'marked';\nimport Renderer from './Renderer';\nimport type { MarkedStyles } from '../theme/types';\nimport type { CustomStyleProp, ParserOptions, TextStyleProp } from './types';\n\nclass Parser {\n private renderer;\n private styles: MarkedStyles;\n private headingStylesMap: Record<number, TextStyleProp>;\n constructor(options: ParserOptions) {\n this.styles = { ...options.styles };\n this.renderer = new Renderer();\n this.headingStylesMap = {\n 1: this.styles.h1,\n 2: this.styles.h2,\n 3: this.styles.h3,\n 4: this.styles.h4,\n 5: this.styles.h5,\n 6: this.styles.h6,\n };\n }\n\n parse(tokens: marked.Token[]) {\n const elements: React.ReactNode[] = tokens.map((token) => {\n switch (token.type) {\n case 'space': {\n return null;\n }\n case 'paragraph': {\n let tempTokens: marked.Token[] = [];\n const paragraphChildren: React.ReactNode[] = [];\n token.tokens.forEach((t) => {\n /* To avoid inlining of image */\n if (t.type === 'image') {\n paragraphChildren.push(\n this.renderer.getTextNode(\n this.parseInline(tempTokens),\n this.styles.text\n )\n );\n paragraphChildren.push(this.parseInline([t]));\n tempTokens = [];\n return;\n }\n tempTokens = [...tempTokens, t];\n });\n\n if (tempTokens.length > 0) {\n paragraphChildren.push(\n this.renderer.getTextNode(this.parseInline(tempTokens), {})\n );\n }\n\n return this.renderer.getViewNode(\n paragraphChildren,\n this.styles.paragraph\n );\n }\n case 'blockquote': {\n return this.renderer.getBlockquoteNode(\n this.parse(token.tokens),\n this.styles.blockquote\n );\n }\n case 'heading': {\n const styles = this.headingStylesMap[token.depth] ?? this.styles.text;\n return this.renderer.getTextNode(token.text, styles);\n }\n case 'code': {\n return this.renderer.getCodeBlockNode(\n token.text,\n this.styles.code,\n this.styles.em\n );\n }\n case 'hr': {\n return this.renderer.getViewNode(null, this.styles.hr);\n }\n case 'list': {\n const li = token.items.map((item) => {\n if (\n item.tokens.length > 0 &&\n item.tokens[0]?.type === 'text' &&\n // @ts-ignore\n Array.isArray(item.tokens[0]?.tokens)\n ) {\n return this.renderer.getTextNode(\n // @ts-ignore\n this.parseInline(item.tokens[0]?.tokens),\n this.styles.li\n );\n }\n return this.renderer.getTextNode(item.text, this.styles.li);\n });\n return this.renderer.getListNode(\n token.ordered,\n li,\n this.styles.list,\n this.styles.li\n );\n }\n case 'html': {\n return this.renderer.getTextNode(token.text.trim(), this.styles.text);\n }\n default:\n console.warn(`Token with '${token.type}' type was not found.`);\n return null;\n }\n });\n return elements;\n }\n\n parseInline(tokens: marked.Token[], styles?: CustomStyleProp) {\n const elements: React.ReactNode[] = tokens.map((token) => {\n if (!token) return null;\n\n switch (token.type) {\n case 'escape': {\n return this.renderer.getTextNode(token.text, {\n ...styles,\n ...this.styles.text,\n });\n }\n case 'link': {\n return this.renderer.getLinkNode(token.text, token.href, {\n ...styles,\n ...this.styles.link,\n });\n }\n case 'image': {\n return this.renderer.getImageNode(token.href);\n }\n case 'strong': {\n return this.renderer.getTextNode(\n this.parseInline(token.tokens, this.styles.strong),\n { ...styles, ...this.styles.strong }\n );\n }\n case 'em': {\n return this.renderer.getTextNode(\n this.parseInline(token.tokens, this.styles.em),\n { ...styles, ...this.styles.em }\n );\n }\n case 'codespan': {\n return this.renderer.getTextNode(token.text, this.styles.codespan);\n }\n case 'br': {\n return this.renderer.getTextNode('\\n', {});\n }\n case 'del': {\n return null;\n }\n case 'text': {\n return this.renderer.getTextNode(token.raw, {\n ...styles,\n ...this.styles.text,\n });\n }\n default: {\n console.warn(`Token with '${token.type}' type was not found.`);\n return null;\n }\n }\n });\n return elements;\n }\n}\n\nexport default Parser;\n"],"mappings":"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"}
|
|
@@ -82,10 +82,7 @@ class Renderer {
|
|
|
82
82
|
counterRenderer: ordered ? _decimal.default : _disc.default,
|
|
83
83
|
markerTextStyle: textStyle,
|
|
84
84
|
markerBoxStyle: listStyle
|
|
85
|
-
}, li.map(
|
|
86
|
-
key: index,
|
|
87
|
-
style: textStyle
|
|
88
|
-
}, text)));
|
|
85
|
+
}, li.map(node => node));
|
|
89
86
|
}
|
|
90
87
|
|
|
91
88
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Renderer","href","Linking","openURL","children","styles","generateRandomString","text","onLinkPress","getViewNode","getCodeBlockNode","containerStyle","textStyle","getBlockquoteNode","getImageNode","uri","getListNode","ordered","li","listStyle","Decimal","Disc","map","
|
|
1
|
+
{"version":3,"names":["Renderer","href","Linking","openURL","children","styles","generateRandomString","text","onLinkPress","getViewNode","getCodeBlockNode","containerStyle","textStyle","getBlockquoteNode","getImageNode","uri","getListNode","ordered","li","listStyle","Decimal","Disc","map","node"],"sources":["Renderer.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Linking, ScrollView, View, Text } from 'react-native';\nimport MarkedList from '@jsamr/react-native-li';\nimport Disc from '@jsamr/counter-style/presets/disc';\nimport Decimal from '@jsamr/counter-style/presets/decimal';\nimport MDImage from './../components/MDImage';\nimport { generateRandomString } from '../utils/string';\nimport type { TextStyleProp, ViewStyleProp } from './types';\n\nclass Renderer {\n private onLinkPress = (href: string) => () => Linking.openURL(href);\n\n getTextNode = (\n children: string | React.ReactNode[],\n styles: TextStyleProp\n ) => {\n return (\n <Text key={generateRandomString()} style={styles}>\n {children}\n </Text>\n );\n };\n\n getLinkNode = (text: string, href: string, styles: TextStyleProp) => {\n return (\n <Text\n key={generateRandomString()}\n onPress={this.onLinkPress(href)}\n style={styles}\n >\n {text}\n </Text>\n );\n };\n\n getViewNode(children: React.ReactNode[] | null, styles: ViewStyleProp) {\n return (\n <View key={generateRandomString()} style={styles}>\n {children}\n </View>\n );\n }\n\n getCodeBlockNode(\n text: string,\n containerStyle: ViewStyleProp,\n textStyle: TextStyleProp\n ) {\n return (\n <ScrollView contentContainerStyle={containerStyle} horizontal>\n <Text style={textStyle}>{text}</Text>\n </ScrollView>\n );\n }\n\n getBlockquoteNode(children: React.ReactNode[], styles: ViewStyleProp) {\n return (\n <View key={generateRandomString()} style={styles}>\n {children}\n </View>\n );\n }\n\n getImageNode(uri: string) {\n return <MDImage key={generateRandomString()} uri={uri} />;\n }\n\n getListNode(\n ordered: boolean,\n li: React.ReactNode[],\n listStyle: ViewStyleProp,\n textStyle: TextStyleProp\n ) {\n return (\n <MarkedList\n counterRenderer={ordered ? Decimal : Disc}\n markerTextStyle={textStyle}\n markerBoxStyle={listStyle}\n >\n {li.map((node) => node)}\n </MarkedList>\n );\n }\n}\n\nexport default Renderer;\n"],"mappings":";;;;;;;AAAA;;AACA;;AACA;;AACA;;AACA;;AACA;;AACA;;;;;;;;;;AAGA,MAAMA,QAAN,CAAe;EAAA;IAAA,qCACUC,IAAD,IAAkB,MAAMC,oBAAA,CAAQC,OAAR,CAAgBF,IAAhB,CADjC;;IAAA,qCAGC,CACZG,QADY,EAEZC,MAFY,KAGT;MACH,oBACE,oBAAC,iBAAD;QAAM,GAAG,EAAE,IAAAC,4BAAA,GAAX;QAAmC,KAAK,EAAED;MAA1C,GACGD,QADH,CADF;IAKD,CAZY;;IAAA,qCAcC,CAACG,IAAD,EAAeN,IAAf,EAA6BI,MAA7B,KAAuD;MACnE,oBACE,oBAAC,iBAAD;QACE,GAAG,EAAE,IAAAC,4BAAA,GADP;QAEE,OAAO,EAAE,KAAKE,WAAL,CAAiBP,IAAjB,CAFX;QAGE,KAAK,EAAEI;MAHT,GAKGE,IALH,CADF;IASD,CAxBY;EAAA;;EA0BbE,WAAW,CAACL,QAAD,EAAqCC,MAArC,EAA4D;IACrE,oBACE,oBAAC,iBAAD;MAAM,GAAG,EAAE,IAAAC,4BAAA,GAAX;MAAmC,KAAK,EAAED;IAA1C,GACGD,QADH,CADF;EAKD;;EAEDM,gBAAgB,CACdH,IADc,EAEdI,cAFc,EAGdC,SAHc,EAId;IACA,oBACE,oBAAC,uBAAD;MAAY,qBAAqB,EAAED,cAAnC;MAAmD,UAAU;IAA7D,gBACE,oBAAC,iBAAD;MAAM,KAAK,EAAEC;IAAb,GAAyBL,IAAzB,CADF,CADF;EAKD;;EAEDM,iBAAiB,CAACT,QAAD,EAA8BC,MAA9B,EAAqD;IACpE,oBACE,oBAAC,iBAAD;MAAM,GAAG,EAAE,IAAAC,4BAAA,GAAX;MAAmC,KAAK,EAAED;IAA1C,GACGD,QADH,CADF;EAKD;;EAEDU,YAAY,CAACC,GAAD,EAAc;IACxB,oBAAO,oBAAC,gBAAD;MAAS,GAAG,EAAE,IAAAT,4BAAA,GAAd;MAAsC,GAAG,EAAES;IAA3C,EAAP;EACD;;EAEDC,WAAW,CACTC,OADS,EAETC,EAFS,EAGTC,SAHS,EAITP,SAJS,EAKT;IACA,oBACE,oBAAC,sBAAD;MACE,eAAe,EAAEK,OAAO,GAAGG,gBAAH,GAAaC,aADvC;MAEE,eAAe,EAAET,SAFnB;MAGE,cAAc,EAAEO;IAHlB,GAKGD,EAAE,CAACI,GAAH,CAAQC,IAAD,IAAUA,IAAjB,CALH,CADF;EASD;;AAzEY;;eA4EAvB,Q"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type {\n ImageStyle,\n TextStyle,\n ViewStyle,\n FlatListProps,\n} from 'react-native';\nimport type { MarkedStyles } from './../theme/types';\n\nexport type TextStyleProp = TextStyle | undefined;\nexport type ViewStyleProp = ViewStyle | undefined;\nexport type CustomStyleProp = ViewStyle | TextStyle | ImageStyle | undefined;\n\nexport interface ParserOptions {\n styles?: MarkedStyles;\n}\n\nexport interface MarkdownProps {\n value: string;\n flatListProps?: Omit<\n FlatListProps<ReactNode>,\n 'data' | 'renderItem' | 'horizontal'\n >;\n styles?: MarkedStyles;\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","memo","useCallback","useMemo","FlatList","useColorScheme","marked","Parser","getStyles","Markdown","value","flatListProps","styles","userStyles","systemTheme","rnElements","parser","tokens","lexer","trim","parse","renderItem","item","keyExtractor","_","index","toString","container"],"sources":["Markdown.tsx"],"sourcesContent":["import React, { memo, ReactNode, useCallback, useMemo } from 'react';\nimport { FlatList,
|
|
1
|
+
{"version":3,"names":["React","memo","useCallback","useMemo","FlatList","useColorScheme","marked","Parser","getStyles","Markdown","value","flatListProps","styles","userStyles","systemTheme","rnElements","parser","tokens","lexer","trim","parse","renderItem","item","keyExtractor","_","index","toString","container"],"sources":["Markdown.tsx"],"sourcesContent":["import React, { memo, ReactNode, useCallback, useMemo } from 'react';\nimport { FlatList, useColorScheme } from 'react-native';\nimport { marked } from 'marked';\nimport Parser from './Parser';\nimport getStyles from '../theme/styles';\nimport type { MarkdownProps } from './types';\n\nconst Markdown = ({\n value,\n flatListProps,\n styles: userStyles,\n}: MarkdownProps) => {\n const systemTheme = useColorScheme();\n const styles = useMemo(\n () => getStyles(userStyles, systemTheme),\n [userStyles, systemTheme]\n );\n\n const rnElements = useMemo(() => {\n const parser = new Parser({\n styles,\n });\n const tokens = marked.lexer(value.trim());\n\n return parser.parse(tokens);\n }, [value, styles]);\n\n const renderItem = useCallback(({ item }: { item: ReactNode }) => {\n return <>{item}</>;\n }, []);\n\n const keyExtractor = useCallback((_, index) => index.toString(), []);\n\n return (\n <FlatList\n keyExtractor={keyExtractor}\n maxToRenderPerBatch={8}\n initialNumToRender={8}\n removeClippedSubviews\n style={styles.container}\n {...flatListProps}\n data={rnElements}\n renderItem={renderItem}\n />\n );\n};\n\nexport default memo(Markdown);\n"],"mappings":";;AAAA,OAAOA,KAAP,IAAgBC,IAAhB,EAAiCC,WAAjC,EAA8CC,OAA9C,QAA6D,OAA7D;AACA,SAASC,QAAT,EAAmBC,cAAnB,QAAyC,cAAzC;AACA,SAASC,MAAT,QAAuB,QAAvB;AACA,OAAOC,MAAP,MAAmB,UAAnB;AACA,OAAOC,SAAP,MAAsB,iBAAtB;;AAGA,MAAMC,QAAQ,GAAG,QAII;EAAA,IAJH;IAChBC,KADgB;IAEhBC,aAFgB;IAGhBC,MAAM,EAAEC;EAHQ,CAIG;EACnB,MAAMC,WAAW,GAAGT,cAAc,EAAlC;EACA,MAAMO,MAAM,GAAGT,OAAO,CACpB,MAAMK,SAAS,CAACK,UAAD,EAAaC,WAAb,CADK,EAEpB,CAACD,UAAD,EAAaC,WAAb,CAFoB,CAAtB;EAKA,MAAMC,UAAU,GAAGZ,OAAO,CAAC,MAAM;IAC/B,MAAMa,MAAM,GAAG,IAAIT,MAAJ,CAAW;MACxBK;IADwB,CAAX,CAAf;IAGA,MAAMK,MAAM,GAAGX,MAAM,CAACY,KAAP,CAAaR,KAAK,CAACS,IAAN,EAAb,CAAf;IAEA,OAAOH,MAAM,CAACI,KAAP,CAAaH,MAAb,CAAP;EACD,CAPyB,EAOvB,CAACP,KAAD,EAAQE,MAAR,CAPuB,CAA1B;EASA,MAAMS,UAAU,GAAGnB,WAAW,CAAC,SAAmC;IAAA,IAAlC;MAAEoB;IAAF,CAAkC;IAChE,oBAAO,0CAAGA,IAAH,CAAP;EACD,CAF6B,EAE3B,EAF2B,CAA9B;EAIA,MAAMC,YAAY,GAAGrB,WAAW,CAAC,CAACsB,CAAD,EAAIC,KAAJ,KAAcA,KAAK,CAACC,QAAN,EAAf,EAAiC,EAAjC,CAAhC;EAEA,oBACE,oBAAC,QAAD;IACE,YAAY,EAAEH,YADhB;IAEE,mBAAmB,EAAE,CAFvB;IAGE,kBAAkB,EAAE,CAHtB;IAIE,qBAAqB,MAJvB;IAKE,KAAK,EAAEX,MAAM,CAACe;EALhB,GAMMhB,aANN;IAOE,IAAI,EAAEI,UAPR;IAQE,UAAU,EAAEM;EARd,GADF;AAYD,CAtCD;;AAwCA,4BAAepB,IAAI,CAACQ,QAAD,CAAnB"}
|
|
@@ -36,6 +36,7 @@ class Parser {
|
|
|
36
36
|
let tempTokens = [];
|
|
37
37
|
const paragraphChildren = [];
|
|
38
38
|
token.tokens.forEach(t => {
|
|
39
|
+
/* To avoid inlining of image */
|
|
39
40
|
if (t.type === 'image') {
|
|
40
41
|
paragraphChildren.push(this.renderer.getTextNode(this.parseInline(tempTokens), this.styles.text));
|
|
41
42
|
paragraphChildren.push(this.parseInline([t]));
|
|
@@ -76,10 +77,27 @@ class Parser {
|
|
|
76
77
|
|
|
77
78
|
case 'list':
|
|
78
79
|
{
|
|
79
|
-
const li = token.items.map(item =>
|
|
80
|
+
const li = token.items.map(item => {
|
|
81
|
+
var _item$tokens$, _item$tokens$2;
|
|
82
|
+
|
|
83
|
+
if (item.tokens.length > 0 && ((_item$tokens$ = item.tokens[0]) === null || _item$tokens$ === void 0 ? void 0 : _item$tokens$.type) === 'text' && // @ts-ignore
|
|
84
|
+
Array.isArray((_item$tokens$2 = item.tokens[0]) === null || _item$tokens$2 === void 0 ? void 0 : _item$tokens$2.tokens)) {
|
|
85
|
+
var _item$tokens$3;
|
|
86
|
+
|
|
87
|
+
return this.renderer.getTextNode( // @ts-ignore
|
|
88
|
+
this.parseInline((_item$tokens$3 = item.tokens[0]) === null || _item$tokens$3 === void 0 ? void 0 : _item$tokens$3.tokens), this.styles.li);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return this.renderer.getTextNode(item.text, this.styles.li);
|
|
92
|
+
});
|
|
80
93
|
return this.renderer.getListNode(token.ordered, li, this.styles.list, this.styles.li);
|
|
81
94
|
}
|
|
82
95
|
|
|
96
|
+
case 'html':
|
|
97
|
+
{
|
|
98
|
+
return this.renderer.getTextNode(token.text.trim(), this.styles.text);
|
|
99
|
+
}
|
|
100
|
+
|
|
83
101
|
default:
|
|
84
102
|
console.warn(`Token with '${token.type}' type was not found.`);
|
|
85
103
|
return null;
|
|
@@ -88,26 +106,23 @@ class Parser {
|
|
|
88
106
|
return elements;
|
|
89
107
|
}
|
|
90
108
|
|
|
91
|
-
parseInline(tokens) {
|
|
92
|
-
let styles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
109
|
+
parseInline(tokens, styles) {
|
|
93
110
|
const elements = tokens.map(token => {
|
|
94
111
|
if (!token) return null;
|
|
95
112
|
|
|
96
113
|
switch (token.type) {
|
|
97
114
|
case 'escape':
|
|
98
115
|
{
|
|
99
|
-
return this.renderer.getTextNode(token.text,
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
case 'html':
|
|
103
|
-
{
|
|
104
|
-
console.log('html', token);
|
|
105
|
-
return null;
|
|
116
|
+
return this.renderer.getTextNode(token.text, { ...styles,
|
|
117
|
+
...this.styles.text
|
|
118
|
+
});
|
|
106
119
|
}
|
|
107
120
|
|
|
108
121
|
case 'link':
|
|
109
122
|
{
|
|
110
|
-
return this.renderer.getLinkNode(token.text, token.href,
|
|
123
|
+
return this.renderer.getLinkNode(token.text, token.href, { ...styles,
|
|
124
|
+
...this.styles.link
|
|
125
|
+
});
|
|
111
126
|
}
|
|
112
127
|
|
|
113
128
|
case 'image':
|
|
@@ -117,12 +132,16 @@ class Parser {
|
|
|
117
132
|
|
|
118
133
|
case 'strong':
|
|
119
134
|
{
|
|
120
|
-
return this.renderer.getTextNode(this.parseInline(token.tokens, this.styles.strong),
|
|
135
|
+
return this.renderer.getTextNode(this.parseInline(token.tokens, this.styles.strong), { ...styles,
|
|
136
|
+
...this.styles.strong
|
|
137
|
+
});
|
|
121
138
|
}
|
|
122
139
|
|
|
123
140
|
case 'em':
|
|
124
141
|
{
|
|
125
|
-
return this.renderer.getTextNode(this.parseInline(token.tokens, this.styles.em),
|
|
142
|
+
return this.renderer.getTextNode(this.parseInline(token.tokens, this.styles.em), { ...styles,
|
|
143
|
+
...this.styles.em
|
|
144
|
+
});
|
|
126
145
|
}
|
|
127
146
|
|
|
128
147
|
case 'codespan':
|
|
@@ -142,7 +161,9 @@ class Parser {
|
|
|
142
161
|
|
|
143
162
|
case 'text':
|
|
144
163
|
{
|
|
145
|
-
return this.renderer.getTextNode(token.raw,
|
|
164
|
+
return this.renderer.getTextNode(token.raw, { ...styles,
|
|
165
|
+
...this.styles.text
|
|
166
|
+
});
|
|
146
167
|
}
|
|
147
168
|
|
|
148
169
|
default:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Renderer","Parser","constructor","options","styles","renderer","headingStylesMap","h1","h2","h3","h4","h5","h6","parse","tokens","elements","map","token","type","tempTokens","paragraphChildren","forEach","t","push","getTextNode","parseInline","text","length","getViewNode","paragraph","getBlockquoteNode","blockquote","depth","getCodeBlockNode","code","em","hr","li","items","item","getListNode","ordered","list","console","warn","log","getLinkNode","href","link","getImageNode","strong","codespan","raw"],"sources":["Parser.tsx"],"sourcesContent":["import type { marked } from 'marked';\nimport type { ImageStyle, StyleProp, TextStyle, ViewStyle } from 'react-native';\nimport Renderer from './Renderer';\nimport type { MarkedStyles } from '../theme/types';\n\ninterface ParserOptions {\n styles?: MarkedStyles;\n}\n\nclass Parser {\n private renderer;\n private styles: MarkedStyles;\n private headingStylesMap: Record<number, TextStyle | undefined>;\n constructor(options: ParserOptions) {\n this.styles = { ...options.styles };\n this.renderer = new Renderer();\n this.headingStylesMap = {\n 1: this.styles.h1,\n 2: this.styles.h2,\n 3: this.styles.h3,\n 4: this.styles.h4,\n 5: this.styles.h5,\n 6: this.styles.h6,\n };\n }\n\n parse(tokens: marked.Token[]) {\n const elements: React.ReactNode[] = tokens.map((token) => {\n switch (token.type) {\n case 'space': {\n return null;\n }\n case 'paragraph': {\n let tempTokens: marked.Token[] = [];\n const paragraphChildren: React.ReactNode[] = [];\n token.tokens.forEach((t) => {\n if (t.type === 'image') {\n paragraphChildren.push(\n this.renderer.getTextNode(\n this.parseInline(tempTokens),\n this.styles.text\n )\n );\n paragraphChildren.push(this.parseInline([t]));\n tempTokens = [];\n return;\n }\n tempTokens = [...tempTokens, t];\n });\n\n if (tempTokens.length > 0) {\n paragraphChildren.push(\n this.renderer.getTextNode(this.parseInline(tempTokens), {})\n );\n }\n\n return this.renderer.getViewNode(\n paragraphChildren,\n this.styles.paragraph\n );\n }\n case 'blockquote': {\n return this.renderer.getBlockquoteNode(\n this.parse(token.tokens),\n this.styles.blockquote\n );\n }\n case 'heading': {\n const styles = this.headingStylesMap[token.depth] ?? this.styles.text;\n return this.renderer.getTextNode(token.text, styles);\n }\n case 'code': {\n return this.renderer.getCodeBlockNode(\n token.text,\n this.styles.code,\n this.styles.em\n );\n }\n case 'hr': {\n return this.renderer.getViewNode(null, this.styles.hr);\n }\n case 'list': {\n const li = token.items.map((item) => item.text);\n return this.renderer.getListNode(\n token.ordered,\n li,\n this.styles.list,\n this.styles.li\n );\n }\n default:\n console.warn(`Token with '${token.type}' type was not found.`);\n return null;\n }\n });\n return elements;\n }\n\n parseInline(\n tokens: marked.Token[],\n styles: StyleProp<ViewStyle | TextStyle | ImageStyle> = {}\n ) {\n const elements: React.ReactNode[] = tokens.map((token) => {\n if (!token) return null;\n\n switch (token.type) {\n case 'escape': {\n return this.renderer.getTextNode(token.text, [\n styles,\n this.styles.text,\n ]);\n }\n case 'html': {\n console.log('html', token);\n return null;\n }\n case 'link': {\n return this.renderer.getLinkNode(token.text, token.href, [\n styles,\n this.styles.link,\n ]);\n }\n case 'image': {\n return this.renderer.getImageNode(token.href);\n }\n case 'strong': {\n return this.renderer.getTextNode(\n this.parseInline(token.tokens, this.styles.strong),\n [styles, this.styles.strong]\n );\n }\n case 'em': {\n return this.renderer.getTextNode(\n this.parseInline(token.tokens, this.styles.em),\n [styles, this.styles.em]\n );\n }\n case 'codespan': {\n return this.renderer.getTextNode(token.text, this.styles.codespan);\n }\n case 'br': {\n return this.renderer.getTextNode('\\n', {});\n }\n case 'del': {\n return null;\n }\n case 'text': {\n return this.renderer.getTextNode(token.raw, [\n styles,\n this.styles.text,\n ]);\n }\n default: {\n console.warn(`Token with '${token.type}' type was not found.`);\n return null;\n }\n }\n });\n return elements;\n }\n}\n\nexport default Parser;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["Renderer","Parser","constructor","options","styles","renderer","headingStylesMap","h1","h2","h3","h4","h5","h6","parse","tokens","elements","map","token","type","tempTokens","paragraphChildren","forEach","t","push","getTextNode","parseInline","text","length","getViewNode","paragraph","getBlockquoteNode","blockquote","depth","getCodeBlockNode","code","em","hr","li","items","item","Array","isArray","getListNode","ordered","list","trim","console","warn","getLinkNode","href","link","getImageNode","strong","codespan","raw"],"sources":["Parser.tsx"],"sourcesContent":["import type { marked } from 'marked';\nimport Renderer from './Renderer';\nimport type { MarkedStyles } from '../theme/types';\nimport type { CustomStyleProp, ParserOptions, TextStyleProp } from './types';\n\nclass Parser {\n private renderer;\n private styles: MarkedStyles;\n private headingStylesMap: Record<number, TextStyleProp>;\n constructor(options: ParserOptions) {\n this.styles = { ...options.styles };\n this.renderer = new Renderer();\n this.headingStylesMap = {\n 1: this.styles.h1,\n 2: this.styles.h2,\n 3: this.styles.h3,\n 4: this.styles.h4,\n 5: this.styles.h5,\n 6: this.styles.h6,\n };\n }\n\n parse(tokens: marked.Token[]) {\n const elements: React.ReactNode[] = tokens.map((token) => {\n switch (token.type) {\n case 'space': {\n return null;\n }\n case 'paragraph': {\n let tempTokens: marked.Token[] = [];\n const paragraphChildren: React.ReactNode[] = [];\n token.tokens.forEach((t) => {\n /* To avoid inlining of image */\n if (t.type === 'image') {\n paragraphChildren.push(\n this.renderer.getTextNode(\n this.parseInline(tempTokens),\n this.styles.text\n )\n );\n paragraphChildren.push(this.parseInline([t]));\n tempTokens = [];\n return;\n }\n tempTokens = [...tempTokens, t];\n });\n\n if (tempTokens.length > 0) {\n paragraphChildren.push(\n this.renderer.getTextNode(this.parseInline(tempTokens), {})\n );\n }\n\n return this.renderer.getViewNode(\n paragraphChildren,\n this.styles.paragraph\n );\n }\n case 'blockquote': {\n return this.renderer.getBlockquoteNode(\n this.parse(token.tokens),\n this.styles.blockquote\n );\n }\n case 'heading': {\n const styles = this.headingStylesMap[token.depth] ?? this.styles.text;\n return this.renderer.getTextNode(token.text, styles);\n }\n case 'code': {\n return this.renderer.getCodeBlockNode(\n token.text,\n this.styles.code,\n this.styles.em\n );\n }\n case 'hr': {\n return this.renderer.getViewNode(null, this.styles.hr);\n }\n case 'list': {\n const li = token.items.map((item) => {\n if (\n item.tokens.length > 0 &&\n item.tokens[0]?.type === 'text' &&\n // @ts-ignore\n Array.isArray(item.tokens[0]?.tokens)\n ) {\n return this.renderer.getTextNode(\n // @ts-ignore\n this.parseInline(item.tokens[0]?.tokens),\n this.styles.li\n );\n }\n return this.renderer.getTextNode(item.text, this.styles.li);\n });\n return this.renderer.getListNode(\n token.ordered,\n li,\n this.styles.list,\n this.styles.li\n );\n }\n case 'html': {\n return this.renderer.getTextNode(token.text.trim(), this.styles.text);\n }\n default:\n console.warn(`Token with '${token.type}' type was not found.`);\n return null;\n }\n });\n return elements;\n }\n\n parseInline(tokens: marked.Token[], styles?: CustomStyleProp) {\n const elements: React.ReactNode[] = tokens.map((token) => {\n if (!token) return null;\n\n switch (token.type) {\n case 'escape': {\n return this.renderer.getTextNode(token.text, {\n ...styles,\n ...this.styles.text,\n });\n }\n case 'link': {\n return this.renderer.getLinkNode(token.text, token.href, {\n ...styles,\n ...this.styles.link,\n });\n }\n case 'image': {\n return this.renderer.getImageNode(token.href);\n }\n case 'strong': {\n return this.renderer.getTextNode(\n this.parseInline(token.tokens, this.styles.strong),\n { ...styles, ...this.styles.strong }\n );\n }\n case 'em': {\n return this.renderer.getTextNode(\n this.parseInline(token.tokens, this.styles.em),\n { ...styles, ...this.styles.em }\n );\n }\n case 'codespan': {\n return this.renderer.getTextNode(token.text, this.styles.codespan);\n }\n case 'br': {\n return this.renderer.getTextNode('\\n', {});\n }\n case 'del': {\n return null;\n }\n case 'text': {\n return this.renderer.getTextNode(token.raw, {\n ...styles,\n ...this.styles.text,\n });\n }\n default: {\n console.warn(`Token with '${token.type}' type was not found.`);\n return null;\n }\n }\n });\n return elements;\n }\n}\n\nexport default Parser;\n"],"mappings":"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"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
2
2
|
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { Linking, ScrollView, View } from 'react-native';
|
|
5
|
-
import { Text } from 'react-native';
|
|
4
|
+
import { Linking, ScrollView, View, Text } from 'react-native';
|
|
6
5
|
import MarkedList from '@jsamr/react-native-li';
|
|
7
6
|
import Disc from '@jsamr/counter-style/presets/disc';
|
|
8
7
|
import Decimal from '@jsamr/counter-style/presets/decimal';
|
|
@@ -64,10 +63,7 @@ class Renderer {
|
|
|
64
63
|
counterRenderer: ordered ? Decimal : Disc,
|
|
65
64
|
markerTextStyle: textStyle,
|
|
66
65
|
markerBoxStyle: listStyle
|
|
67
|
-
}, li.map(
|
|
68
|
-
key: index,
|
|
69
|
-
style: textStyle
|
|
70
|
-
}, text)));
|
|
66
|
+
}, li.map(node => node));
|
|
71
67
|
}
|
|
72
68
|
|
|
73
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","Linking","ScrollView","View","Text","MarkedList","Disc","Decimal","MDImage","generateRandomString","Renderer","href","openURL","children","styles","text","onLinkPress","getViewNode","getCodeBlockNode","containerStyle","textStyle","getBlockquoteNode","getImageNode","uri","getListNode","ordered","li","listStyle","map","
|
|
1
|
+
{"version":3,"names":["React","Linking","ScrollView","View","Text","MarkedList","Disc","Decimal","MDImage","generateRandomString","Renderer","href","openURL","children","styles","text","onLinkPress","getViewNode","getCodeBlockNode","containerStyle","textStyle","getBlockquoteNode","getImageNode","uri","getListNode","ordered","li","listStyle","map","node"],"sources":["Renderer.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Linking, ScrollView, View, Text } from 'react-native';\nimport MarkedList from '@jsamr/react-native-li';\nimport Disc from '@jsamr/counter-style/presets/disc';\nimport Decimal from '@jsamr/counter-style/presets/decimal';\nimport MDImage from './../components/MDImage';\nimport { generateRandomString } from '../utils/string';\nimport type { TextStyleProp, ViewStyleProp } from './types';\n\nclass Renderer {\n private onLinkPress = (href: string) => () => Linking.openURL(href);\n\n getTextNode = (\n children: string | React.ReactNode[],\n styles: TextStyleProp\n ) => {\n return (\n <Text key={generateRandomString()} style={styles}>\n {children}\n </Text>\n );\n };\n\n getLinkNode = (text: string, href: string, styles: TextStyleProp) => {\n return (\n <Text\n key={generateRandomString()}\n onPress={this.onLinkPress(href)}\n style={styles}\n >\n {text}\n </Text>\n );\n };\n\n getViewNode(children: React.ReactNode[] | null, styles: ViewStyleProp) {\n return (\n <View key={generateRandomString()} style={styles}>\n {children}\n </View>\n );\n }\n\n getCodeBlockNode(\n text: string,\n containerStyle: ViewStyleProp,\n textStyle: TextStyleProp\n ) {\n return (\n <ScrollView contentContainerStyle={containerStyle} horizontal>\n <Text style={textStyle}>{text}</Text>\n </ScrollView>\n );\n }\n\n getBlockquoteNode(children: React.ReactNode[], styles: ViewStyleProp) {\n return (\n <View key={generateRandomString()} style={styles}>\n {children}\n </View>\n );\n }\n\n getImageNode(uri: string) {\n return <MDImage key={generateRandomString()} uri={uri} />;\n }\n\n getListNode(\n ordered: boolean,\n li: React.ReactNode[],\n listStyle: ViewStyleProp,\n textStyle: TextStyleProp\n ) {\n return (\n <MarkedList\n counterRenderer={ordered ? Decimal : Disc}\n markerTextStyle={textStyle}\n markerBoxStyle={listStyle}\n >\n {li.map((node) => node)}\n </MarkedList>\n );\n }\n}\n\nexport default Renderer;\n"],"mappings":";;AAAA,OAAO,KAAKA,KAAZ,MAAuB,OAAvB;AACA,SAASC,OAAT,EAAkBC,UAAlB,EAA8BC,IAA9B,EAAoCC,IAApC,QAAgD,cAAhD;AACA,OAAOC,UAAP,MAAuB,wBAAvB;AACA,OAAOC,IAAP,MAAiB,mCAAjB;AACA,OAAOC,OAAP,MAAoB,sCAApB;AACA,OAAOC,OAAP,MAAoB,yBAApB;AACA,SAASC,oBAAT,QAAqC,iBAArC;;AAGA,MAAMC,QAAN,CAAe;EAAA;IAAA,qCACUC,IAAD,IAAkB,MAAMV,OAAO,CAACW,OAAR,CAAgBD,IAAhB,CADjC;;IAAA,qCAGC,CACZE,QADY,EAEZC,MAFY,KAGT;MACH,oBACE,oBAAC,IAAD;QAAM,GAAG,EAAEL,oBAAoB,EAA/B;QAAmC,KAAK,EAAEK;MAA1C,GACGD,QADH,CADF;IAKD,CAZY;;IAAA,qCAcC,CAACE,IAAD,EAAeJ,IAAf,EAA6BG,MAA7B,KAAuD;MACnE,oBACE,oBAAC,IAAD;QACE,GAAG,EAAEL,oBAAoB,EAD3B;QAEE,OAAO,EAAE,KAAKO,WAAL,CAAiBL,IAAjB,CAFX;QAGE,KAAK,EAAEG;MAHT,GAKGC,IALH,CADF;IASD,CAxBY;EAAA;;EA0BbE,WAAW,CAACJ,QAAD,EAAqCC,MAArC,EAA4D;IACrE,oBACE,oBAAC,IAAD;MAAM,GAAG,EAAEL,oBAAoB,EAA/B;MAAmC,KAAK,EAAEK;IAA1C,GACGD,QADH,CADF;EAKD;;EAEDK,gBAAgB,CACdH,IADc,EAEdI,cAFc,EAGdC,SAHc,EAId;IACA,oBACE,oBAAC,UAAD;MAAY,qBAAqB,EAAED,cAAnC;MAAmD,UAAU;IAA7D,gBACE,oBAAC,IAAD;MAAM,KAAK,EAAEC;IAAb,GAAyBL,IAAzB,CADF,CADF;EAKD;;EAEDM,iBAAiB,CAACR,QAAD,EAA8BC,MAA9B,EAAqD;IACpE,oBACE,oBAAC,IAAD;MAAM,GAAG,EAAEL,oBAAoB,EAA/B;MAAmC,KAAK,EAAEK;IAA1C,GACGD,QADH,CADF;EAKD;;EAEDS,YAAY,CAACC,GAAD,EAAc;IACxB,oBAAO,oBAAC,OAAD;MAAS,GAAG,EAAEd,oBAAoB,EAAlC;MAAsC,GAAG,EAAEc;IAA3C,EAAP;EACD;;EAEDC,WAAW,CACTC,OADS,EAETC,EAFS,EAGTC,SAHS,EAITP,SAJS,EAKT;IACA,oBACE,oBAAC,UAAD;MACE,eAAe,EAAEK,OAAO,GAAGlB,OAAH,GAAaD,IADvC;MAEE,eAAe,EAAEc,SAFnB;MAGE,cAAc,EAAEO;IAHlB,GAKGD,EAAE,CAACE,GAAH,CAAQC,IAAD,IAAUA,IAAjB,CALH,CADF;EASD;;AAzEY;;AA4Ef,eAAenB,QAAf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type { ReactNode } from 'react';\nimport type {\n ImageStyle,\n TextStyle,\n ViewStyle,\n FlatListProps,\n} from 'react-native';\nimport type { MarkedStyles } from './../theme/types';\n\nexport type TextStyleProp = TextStyle | undefined;\nexport type ViewStyleProp = ViewStyle | undefined;\nexport type CustomStyleProp = ViewStyle | TextStyle | ImageStyle | undefined;\n\nexport interface ParserOptions {\n styles?: MarkedStyles;\n}\n\nexport interface MarkdownProps {\n value: string;\n flatListProps?: Omit<\n FlatListProps<ReactNode>,\n 'data' | 'renderItem' | 'horizontal'\n >;\n styles?: MarkedStyles;\n}\n"],"mappings":""}
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import {
|
|
3
|
-
import type { MarkedStyles } from '../theme/types';
|
|
4
|
-
interface MarkdownProps {
|
|
5
|
-
value: string;
|
|
6
|
-
flatListProps?: Omit<FlatListProps<ReactNode>, 'data' | 'renderItem' | 'horizontal'>;
|
|
7
|
-
styles?: MarkedStyles;
|
|
8
|
-
}
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { MarkdownProps } from './types';
|
|
9
3
|
declare const _default: React.MemoExoticComponent<({ value, flatListProps, styles: userStyles, }: MarkdownProps) => JSX.Element>;
|
|
10
4
|
export default _default;
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { marked } from 'marked';
|
|
3
|
-
import type {
|
|
4
|
-
import type { MarkedStyles } from '../theme/types';
|
|
5
|
-
interface ParserOptions {
|
|
6
|
-
styles?: MarkedStyles;
|
|
7
|
-
}
|
|
3
|
+
import type { CustomStyleProp, ParserOptions } from './types';
|
|
8
4
|
declare class Parser {
|
|
9
5
|
private renderer;
|
|
10
6
|
private styles;
|
|
11
7
|
private headingStylesMap;
|
|
12
8
|
constructor(options: ParserOptions);
|
|
13
9
|
parse(tokens: marked.Token[]): import("react").ReactNode[];
|
|
14
|
-
parseInline(tokens: marked.Token[], styles?:
|
|
10
|
+
parseInline(tokens: marked.Token[], styles?: CustomStyleProp): import("react").ReactNode[];
|
|
15
11
|
}
|
|
16
12
|
export default Parser;
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { StyleProp, TextStyle } from 'react-native';
|
|
2
|
+
import type { TextStyleProp, ViewStyleProp } from './types';
|
|
4
3
|
declare class Renderer {
|
|
5
4
|
private onLinkPress;
|
|
6
|
-
getTextNode: (children: string | React.ReactNode[], styles:
|
|
7
|
-
getLinkNode: (text: string, href: string, styles:
|
|
8
|
-
getViewNode(children: React.ReactNode[] | null, styles:
|
|
9
|
-
getCodeBlockNode(text: string, containerStyle:
|
|
10
|
-
getBlockquoteNode(children: React.ReactNode[], styles:
|
|
5
|
+
getTextNode: (children: string | React.ReactNode[], styles: TextStyleProp) => JSX.Element;
|
|
6
|
+
getLinkNode: (text: string, href: string, styles: TextStyleProp) => JSX.Element;
|
|
7
|
+
getViewNode(children: React.ReactNode[] | null, styles: ViewStyleProp): JSX.Element;
|
|
8
|
+
getCodeBlockNode(text: string, containerStyle: ViewStyleProp, textStyle: TextStyleProp): JSX.Element;
|
|
9
|
+
getBlockquoteNode(children: React.ReactNode[], styles: ViewStyleProp): JSX.Element;
|
|
11
10
|
getImageNode(uri: string): JSX.Element;
|
|
12
|
-
getListNode(ordered: boolean, li:
|
|
11
|
+
getListNode(ordered: boolean, li: React.ReactNode[], listStyle: ViewStyleProp, textStyle: TextStyleProp): JSX.Element;
|
|
13
12
|
}
|
|
14
13
|
export default Renderer;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { ImageStyle, TextStyle, ViewStyle, FlatListProps } from 'react-native';
|
|
3
|
+
import type { MarkedStyles } from './../theme/types';
|
|
4
|
+
export declare type TextStyleProp = TextStyle | undefined;
|
|
5
|
+
export declare type ViewStyleProp = ViewStyle | undefined;
|
|
6
|
+
export declare type CustomStyleProp = ViewStyle | TextStyle | ImageStyle | undefined;
|
|
7
|
+
export interface ParserOptions {
|
|
8
|
+
styles?: MarkedStyles;
|
|
9
|
+
}
|
|
10
|
+
export interface MarkdownProps {
|
|
11
|
+
value: string;
|
|
12
|
+
flatListProps?: Omit<FlatListProps<ReactNode>, 'data' | 'renderItem' | 'horizontal'>;
|
|
13
|
+
styles?: MarkedStyles;
|
|
14
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-marked",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Markdown renderer for React Native powered by marked.js",
|
|
5
5
|
"main": "dist/commonjs/index",
|
|
6
6
|
"module": "dist/module/index",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"typescript": "tsc --noEmit",
|
|
27
27
|
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
28
28
|
"build": "bob build",
|
|
29
|
-
"prepare": "
|
|
30
|
-
"release": "release-it"
|
|
29
|
+
"prepare": "yarn build",
|
|
30
|
+
"release": "yarn build && release-it"
|
|
31
31
|
},
|
|
32
32
|
"keywords": [
|
|
33
33
|
"react-native",
|
|
@@ -146,7 +146,8 @@
|
|
|
146
146
|
"trailingComma": "es5",
|
|
147
147
|
"useTabs": false
|
|
148
148
|
}
|
|
149
|
-
]
|
|
149
|
+
],
|
|
150
|
+
"@typescript-eslint/ban-ts-comment": "off"
|
|
150
151
|
}
|
|
151
152
|
},
|
|
152
153
|
"eslintIgnore": [
|
package/src/lib/Markdown.tsx
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
import React, { memo, ReactNode, useCallback, useMemo } from 'react';
|
|
2
|
-
import { FlatList,
|
|
2
|
+
import { FlatList, useColorScheme } from 'react-native';
|
|
3
3
|
import { marked } from 'marked';
|
|
4
4
|
import Parser from './Parser';
|
|
5
5
|
import getStyles from '../theme/styles';
|
|
6
|
-
import type {
|
|
7
|
-
|
|
8
|
-
interface MarkdownProps {
|
|
9
|
-
value: string;
|
|
10
|
-
flatListProps?: Omit<
|
|
11
|
-
FlatListProps<ReactNode>,
|
|
12
|
-
'data' | 'renderItem' | 'horizontal'
|
|
13
|
-
>;
|
|
14
|
-
styles?: MarkedStyles;
|
|
15
|
-
}
|
|
6
|
+
import type { MarkdownProps } from './types';
|
|
16
7
|
|
|
17
8
|
const Markdown = ({
|
|
18
9
|
value,
|
package/src/lib/Parser.tsx
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import type { marked } from 'marked';
|
|
2
|
-
import type { ImageStyle, StyleProp, TextStyle, ViewStyle } from 'react-native';
|
|
3
2
|
import Renderer from './Renderer';
|
|
4
3
|
import type { MarkedStyles } from '../theme/types';
|
|
5
|
-
|
|
6
|
-
interface ParserOptions {
|
|
7
|
-
styles?: MarkedStyles;
|
|
8
|
-
}
|
|
4
|
+
import type { CustomStyleProp, ParserOptions, TextStyleProp } from './types';
|
|
9
5
|
|
|
10
6
|
class Parser {
|
|
11
7
|
private renderer;
|
|
12
8
|
private styles: MarkedStyles;
|
|
13
|
-
private headingStylesMap: Record<number,
|
|
9
|
+
private headingStylesMap: Record<number, TextStyleProp>;
|
|
14
10
|
constructor(options: ParserOptions) {
|
|
15
11
|
this.styles = { ...options.styles };
|
|
16
12
|
this.renderer = new Renderer();
|
|
@@ -34,6 +30,7 @@ class Parser {
|
|
|
34
30
|
let tempTokens: marked.Token[] = [];
|
|
35
31
|
const paragraphChildren: React.ReactNode[] = [];
|
|
36
32
|
token.tokens.forEach((t) => {
|
|
33
|
+
/* To avoid inlining of image */
|
|
37
34
|
if (t.type === 'image') {
|
|
38
35
|
paragraphChildren.push(
|
|
39
36
|
this.renderer.getTextNode(
|
|
@@ -80,7 +77,21 @@ class Parser {
|
|
|
80
77
|
return this.renderer.getViewNode(null, this.styles.hr);
|
|
81
78
|
}
|
|
82
79
|
case 'list': {
|
|
83
|
-
const li = token.items.map((item) =>
|
|
80
|
+
const li = token.items.map((item) => {
|
|
81
|
+
if (
|
|
82
|
+
item.tokens.length > 0 &&
|
|
83
|
+
item.tokens[0]?.type === 'text' &&
|
|
84
|
+
// @ts-ignore
|
|
85
|
+
Array.isArray(item.tokens[0]?.tokens)
|
|
86
|
+
) {
|
|
87
|
+
return this.renderer.getTextNode(
|
|
88
|
+
// @ts-ignore
|
|
89
|
+
this.parseInline(item.tokens[0]?.tokens),
|
|
90
|
+
this.styles.li
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
return this.renderer.getTextNode(item.text, this.styles.li);
|
|
94
|
+
});
|
|
84
95
|
return this.renderer.getListNode(
|
|
85
96
|
token.ordered,
|
|
86
97
|
li,
|
|
@@ -88,6 +99,9 @@ class Parser {
|
|
|
88
99
|
this.styles.li
|
|
89
100
|
);
|
|
90
101
|
}
|
|
102
|
+
case 'html': {
|
|
103
|
+
return this.renderer.getTextNode(token.text.trim(), this.styles.text);
|
|
104
|
+
}
|
|
91
105
|
default:
|
|
92
106
|
console.warn(`Token with '${token.type}' type was not found.`);
|
|
93
107
|
return null;
|
|
@@ -96,29 +110,22 @@ class Parser {
|
|
|
96
110
|
return elements;
|
|
97
111
|
}
|
|
98
112
|
|
|
99
|
-
parseInline(
|
|
100
|
-
tokens: marked.Token[],
|
|
101
|
-
styles: StyleProp<ViewStyle | TextStyle | ImageStyle> = {}
|
|
102
|
-
) {
|
|
113
|
+
parseInline(tokens: marked.Token[], styles?: CustomStyleProp) {
|
|
103
114
|
const elements: React.ReactNode[] = tokens.map((token) => {
|
|
104
115
|
if (!token) return null;
|
|
105
116
|
|
|
106
117
|
switch (token.type) {
|
|
107
118
|
case 'escape': {
|
|
108
|
-
return this.renderer.getTextNode(token.text,
|
|
109
|
-
styles,
|
|
110
|
-
this.styles.text,
|
|
111
|
-
|
|
112
|
-
}
|
|
113
|
-
case 'html': {
|
|
114
|
-
console.log('html', token);
|
|
115
|
-
return null;
|
|
119
|
+
return this.renderer.getTextNode(token.text, {
|
|
120
|
+
...styles,
|
|
121
|
+
...this.styles.text,
|
|
122
|
+
});
|
|
116
123
|
}
|
|
117
124
|
case 'link': {
|
|
118
|
-
return this.renderer.getLinkNode(token.text, token.href,
|
|
119
|
-
styles,
|
|
120
|
-
this.styles.link,
|
|
121
|
-
|
|
125
|
+
return this.renderer.getLinkNode(token.text, token.href, {
|
|
126
|
+
...styles,
|
|
127
|
+
...this.styles.link,
|
|
128
|
+
});
|
|
122
129
|
}
|
|
123
130
|
case 'image': {
|
|
124
131
|
return this.renderer.getImageNode(token.href);
|
|
@@ -126,13 +133,13 @@ class Parser {
|
|
|
126
133
|
case 'strong': {
|
|
127
134
|
return this.renderer.getTextNode(
|
|
128
135
|
this.parseInline(token.tokens, this.styles.strong),
|
|
129
|
-
|
|
136
|
+
{ ...styles, ...this.styles.strong }
|
|
130
137
|
);
|
|
131
138
|
}
|
|
132
139
|
case 'em': {
|
|
133
140
|
return this.renderer.getTextNode(
|
|
134
141
|
this.parseInline(token.tokens, this.styles.em),
|
|
135
|
-
|
|
142
|
+
{ ...styles, ...this.styles.em }
|
|
136
143
|
);
|
|
137
144
|
}
|
|
138
145
|
case 'codespan': {
|
|
@@ -145,10 +152,10 @@ class Parser {
|
|
|
145
152
|
return null;
|
|
146
153
|
}
|
|
147
154
|
case 'text': {
|
|
148
|
-
return this.renderer.getTextNode(token.raw,
|
|
149
|
-
styles,
|
|
150
|
-
this.styles.text,
|
|
151
|
-
|
|
155
|
+
return this.renderer.getTextNode(token.raw, {
|
|
156
|
+
...styles,
|
|
157
|
+
...this.styles.text,
|
|
158
|
+
});
|
|
152
159
|
}
|
|
153
160
|
default: {
|
|
154
161
|
console.warn(`Token with '${token.type}' type was not found.`);
|
package/src/lib/Renderer.tsx
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { Linking, ScrollView, View,
|
|
3
|
-
import { Text, StyleProp, TextStyle } from 'react-native';
|
|
2
|
+
import { Linking, ScrollView, View, Text } from 'react-native';
|
|
4
3
|
import MarkedList from '@jsamr/react-native-li';
|
|
5
4
|
import Disc from '@jsamr/counter-style/presets/disc';
|
|
6
5
|
import Decimal from '@jsamr/counter-style/presets/decimal';
|
|
7
6
|
import MDImage from './../components/MDImage';
|
|
8
|
-
|
|
9
7
|
import { generateRandomString } from '../utils/string';
|
|
8
|
+
import type { TextStyleProp, ViewStyleProp } from './types';
|
|
10
9
|
|
|
11
10
|
class Renderer {
|
|
12
11
|
private onLinkPress = (href: string) => () => Linking.openURL(href);
|
|
13
12
|
|
|
14
13
|
getTextNode = (
|
|
15
14
|
children: string | React.ReactNode[],
|
|
16
|
-
styles:
|
|
15
|
+
styles: TextStyleProp
|
|
17
16
|
) => {
|
|
18
17
|
return (
|
|
19
18
|
<Text key={generateRandomString()} style={styles}>
|
|
@@ -22,7 +21,7 @@ class Renderer {
|
|
|
22
21
|
);
|
|
23
22
|
};
|
|
24
23
|
|
|
25
|
-
getLinkNode = (text: string, href: string, styles:
|
|
24
|
+
getLinkNode = (text: string, href: string, styles: TextStyleProp) => {
|
|
26
25
|
return (
|
|
27
26
|
<Text
|
|
28
27
|
key={generateRandomString()}
|
|
@@ -34,10 +33,7 @@ class Renderer {
|
|
|
34
33
|
);
|
|
35
34
|
};
|
|
36
35
|
|
|
37
|
-
getViewNode(
|
|
38
|
-
children: React.ReactNode[] | null,
|
|
39
|
-
styles: StyleProp<ViewStyle>
|
|
40
|
-
) {
|
|
36
|
+
getViewNode(children: React.ReactNode[] | null, styles: ViewStyleProp) {
|
|
41
37
|
return (
|
|
42
38
|
<View key={generateRandomString()} style={styles}>
|
|
43
39
|
{children}
|
|
@@ -47,8 +43,8 @@ class Renderer {
|
|
|
47
43
|
|
|
48
44
|
getCodeBlockNode(
|
|
49
45
|
text: string,
|
|
50
|
-
containerStyle:
|
|
51
|
-
textStyle:
|
|
46
|
+
containerStyle: ViewStyleProp,
|
|
47
|
+
textStyle: TextStyleProp
|
|
52
48
|
) {
|
|
53
49
|
return (
|
|
54
50
|
<ScrollView contentContainerStyle={containerStyle} horizontal>
|
|
@@ -57,7 +53,7 @@ class Renderer {
|
|
|
57
53
|
);
|
|
58
54
|
}
|
|
59
55
|
|
|
60
|
-
getBlockquoteNode(children: React.ReactNode[], styles:
|
|
56
|
+
getBlockquoteNode(children: React.ReactNode[], styles: ViewStyleProp) {
|
|
61
57
|
return (
|
|
62
58
|
<View key={generateRandomString()} style={styles}>
|
|
63
59
|
{children}
|
|
@@ -71,9 +67,9 @@ class Renderer {
|
|
|
71
67
|
|
|
72
68
|
getListNode(
|
|
73
69
|
ordered: boolean,
|
|
74
|
-
li:
|
|
75
|
-
listStyle:
|
|
76
|
-
textStyle:
|
|
70
|
+
li: React.ReactNode[],
|
|
71
|
+
listStyle: ViewStyleProp,
|
|
72
|
+
textStyle: TextStyleProp
|
|
77
73
|
) {
|
|
78
74
|
return (
|
|
79
75
|
<MarkedList
|
|
@@ -81,11 +77,7 @@ class Renderer {
|
|
|
81
77
|
markerTextStyle={textStyle}
|
|
82
78
|
markerBoxStyle={listStyle}
|
|
83
79
|
>
|
|
84
|
-
{li.map((
|
|
85
|
-
<Text key={index} style={textStyle}>
|
|
86
|
-
{text}
|
|
87
|
-
</Text>
|
|
88
|
-
))}
|
|
80
|
+
{li.map((node) => node)}
|
|
89
81
|
</MarkedList>
|
|
90
82
|
);
|
|
91
83
|
}
|
package/src/lib/types.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type {
|
|
3
|
+
ImageStyle,
|
|
4
|
+
TextStyle,
|
|
5
|
+
ViewStyle,
|
|
6
|
+
FlatListProps,
|
|
7
|
+
} from 'react-native';
|
|
8
|
+
import type { MarkedStyles } from './../theme/types';
|
|
9
|
+
|
|
10
|
+
export type TextStyleProp = TextStyle | undefined;
|
|
11
|
+
export type ViewStyleProp = ViewStyle | undefined;
|
|
12
|
+
export type CustomStyleProp = ViewStyle | TextStyle | ImageStyle | undefined;
|
|
13
|
+
|
|
14
|
+
export interface ParserOptions {
|
|
15
|
+
styles?: MarkedStyles;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface MarkdownProps {
|
|
19
|
+
value: string;
|
|
20
|
+
flatListProps?: Omit<
|
|
21
|
+
FlatListProps<ReactNode>,
|
|
22
|
+
'data' | 'renderItem' | 'horizontal'
|
|
23
|
+
>;
|
|
24
|
+
styles?: MarkedStyles;
|
|
25
|
+
}
|