fix: render bold and inline code formatting in list items
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { Bot } from '$lib/api';
|
import type { Bot } from '$lib/api';
|
||||||
import type { ChatMessage } from '$lib/stores/chatStore';
|
import type { ChatMessage } from '$lib/stores/chatStore';
|
||||||
import { parseMarkdown } from '$lib/utils/markdown';
|
import { parseMarkdown, parseInlineElements, type InlineSegment } from '$lib/utils/markdown';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
bot: Bot | null;
|
bot: Bot | null;
|
||||||
@@ -62,6 +62,18 @@
|
|||||||
function renderContent(content: string) {
|
function renderContent(content: string) {
|
||||||
return parseMarkdown(content);
|
return parseMarkdown(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderInline(segments: InlineSegment[]): string {
|
||||||
|
return segments.map(seg => {
|
||||||
|
switch (seg.type) {
|
||||||
|
case 'bold': return `<strong>${seg.content}</strong>`;
|
||||||
|
case 'italic': return `<em>${seg.content}</em>`;
|
||||||
|
case 'code': return `<code class="inline-code">${seg.content}</code>`;
|
||||||
|
case 'link': return `<a href="${seg.href || '#'}" target="_blank" rel="noopener noreferrer">${seg.content}</a>`;
|
||||||
|
default: return seg.content;
|
||||||
|
}
|
||||||
|
}).join('');
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="chat-interface">
|
<div class="chat-interface">
|
||||||
@@ -121,7 +133,7 @@
|
|||||||
{:else if segment.type === 'list' && segment.items}
|
{:else if segment.type === 'list' && segment.items}
|
||||||
<ul>
|
<ul>
|
||||||
{#each segment.items as item}
|
{#each segment.items as item}
|
||||||
<li>{item}</li>
|
<li>{@html renderInline(parseInlineElements(item))}</li>
|
||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
{:else if segment.type === 'table' && segment.headers && segment.rows}
|
{:else if segment.type === 'table' && segment.headers && segment.rows}
|
||||||
|
|||||||
@@ -134,6 +134,19 @@ function parseInlineElements(text: string): InlineSegment[] {
|
|||||||
return segments;
|
return segments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render inline segments to HTML string
|
||||||
|
function renderInlineSegments(segments: InlineSegment[]): string {
|
||||||
|
return segments.map(seg => {
|
||||||
|
switch (seg.type) {
|
||||||
|
case 'bold': return `<strong>${seg.content}</strong>`;
|
||||||
|
case 'italic': return `<em>${seg.content}</em>`;
|
||||||
|
case 'code': return `<code class="inline-code">${seg.content}</code>`;
|
||||||
|
case 'link': return `<a href="${seg.href || '#'}" target="_blank" rel="noopener noreferrer">${seg.content}</a>`;
|
||||||
|
default: return seg.content;
|
||||||
|
}
|
||||||
|
}).join('');
|
||||||
|
}
|
||||||
|
|
||||||
function parseLines(text: string): ParsedSegment[] {
|
function parseLines(text: string): ParsedSegment[] {
|
||||||
const segments: ParsedSegment[] = [];
|
const segments: ParsedSegment[] = [];
|
||||||
|
|
||||||
@@ -160,12 +173,16 @@ function parseLines(text: string): ParsedSegment[] {
|
|||||||
if (line.match(/^[\-\*]\s/)) {
|
if (line.match(/^[\-\*]\s/)) {
|
||||||
const listMatch = line.match(/^([\-\*])\s(.*)/);
|
const listMatch = line.match(/^([\-\*])\s(.*)/);
|
||||||
if (listMatch) {
|
if (listMatch) {
|
||||||
|
// Parse inline formatting for list item
|
||||||
|
const itemContent = listMatch[2];
|
||||||
|
const inlineSegments = parseInlineElements(itemContent);
|
||||||
|
|
||||||
// Check if previous segment is a list
|
// Check if previous segment is a list
|
||||||
const lastSeg = segments[segments.length - 1];
|
const lastSeg = segments[segments.length - 1];
|
||||||
if (lastSeg && lastSeg.type === 'list') {
|
if (lastSeg && lastSeg.type === 'list') {
|
||||||
lastSeg.items?.push(listMatch[2]);
|
lastSeg.items?.push(itemContent);
|
||||||
} else {
|
} else {
|
||||||
segments.push({ type: 'list', content: '', items: [listMatch[2]] });
|
segments.push({ type: 'list', content: '', items: [itemContent] });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -175,11 +192,13 @@ function parseLines(text: string): ParsedSegment[] {
|
|||||||
if (line.match(/^\d+\.\s/)) {
|
if (line.match(/^\d+\.\s/)) {
|
||||||
const listMatch = line.match(/^\d+\.\s(.*)/);
|
const listMatch = line.match(/^\d+\.\s(.*)/);
|
||||||
if (listMatch) {
|
if (listMatch) {
|
||||||
|
const itemContent = listMatch[1];
|
||||||
|
|
||||||
const lastSeg = segments[segments.length - 1];
|
const lastSeg = segments[segments.length - 1];
|
||||||
if (lastSeg && lastSeg.type === 'list') {
|
if (lastSeg && lastSeg.type === 'list') {
|
||||||
lastSeg.items?.push(listMatch[1]);
|
lastSeg.items?.push(itemContent);
|
||||||
} else {
|
} else {
|
||||||
segments.push({ type: 'list', content: '', items: [listMatch[1]] });
|
segments.push({ type: 'list', content: '', items: [itemContent] });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user