1
0
mirror of https://github.com/kamranahmedse/developer-roadmap.git synced 2025-09-09 08:40:40 +02:00

Refactor content parsing

This commit is contained in:
Kamran Ahmed
2025-05-23 09:24:38 +01:00
parent c81a2930e6
commit 0d1f19f0a3

View File

@@ -29,52 +29,61 @@ export async function parseMessageParts(
},
) {
const parts: MessagePart[] = [];
const regex = /<([a-zA-Z0-9\-]+)>(.*?)<\/\1>/gs;
const tagNames = Object.keys(renderer);
// If no renderers, just return the content as markdown
if (tagNames.length === 0) {
const html = await markdownToHtmlWithHighlighting(content);
parts.push({
id: nanoid(),
type: 'html',
content: html,
});
return parts;
}
const tagPattern = tagNames.join('|');
const regex = new RegExp(`<(${tagPattern})>(.*?)<\/\\1>`, 'gs');
let lastIndex = 0;
let match;
// we will match all tags in the content
// we will match only tags that have renderers
// and then we will render each tag with the corresponding renderer
// and then we will push the rendered content to the parts array
while ((match = regex.exec(content)) !== null) {
const [_, tag, innerContent] = match;
// check if the tag has a renderer
if (renderer[tag]) {
// push the text before the tag
// so that we can render it later
if (match.index > lastIndex) {
const rawBefore = content.slice(lastIndex, match.index);
const html = await markdownToHtmlWithHighlighting(rawBefore);
parts.push({
id: nanoid(),
type: 'html',
content: html,
});
}
const output = renderer[tag]({
content: innerContent,
isLoading: options.isLoading,
});
// push the text before the tag
// so that we can render it later
if (match.index > lastIndex) {
const rawBefore = content.slice(lastIndex, match.index);
const html = await markdownToHtmlWithHighlighting(rawBefore);
parts.push({
id: nanoid(),
type: 'html',
content: output,
content: html,
});
// update the last index
// so that we can render the next tag
lastIndex = regex.lastIndex;
}
const output = renderer[tag]({
content: innerContent,
isLoading: options.isLoading,
});
parts.push({
id: nanoid(),
type: 'html',
content: output,
});
// update the last index
// so that we can render the next tag
lastIndex = regex.lastIndex;
}
// if there was an opening tag that never closed, check manually
// search for any known tag that starts but wasn't matched
// we have to do this way otherwise we might process html tags
// that are not in the renderer
for (const tag of Object.keys(renderer)) {
for (const tag of tagNames) {
const openingTag = `<${tag}>`;
const openingIndex = content.indexOf(openingTag, lastIndex);
const closingTag = `</${tag}>`;
@@ -105,6 +114,7 @@ export async function parseMessageParts(
return parts;
}
}
// add the remaining content
if (lastIndex < content.length) {
const rawRemaining = content.slice(lastIndex);