feat: форматирование — переносы строк, жирный, списки, цветные блоки
This commit is contained in:
+31
-4
@@ -63,13 +63,40 @@
|
||||
document.querySelectorAll('.hitem').forEach(el => {
|
||||
el.onclick = () => {
|
||||
const h = history[+el.dataset.idx];
|
||||
chat.innerHTML += '<div class="user">📋 ' + esc(h.q) + '</div>';
|
||||
chat.innerHTML += '<div class="bot">🤖 ' + esc(h.a) + '</div>';
|
||||
chat.innerHTML += '<div class="user">📋 ' + fmt(h.q) + '</div>';
|
||||
chat.innerHTML += '<div class="bot">🤖 ' + fmt(h.a) + '</div>';
|
||||
chat.scrollTop = chat.scrollHeight;
|
||||
};
|
||||
});
|
||||
}
|
||||
function esc(s) { return String(s).replace(/</g,'<').replace(/>/g,'>'); }
|
||||
function fmt(s) {
|
||||
s = esc(s);
|
||||
// Заменяем **жирный**
|
||||
s = s.replace(/\*\*(.+?)\*\*/g, '<b>$1</b>');
|
||||
// Заменяем `код`
|
||||
s = s.replace(/`(.+?)`/g, '<code>$1</code>');
|
||||
// Заменяем *курсив*
|
||||
s = s.replace(/\*(.+?)\*/g, '<i>$1</i>');
|
||||
// Горизонтальная линия ---
|
||||
s = s.replace(/^---+/gm, '<hr>');
|
||||
// Заголовки ###
|
||||
s = s.replace(/^### (.+)$/gm, '<h3>$1</h3>');
|
||||
s = s.replace(/^## (.+)$/gm, '<h2>$1</h2>');
|
||||
s = s.replace(/^# (.+)$/gm, '<h1>$1</h1>');
|
||||
// Маркированный список
|
||||
s = s.replace(/^[•\-*] (.+)$/gm, '<li>$1</li>');
|
||||
s = s.replace(/(<li>[\s\S]*?<\/li>)/g, '<ul>$1</ul>');
|
||||
// Нумерованный список
|
||||
s = s.replace(/^\d+\.\s+(.+)$/gm, '<li>$1</li>');
|
||||
// Абзацы (двойной перенос строки)
|
||||
s = s.replace(/\n\n+/g, '</p><p>');
|
||||
// Одинарный перенос → <br>
|
||||
s = s.replace(/\n/g, '<br>');
|
||||
// Убираем пустые <ul>
|
||||
s = s.replace(/<ul>\s*<\/ul>/g, '');
|
||||
return '<p>' + s + '</p>';
|
||||
}
|
||||
|
||||
renderHistory();
|
||||
|
||||
@@ -152,7 +179,7 @@
|
||||
clearTimeout(to);
|
||||
const tData = await tRes.json();
|
||||
const text = tData.text || '(не распознано)';
|
||||
chat.innerHTML += '<div class="user">🗣 ' + esc(text) + '</div>';
|
||||
chat.innerHTML += '<div class="user">🗣 ' + fmt(text) + '</div>';
|
||||
chat.scrollTop = chat.scrollHeight;
|
||||
|
||||
startThinkTimer();
|
||||
@@ -166,7 +193,7 @@
|
||||
const cData = await cRes.json();
|
||||
if (cData.sid) sessionSid = cData.sid;
|
||||
const resp = cData.response || cData.error || 'Ошибка';
|
||||
chat.innerHTML += '<div class="bot">🤖 ' + esc(resp) + '</div>';
|
||||
chat.innerHTML += '<div class="bot">🤖 ' + fmt(resp) + '</div>';
|
||||
chat.scrollTop = chat.scrollHeight;
|
||||
setStatus('✅ Готово — ' + ((Date.now() - thinkStart) / 1000).toFixed(1) + 'с');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user