Spaces:
Sleeping
Sleeping
Update templates/index.html
Browse files- templates/index.html +40 -9
templates/index.html
CHANGED
|
@@ -81,7 +81,7 @@
|
|
| 81 |
});
|
| 82 |
};
|
| 83 |
|
| 84 |
-
|
| 85 |
// β
Handle base64 images
|
| 86 |
const imageRegex = /\[IMAGE_START\](.*?)\[IMAGE_END\]/gs;
|
| 87 |
text = text.replace(imageRegex, (match, base64) => {
|
|
@@ -89,21 +89,45 @@
|
|
| 89 |
return `<img src="${src}" alt="Generated Image" class="chat-image"/>`;
|
| 90 |
});
|
| 91 |
|
| 92 |
-
// β
Normalize line endings and remove
|
| 93 |
text = text.replace(/\r\n|\r/g, '\n');
|
| 94 |
text = text.replace(/\n{3,}/g, '\n\n');
|
| 95 |
|
| 96 |
-
// β
Parse
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
text = text.replace(/^### (.*)$/gm, '<h3>$1</h3>');
|
| 98 |
|
| 99 |
-
// β
|
| 100 |
text = text.replace(/^---$/gm, '<hr>');
|
| 101 |
|
| 102 |
-
// β
|
| 103 |
text = text.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
|
| 104 |
text = text.replace(/\*(.*?)\*/g, '<em>$1</em>');
|
| 105 |
|
| 106 |
-
// β
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
const listify = (lines, tag) =>
|
| 108 |
`<${tag}>` +
|
| 109 |
lines.map(item => `<li>${item.replace(/^(\-|\d+\.)\s*/, '').trim()}</li>`).join('') +
|
|
@@ -113,12 +137,16 @@
|
|
| 113 |
/((?:^[-*] .+(?:\n|$))+)/gm,
|
| 114 |
(match) => listify(match.trim().split('\n'), 'ul')
|
| 115 |
);
|
|
|
|
|
|
|
|
|
|
| 116 |
text = text.replace(
|
| 117 |
-
/(
|
| 118 |
-
(
|
| 119 |
);
|
|
|
|
| 120 |
|
| 121 |
-
// β
|
| 122 |
text = text.replace(
|
| 123 |
/^\|(.+?)\|\n\|([-:| ]+)\|\n((?:\|.*\|\n?)*)/gm,
|
| 124 |
(_, headerRow, dividerRow, bodyRows) => {
|
|
@@ -138,6 +166,8 @@
|
|
| 138 |
block.startsWith('<ul>') ||
|
| 139 |
block.startsWith('<ol>') ||
|
| 140 |
block.startsWith('<table>') ||
|
|
|
|
|
|
|
| 141 |
block.startsWith('<img')
|
| 142 |
) {
|
| 143 |
return block;
|
|
@@ -152,6 +182,7 @@
|
|
| 152 |
|
| 153 |
|
| 154 |
|
|
|
|
| 155 |
const renderCode = (text) => {
|
| 156 |
const codeBlocks = text.split(/```/);
|
| 157 |
let output = '';
|
|
|
|
| 81 |
});
|
| 82 |
};
|
| 83 |
|
| 84 |
+
const formatText = (text) => {
|
| 85 |
// β
Handle base64 images
|
| 86 |
const imageRegex = /\[IMAGE_START\](.*?)\[IMAGE_END\]/gs;
|
| 87 |
text = text.replace(imageRegex, (match, base64) => {
|
|
|
|
| 89 |
return `<img src="${src}" alt="Generated Image" class="chat-image"/>`;
|
| 90 |
});
|
| 91 |
|
| 92 |
+
// β
Normalize line endings and remove excessive blank lines
|
| 93 |
text = text.replace(/\r\n|\r/g, '\n');
|
| 94 |
text = text.replace(/\n{3,}/g, '\n\n');
|
| 95 |
|
| 96 |
+
// β
Parse fenced code blocks (```code```)
|
| 97 |
+
text = text.replace(/```(\w+)?\n([\s\S]*?)```/g, (match, lang, code) => {
|
| 98 |
+
const language = lang ? ` class="language-${lang}"` : '';
|
| 99 |
+
return `<pre><code${language}>${code.trim().replace(/</g, '<').replace(/>/g, '>')}</code></pre>`;
|
| 100 |
+
});
|
| 101 |
+
|
| 102 |
+
// β
Parse blockquotes
|
| 103 |
+
text = text.replace(/^> (.*)$/gm, '<blockquote>$1</blockquote>');
|
| 104 |
+
|
| 105 |
+
// β
Headings
|
| 106 |
text = text.replace(/^### (.*)$/gm, '<h3>$1</h3>');
|
| 107 |
|
| 108 |
+
// β
Horizontal rules
|
| 109 |
text = text.replace(/^---$/gm, '<hr>');
|
| 110 |
|
| 111 |
+
// β
Bold (**text**) and italic (*text*)
|
| 112 |
text = text.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
|
| 113 |
text = text.replace(/\*(.*?)\*/g, '<em>$1</em>');
|
| 114 |
|
| 115 |
+
// β
Emoji rendering using colon syntax (:smile:)
|
| 116 |
+
const emojiMap = {
|
| 117 |
+
smile: "π",
|
| 118 |
+
sad: "π’",
|
| 119 |
+
heart: "β€οΈ",
|
| 120 |
+
thumbs_up: "π",
|
| 121 |
+
fire: "π₯",
|
| 122 |
+
check: "β
",
|
| 123 |
+
x: "β",
|
| 124 |
+
star: "β",
|
| 125 |
+
rocket: "π",
|
| 126 |
+
warning: "β οΈ",
|
| 127 |
+
};
|
| 128 |
+
text = text.replace(/:([a-z0-9_+-]+):/g, (match, name) => emojiMap[name] || match);
|
| 129 |
+
|
| 130 |
+
// β
Unordered list (bullets)
|
| 131 |
const listify = (lines, tag) =>
|
| 132 |
`<${tag}>` +
|
| 133 |
lines.map(item => `<li>${item.replace(/^(\-|\d+\.)\s*/, '').trim()}</li>`).join('') +
|
|
|
|
| 137 |
/((?:^[-*] .+(?:\n|$))+)/gm,
|
| 138 |
(match) => listify(match.trim().split('\n'), 'ul')
|
| 139 |
);
|
| 140 |
+
|
| 141 |
+
// β
Ordered list (fix separate `1.` items issue)
|
| 142 |
+
text = text.replace(/^(\d+\. .+)$/gm, '__ORDERED__START__$1__ORDERED__END__');
|
| 143 |
text = text.replace(
|
| 144 |
+
/__ORDERED__START__(\d+\. .+?)__ORDERED__END__/gs,
|
| 145 |
+
(_, line) => `<ol><li>${line.replace(/^\d+\.\s*/, '')}</li></ol>`
|
| 146 |
);
|
| 147 |
+
text = text.replace(/<\/ol>\s*<ol>/g, '');
|
| 148 |
|
| 149 |
+
// β
Markdown-style tables
|
| 150 |
text = text.replace(
|
| 151 |
/^\|(.+?)\|\n\|([-:| ]+)\|\n((?:\|.*\|\n?)*)/gm,
|
| 152 |
(_, headerRow, dividerRow, bodyRows) => {
|
|
|
|
| 166 |
block.startsWith('<ul>') ||
|
| 167 |
block.startsWith('<ol>') ||
|
| 168 |
block.startsWith('<table>') ||
|
| 169 |
+
block.startsWith('<pre>') ||
|
| 170 |
+
block.startsWith('<blockquote>') ||
|
| 171 |
block.startsWith('<img')
|
| 172 |
) {
|
| 173 |
return block;
|
|
|
|
| 182 |
|
| 183 |
|
| 184 |
|
| 185 |
+
|
| 186 |
const renderCode = (text) => {
|
| 187 |
const codeBlocks = text.split(/```/);
|
| 188 |
let output = '';
|