trying different markdown library for proper list styling

This commit is contained in:
Daniel Avila 2023-02-24 23:16:19 -05:00
parent 34ebd97c9d
commit 78c9f3dc74
8 changed files with 4352 additions and 132 deletions

View file

@ -38,7 +38,7 @@ Currently, this project is only functional with the `text-davinci-003` model.
- [x] Bing AI integration - [x] Bing AI integration
- [x] Remember last selected model - [x] Remember last selected model
- [x] Highlight.js for code blocks - [x] Highlight.js for code blocks
- [ ] Markdown handling - [x] Markdown handling
- [ ] AI model change handling (whether to pseudo-persist convos or start new convos within existing convo) - [ ] AI model change handling (whether to pseudo-persist convos or start new convos within existing convo)
- [ ] Server convo pagination (limit fetch and load more with 'show more' button) - [ ] Server convo pagination (limit fetch and load more with 'show more' button)
- [ ] Prompt Templates - [ ] Prompt Templates

95
package-lock.json generated
View file

@ -24,6 +24,7 @@
"keyv": "^4.5.2", "keyv": "^4.5.2",
"keyv-file": "^0.2.0", "keyv-file": "^0.2.0",
"lucide-react": "^0.113.0", "lucide-react": "^0.113.0",
"markdown-to-jsx": "^7.1.9",
"mongoose": "^6.9.0", "mongoose": "^6.9.0",
"openai": "^3.1.0", "openai": "^3.1.0",
"react": "^18.2.0", "react": "^18.2.0",
@ -46,7 +47,6 @@
"@babel/preset-env": "^7.20.2", "@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6", "@babel/preset-react": "^7.18.6",
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@tailwindcss/typography": "^0.5.9",
"autoprefixer": "^10.4.13", "autoprefixer": "^10.4.13",
"babel-loader": "^9.1.2", "babel-loader": "^9.1.2",
"babel-plugin-root-import": "^6.6.0", "babel-plugin-root-import": "^6.6.0",
@ -4098,34 +4098,6 @@
} }
} }
}, },
"node_modules/@tailwindcss/typography": {
"version": "0.5.9",
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.9.tgz",
"integrity": "sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg==",
"dev": true,
"dependencies": {
"lodash.castarray": "^4.4.0",
"lodash.isplainobject": "^4.0.6",
"lodash.merge": "^4.6.2",
"postcss-selector-parser": "6.0.10"
},
"peerDependencies": {
"tailwindcss": ">=3.0.0 || insiders"
}
},
"node_modules/@tailwindcss/typography/node_modules/postcss-selector-parser": {
"version": "6.0.10",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
"integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
"dev": true,
"dependencies": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@types/body-parser": { "node_modules/@types/body-parser": {
"version": "1.19.2", "version": "1.19.2",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
@ -10047,24 +10019,12 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
}, },
"node_modules/lodash.castarray": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
"integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
"dev": true
},
"node_modules/lodash.debounce": { "node_modules/lodash.debounce": {
"version": "4.0.8", "version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
"dev": true "dev": true
}, },
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
"dev": true
},
"node_modules/lodash.merge": { "node_modules/lodash.merge": {
"version": "4.6.2", "version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@ -10165,6 +10125,17 @@
"semver": "bin/semver" "semver": "bin/semver"
} }
}, },
"node_modules/markdown-to-jsx": {
"version": "7.1.9",
"resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.1.9.tgz",
"integrity": "sha512-x4STVIKIJR0mGgZIZ5RyAeQD7FEZd5tS8m/htbcVGlex32J+hlSLj+ExrHCxP6nRKF1EKbcO7i6WhC1GtOpBlA==",
"engines": {
"node": ">= 10"
},
"peerDependencies": {
"react": ">= 0.14.0"
}
},
"node_modules/md5.js": { "node_modules/md5.js": {
"version": "1.3.5", "version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@ -18875,30 +18846,6 @@
"reselect": "^4.1.7" "reselect": "^4.1.7"
} }
}, },
"@tailwindcss/typography": {
"version": "0.5.9",
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.9.tgz",
"integrity": "sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg==",
"dev": true,
"requires": {
"lodash.castarray": "^4.4.0",
"lodash.isplainobject": "^4.0.6",
"lodash.merge": "^4.6.2",
"postcss-selector-parser": "6.0.10"
},
"dependencies": {
"postcss-selector-parser": {
"version": "6.0.10",
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz",
"integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==",
"dev": true,
"requires": {
"cssesc": "^3.0.0",
"util-deprecate": "^1.0.2"
}
}
}
},
"@types/body-parser": { "@types/body-parser": {
"version": "1.19.2", "version": "1.19.2",
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz",
@ -23395,24 +23342,12 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
}, },
"lodash.castarray": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz",
"integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==",
"dev": true
},
"lodash.debounce": { "lodash.debounce": {
"version": "4.0.8", "version": "4.0.8",
"resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
"integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
"dev": true "dev": true
}, },
"lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
"dev": true
},
"lodash.merge": { "lodash.merge": {
"version": "4.6.2", "version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@ -23491,6 +23426,12 @@
} }
} }
}, },
"markdown-to-jsx": {
"version": "7.1.9",
"resolved": "https://registry.npmjs.org/markdown-to-jsx/-/markdown-to-jsx-7.1.9.tgz",
"integrity": "sha512-x4STVIKIJR0mGgZIZ5RyAeQD7FEZd5tS8m/htbcVGlex32J+hlSLj+ExrHCxP6nRKF1EKbcO7i6WhC1GtOpBlA==",
"requires": {}
},
"md5.js": { "md5.js": {
"version": "1.3.5", "version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",

View file

@ -36,6 +36,7 @@
"keyv": "^4.5.2", "keyv": "^4.5.2",
"keyv-file": "^0.2.0", "keyv-file": "^0.2.0",
"lucide-react": "^0.113.0", "lucide-react": "^0.113.0",
"markdown-to-jsx": "^7.1.9",
"mongoose": "^6.9.0", "mongoose": "^6.9.0",
"openai": "^3.1.0", "openai": "^3.1.0",
"react": "^18.2.0", "react": "^18.2.0",
@ -58,7 +59,6 @@
"@babel/preset-env": "^7.20.2", "@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6", "@babel/preset-react": "^7.18.6",
"@babel/runtime": "^7.20.13", "@babel/runtime": "^7.20.13",
"@tailwindcss/typography": "^0.5.9",
"autoprefixer": "^10.4.13", "autoprefixer": "^10.4.13",
"babel-loader": "^9.1.2", "babel-loader": "^9.1.2",
"babel-plugin-root-import": "^6.6.0", "babel-plugin-root-import": "^6.6.0",

View file

@ -1,23 +1,14 @@
import React from 'react'; import React from 'react';
import ReactMarkdown from 'react-markdown'; // import ReactMarkdown from 'react-markdown';
import supersub from 'remark-supersub' // import supersub from 'remark-supersub'
import Markdown from 'markdown-to-jsx';
import Embed from './Embed'; import Embed from './Embed';
import Highlight from './Highlight'; import Highlight from './Highlight';
import regexSplit from '~/utils/regexSplit'; import regexSplit from '~/utils/regexSplit';
import { languages, wrapperRegex } from '~/utils'; import { languages, wrapperRegex } from '~/utils';
const { codeRegex, inLineRegex, matchRegex, languageMatch, newLineMatch } = wrapperRegex; const { codeRegex, inLineRegex, matchRegex, languageMatch, newLineMatch } = wrapperRegex;
const mdOptions = { wrapper: React.Fragment, forceWrapper: true };
// original function
// const inLineWrap = (parts) =>
// parts.map((part, i) => {
// if (part.match(matchRegex)) {
// return <code key={i} >{part.slice(1, -1)}</code>;
// } else {
// // return <p key={i}>{part}</p>;
// // return part;
// return part.includes('`') ? part : <ReactMarkdown key={i}>{part}</ReactMarkdown>;
// }
// });
const inLineWrap = (parts) => { const inLineWrap = (parts) => {
let previousElement = null; let previousElement = null;
@ -27,10 +18,11 @@ const inLineWrap = (parts) => {
if (previousElement && typeof previousElement !== 'string') { if (previousElement && typeof previousElement !== 'string') {
// Append code element as a child to previous non-code element // Append code element as a child to previous non-code element
previousElement = ( previousElement = (
<ReactMarkdown remarkPlugins={[supersub]} key={i}> // <ReactMarkdown remarkPlugins={[supersub]} key={i}>
<Markdown options={mdOptions} key={i}>
{previousElement} {previousElement}
{codeElement} {codeElement}
</ReactMarkdown> </Markdown>
); );
return previousElement; return previousElement;
} else { } else {
@ -46,15 +38,11 @@ const inLineWrap = (parts) => {
export default function TextWrapper({ text }) { export default function TextWrapper({ text }) {
// append triple backticks to the end of the text only if singular found and language found // append triple backticks to the end of the text only if singular found and language found
if (text.match(/```/g)?.length === 1 && text.match(languageMatch)) { if (text.match(/```/g)?.length === 1 && text.match(languageMatch)) {
text += '```'; text += '\n```';
} }
if (text.match(codeRegex)) { if (text.match(codeRegex)) {
// if (text.includes('```')) {
// const parts = text.split(codeRegex);
const parts = regexSplit(text); const parts = regexSplit(text);
// console.log(parts);
const codeParts = parts.map((part, i) => { const codeParts = parts.map((part, i) => {
if (part.match(codeRegex)) { if (part.match(codeRegex)) {
let language = 'javascript'; let language = 'javascript';
@ -84,15 +72,20 @@ export default function TextWrapper({ text }) {
return inLineWrap(innerParts); return inLineWrap(innerParts);
} else { } else {
// return part; // return part;
return <ReactMarkdown remarkPlugins={[supersub]} key={i}>{part}</ReactMarkdown>; // return <ReactMarkdown remarkPlugins={[supersub]} key={i}>{part}</ReactMarkdown>;
return <Markdown options={mdOptions} key={i}>{part}</Markdown>
} }
}); });
return <>{codeParts}</>; // return the wrapped text return <>{codeParts}</>; // return the wrapped text
} else { } else if (text.match(matchRegex)) {
// map over the parts and wrap any text between tildes with <code> tags // map over the parts and wrap any text between tildes with <code> tags
const parts = text.split(matchRegex); const parts = text.split(matchRegex);
const codeParts = inLineWrap(parts); const codeParts = inLineWrap(parts);
return <>{codeParts}</>; // return the wrapped text return <>{codeParts}</>; // return the wrapped text
} else {
// return <ReactMarkdown remarkPlugins={[supersub]}>{text}</ReactMarkdown>;
// return text
return <Markdown options={mdOptions}>{text}</Markdown>;
} }
} }

View file

@ -36,34 +36,63 @@ export default function TextChat({ messages }) {
const messageHandler = (data) => { const messageHandler = (data) => {
dispatch(setMessages([...messages, currentMsg, { sender: model, text: data }])); dispatch(setMessages([...messages, currentMsg, { sender: model, text: data }]));
}; };
const convoHandler = (data) => { // const convoHandler = (data) => {
console.log('in convo handler'); // dispatch(
if (model !== 'bingai' && convo.conversationId === null && convo.parentMessageId === null) { // setMessages([...messages, { sender: model, text: data.text || data.response }])
const { title, conversationId, id } = data; // );
dispatch(
setConversation({
title,
conversationId,
parentMessageId: id,
conversationSignature: null,
clientId: null,
invocationId: null
})
);
} else if (model === 'bingai' && convo.conversationId === null && convo.invocationId === null) {
const { title, conversationSignature, clientId, conversationId, invocationId } = data;
dispatch(
setConversation({
title,
conversationSignature,
clientId,
conversationId,
invocationId,
parentMessageId: null
})
);
}
// if (
// model !== 'bingai' &&
// convo.conversationId === null &&
// convo.parentMessageId === null
// ) {
// const { title, conversationId, id } = data;
// dispatch(
// setConversation({
// title,
// conversationId,
// parentMessageId: id,
// conversationSignature: null,
// clientId: null,
// invocationId: null
// })
// );
// } else if (
// model === 'bingai' &&
// convo.conversationId === null &&
// convo.invocationId === null
// ) {
// const { title, conversationSignature, clientId, conversationId, invocationId } = data;
// dispatch(
// setConversation({
// title,
// conversationSignature,
// clientId,
// conversationId,
// invocationId,
// parentMessageId: null
// })
// );
// }
// dispatch(setSubmitState(false));
// };
const convoHandler = (data) => {
const { conversationId, id, invocationId, text } = data;
const conversationData = {
title: data.title,
conversationId,
parentMessageId:
model !== 'bingai' && !convo.conversationId && !convo.parentMessageId ? id : null,
conversationSignature:
model === 'bingai' && !convo.conversationId ? data.conversationSignature : null,
clientId: model === 'bingai' && !convo.conversationId ? data.clientId : null,
// invocationId: model === 'bingai' && !convo.conversationId ? data.invocationId : null
invocationId: invocationId ? invocationId : null
};
dispatch(setMessages([...messages, currentMsg, { sender: model, text: text || data.response }]));
dispatch(setConversation(conversationData));
dispatch(setSubmitState(false)); dispatch(setSubmitState(false));
}; };

4251
src/style - official.css Normal file

File diff suppressed because it is too large Load diff

View file

@ -11,6 +11,10 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre {
margin: 0; margin: 0;
} }
.markdown ol li, .markdown ol li > p, .markdown ol ol, .markdown ol ul, .markdown ul li, .markdown ul li > p, .markdown ul ol, .markdown ul ul {
margin: 0;
}
.scroll-down-enter { .scroll-down-enter {
opacity: 0; opacity: 0;
} }
@ -901,13 +905,17 @@ html {
padding-left: 1rem; padding-left: 1rem;
} }
.markdown ol, /* .markdown ol, */
.markdown ul { .markdown ul {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding-left: 1rem; padding-left: 1rem;
} }
.markdown ol {
list-style-type: decimal;
}
.markdown ol li, .markdown ol li,
.markdown ol li > p, .markdown ol li > p,
.markdown ol ol, .markdown ol ol,
@ -1227,3 +1235,4 @@ html {
margin-left: 0.25rem; margin-left: 0.25rem;
vertical-align: baseline; vertical-align: baseline;
} }

View file

@ -43,11 +43,8 @@ export default function handleSubmit({
const data = JSON.parse(e.data); const data = JSON.parse(e.data);
let text = data.text || data.response; let text = data.text || data.response;
if (data.message) { if (data.message) {
// text = text.match(newLineRegex) ? text.replace(newLineRegex, '') : text;
// console.log(data);
messageHandler(text); messageHandler(text);
} else if (data.final) { } else if (data.final) {
console.log(data);
convoHandler(data); convoHandler(data);
} else { } else {
console.log('initial', data); console.log('initial', data);