File size: 3,284 Bytes
7e67669
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<script lang="ts">
	import { onMount } from 'svelte';
	import type { Token } from 'marked';
	import { revertSanitizedResponseContent, unescapeHtml } from '$lib/utils';

	import CodeBlock from '$lib/components/chat/Messages/CodeBlock.svelte';
	import MarkdownInlineTokens from '$lib/components/chat/Messages/MarkdownInlineTokens.svelte';
	import KatexRenderer from './KatexRenderer.svelte';

	export let id: string;
	export let tokens: Token[];
	export let top = true;

	const headerComponent = (depth: number) => {
		return 'h' + depth;
	};
</script>

<!-- {JSON.stringify(tokens)} -->
{#each tokens as token, tokenIdx}
	{#if token.type === 'hr'}
		<hr />
	{:else if token.type === 'heading'}
		<svelte:element this={headerComponent(token.depth)}>
			<MarkdownInlineTokens id={`${id}-${tokenIdx}-h`} tokens={token.tokens} />
		</svelte:element>
	{:else if token.type === 'code'}
		<CodeBlock
			{id}
			lang={token?.lang ?? ''}
			code={revertSanitizedResponseContent(token?.text ?? '')}
		/>
	{:else if token.type === 'table'}
		<table>
			<thead>
				<tr>
					{#each token.header as header, headerIdx}
						<th style={token.align[headerIdx] ? '' : `text-align: ${token.align[headerIdx]}`}>
							<MarkdownInlineTokens
								id={`${id}-${tokenIdx}-header-${headerIdx}`}
								tokens={header.tokens}
							/>
						</th>
					{/each}
				</tr>
			</thead>
			<tbody>
				{#each token.rows as row, rowIdx}
					<tr>
						{#each row ?? [] as cell, cellIdx}
							<td style={token.align[cellIdx] ? '' : `text-align: ${token.align[cellIdx]}`}>
								<MarkdownInlineTokens
									id={`${id}-${tokenIdx}-row-${rowIdx}-${cellIdx}`}
									tokens={cell.tokens}
								/>
							</td>
						{/each}
					</tr>
				{/each}
			</tbody>
		</table>
	{:else if token.type === 'blockquote'}
		<blockquote>
			<svelte:self id={`${id}-${tokenIdx}`} tokens={token.tokens} />
		</blockquote>
	{:else if token.type === 'list'}
		{#if token.ordered}
			<ol start={token.start || 1}>
				{#each token.items as item, itemIdx}
					<li>
						<svelte:self
							id={`${id}-${tokenIdx}-${itemIdx}`}
							tokens={item.tokens}
							top={token.loose}
						/>
					</li>
				{/each}
			</ol>
		{:else}
			<ul>
				{#each token.items as item, itemIdx}
					<li>
						<svelte:self
							id={`${id}-${tokenIdx}-${itemIdx}`}
							tokens={item.tokens}
							top={token.loose}
						/>
					</li>
				{/each}
			</ul>
		{/if}
	{:else if token.type === 'html'}
		{@html token.text}
	{:else if token.type === 'paragraph'}
		<p>
			<MarkdownInlineTokens id={`${id}-${tokenIdx}-p`} tokens={token.tokens ?? []} />
		</p>
	{:else if token.type === 'text'}
		{#if top}
			<p>
				{#if token.tokens}
					<MarkdownInlineTokens id={`${id}-${tokenIdx}-t`} tokens={token.tokens} />
				{:else}
					{unescapeHtml(token.text)}
				{/if}
			</p>
		{:else if token.tokens}
			<MarkdownInlineTokens id={`${id}-${tokenIdx}-p`} tokens={token.tokens ?? []} />
		{:else}
			{unescapeHtml(token.text)}
		{/if}
	{:else if token.type === 'inlineKatex'}
		{#if token.text}
			<KatexRenderer
				content={revertSanitizedResponseContent(token.text)}
				displayMode={token?.displayMode ?? false}
			/>
		{/if}
	{:else if token.type === 'space'}
		{''}
	{:else}
		{console.log('Unknown token', token)}
	{/if}
{/each}