Skip to content

Commit 5553e79

Browse files
committed
Use react-native-markdown-renderer on AI responses
Fixes #41
1 parent 50b8f85 commit 5553e79

File tree

3 files changed

+76
-46
lines changed

3 files changed

+76
-46
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"postinstall-postinstall": "^2.1.0",
2020
"react": "18.2.0",
2121
"react-native": "0.71.0",
22+
"react-native-markdown-renderer": "^3.2.8",
2223
"react-native-syntax-highlighter": "^2.1.0",
2324
"react-native-windows": "0.71.1"
2425
},

src/AiResponse.tsx

Lines changed: 11 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
import { StylesContext } from './Styles';
2222
import { FeedbackContext } from './Feedback';
2323
import Clipboard from '@react-native-clipboard/clipboard';
24+
import Markdown from 'react-native-markdown-renderer';
2425

2526
type AiImageResponseProps = {
2627
imageUrl?: string;
@@ -64,54 +65,19 @@ type AiTextResponseProps = {
6465
function AiTextResponse({text}: AiTextResponseProps): JSX.Element {
6566
let elements: JSX.Element[] = [];
6667

67-
function* matchAll(text: string, regexp: RegExp) {
68-
let match;
69-
while ((match = regexp.exec(text)) !== null) {
70-
yield {value: match, start: match.index, end: regexp.lastIndex};
68+
const rules = {
69+
fence: (node, children, parent, styles) => {
70+
return (
71+
<CodeBlock
72+
key={node.key}
73+
language={node.sourceInfo}
74+
content={node.content}/>
75+
)
76+
},
7177
}
72-
}
73-
74-
// Break up the text into code blocks and regular text
75-
if (text !== undefined) {
76-
// Look for the ``` separator (with option language)
77-
const regex = /^```(.*)$/gm;
78-
let matches = [...matchAll(text, regex)];
79-
80-
// Keep track of where we are in the open/close code blocks
81-
let index = 0;
82-
let inCodeBlock = false;
83-
let currentLanguage = "";
84-
85-
const appendToElements = (key: number, value: string) => {
86-
if (!inCodeBlock) {
87-
elements = [...elements, <Text key={key}>{value}</Text>];
88-
} else {
89-
elements = [...elements, <CodeBlock key={key} language={currentLanguage ?? "unknown"} content={value}/>];
90-
}
91-
}
92-
93-
for (let i = 0; i < matches.length; i++) {
94-
// Grab the text since the last match, but strip out the separator/language
95-
let match = matches[i];
96-
let textSinceLast = text.substring(index, match.start).trim();
97-
index = match.start + match.value[0].length;
98-
99-
appendToElements(i, textSinceLast);
100-
101-
currentLanguage = match.value[1];
102-
inCodeBlock = !inCodeBlock;
103-
}
104-
105-
// Add the remaining text after the last ``` separator
106-
if (index < text.length) {
107-
appendToElements(matches.length, text.substring(index, text.length).trim());
108-
}
109-
}
11078

11179
return (
112-
<View style={{gap: 8}}>
113-
{elements}
114-
</View>
80+
<Markdown rules={rules}>{text || ""}</Markdown>
11581
);
11682
}
11783

yarn.lock

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1956,6 +1956,11 @@
19561956
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
19571957
integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==
19581958

1959+
"@types/markdown-it@^0.0.4":
1960+
version "0.0.4"
1961+
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.4.tgz#c5f67365916044b342dae8d702724788ba0b5b74"
1962+
integrity sha512-FWR7QB7EqBRq1s9BMk0ccOSOuRLfVEWYpHQYpFPaXtCoqN6dJx2ttdsdQbUxLLnAlKpYeVjveGGhQ3583TTa7g==
1963+
19591964
"@types/node@*":
19601965
version "18.11.18"
19611966
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f"
@@ -1971,6 +1976,13 @@
19711976
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
19721977
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
19731978

1979+
"@types/react-native@>=0.50.0":
1980+
version "0.71.3"
1981+
resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.71.3.tgz#537f669ed6b38b5ae47444bd9d253c4cff23bed7"
1982+
integrity sha512-0Uqw1YZ0qbVla0MMWFTANFm6W8KYWNvGQmYfucdecbXivLMcQ2v4PovuYFKr7bE6Bc5nDCUEaga962Y8gcDF7A==
1983+
dependencies:
1984+
"@types/react" "*"
1985+
19741986
"@types/react-test-renderer@^18.0.0":
19751987
version "18.0.0"
19761988
resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-18.0.0.tgz#7b7f69ca98821ea5501b21ba24ea7b6139da2243"
@@ -3240,6 +3252,11 @@ end-of-stream@^1.1.0:
32403252
dependencies:
32413253
once "^1.4.0"
32423254

3255+
entities@~1.1.1:
3256+
version "1.1.2"
3257+
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
3258+
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
3259+
32433260
envinfo@^7.5.0, envinfo@^7.7.2, envinfo@^7.8.1:
32443261
version "7.8.1"
32453262
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475"
@@ -5275,6 +5292,13 @@ lines-and-columns@^1.1.6:
52755292
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
52765293
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
52775294

5295+
linkify-it@^2.0.0:
5296+
version "2.2.0"
5297+
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf"
5298+
integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==
5299+
dependencies:
5300+
uc.micro "^1.0.1"
5301+
52785302
load-json-file@^4.0.0:
52795303
version "4.0.0"
52805304
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b"
@@ -5421,6 +5445,22 @@ map-visit@^1.0.0:
54215445
dependencies:
54225446
object-visit "^1.0.0"
54235447

5448+
markdown-it@^8.4.0:
5449+
version "8.4.2"
5450+
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54"
5451+
integrity sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==
5452+
dependencies:
5453+
argparse "^1.0.7"
5454+
entities "~1.1.1"
5455+
linkify-it "^2.0.0"
5456+
mdurl "^1.0.1"
5457+
uc.micro "^1.0.5"
5458+
5459+
mdurl@^1.0.1:
5460+
version "1.0.1"
5461+
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
5462+
integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==
5463+
54245464
mem@^4.3.0:
54255465
version "4.3.0"
54265466
resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178"
@@ -6527,7 +6567,7 @@ prompts@^2.0.1, prompts@^2.4.0, prompts@^2.4.1:
65276567
kleur "^3.0.3"
65286568
sisteransi "^1.0.5"
65296569

6530-
prop-types@*, prop-types@^15.8.1:
6570+
prop-types@*, prop-types@^15.5.10, prop-types@^15.8.1:
65316571
version "15.8.1"
65326572
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
65336573
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -6599,11 +6639,29 @@ react-native-codegen@^0.71.3:
65996639
jscodeshift "^0.13.1"
66006640
nullthrows "^1.1.1"
66016641

6642+
react-native-fit-image@^1.5.2:
6643+
version "1.5.5"
6644+
resolved "https://registry.yarnpkg.com/react-native-fit-image/-/react-native-fit-image-1.5.5.tgz#c660d1ad74b9dcaa1cba27a0d9c23837e000226c"
6645+
integrity sha512-Wl3Vq2DQzxgsWKuW4USfck9zS7YzhvLNPpkwUUCF90bL32e1a0zOVQ3WsJILJOwzmPdHfzZmWasiiAUNBkhNkg==
6646+
dependencies:
6647+
prop-types "^15.5.10"
6648+
66026649
react-native-gradle-plugin@^0.71.12:
66036650
version "0.71.14"
66046651
resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.14.tgz#cc399662f04fbfcc0e352d03eae1d3efbd5f635a"
66056652
integrity sha512-nnLawTZEPPRAKq92UqDkzoGgCBl9aa9zAihFHMwmwzn4WRVdK4O6Cd4XYiyoNOiQzx3Hh9k5WOckHE80C92ivQ==
66066653

6654+
react-native-markdown-renderer@^3.2.8:
6655+
version "3.2.8"
6656+
resolved "https://registry.yarnpkg.com/react-native-markdown-renderer/-/react-native-markdown-renderer-3.2.8.tgz#217046cf198eca632a65f93cdf7dd7766f718070"
6657+
integrity sha512-gDT5r3lwecNsEfpKagSaidEGfmCbpVcmV+HHLjaGYRALJoHkpOFni0rJZW1rCerOR9sjaUNGXE66U7BUrlEw0w==
6658+
dependencies:
6659+
"@types/markdown-it" "^0.0.4"
6660+
"@types/react-native" ">=0.50.0"
6661+
markdown-it "^8.4.0"
6662+
prop-types "^15.5.10"
6663+
react-native-fit-image "^1.5.2"
6664+
66076665
react-native-syntax-highlighter@^2.1.0:
66086666
version "2.1.0"
66096667
resolved "https://registry.yarnpkg.com/react-native-syntax-highlighter/-/react-native-syntax-highlighter-2.1.0.tgz#66bdb2cedbe938b291bfe415e5d72d0c275ce353"
@@ -7641,6 +7699,11 @@ [email protected]:
76417699
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6"
76427700
integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==
76437701

7702+
uc.micro@^1.0.1, uc.micro@^1.0.5:
7703+
version "1.0.6"
7704+
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
7705+
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
7706+
76447707
uglify-es@^3.1.9:
76457708
version "3.3.9"
76467709
resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677"

0 commit comments

Comments
 (0)