MarkdownTokens.svelte 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. <script lang="ts">
  2. import type { Token } from 'marked';
  3. import { revertSanitizedResponseContent, unescapeHtml } from '$lib/utils';
  4. import CodeBlock from '$lib/components/chat/Messages/CodeBlock.svelte';
  5. import { onMount } from 'svelte';
  6. import MarkdownInlineTokens from '$lib/components/chat/Messages/MarkdownInlineTokens.svelte';
  7. export let id: string;
  8. export let tokens: Token[];
  9. export let top = true;
  10. const headerComponent = (depth: number) => {
  11. return 'h' + depth;
  12. };
  13. onMount(() => {
  14. console.log('MarkdownTokens', id, tokens, top);
  15. });
  16. </script>
  17. {#each tokens as token, tokenIdx}
  18. {#if token.type === 'hr'}
  19. <hr />
  20. {:else if token.type === 'heading'}
  21. <svelte:element this={headerComponent(token.depth)}>
  22. <MarkdownInlineTokens id={`${id}-${tokenIdx}-h`} tokens={token.tokens} />
  23. </svelte:element>
  24. {:else if token.type === 'code'}
  25. <CodeBlock
  26. {id}
  27. lang={token?.lang ?? ''}
  28. code={revertSanitizedResponseContent(token?.text ?? '')}
  29. />
  30. {:else if token.type === 'table'}
  31. <table>
  32. <thead>
  33. <tr>
  34. {#each token.header as header, headerIdx}
  35. <th style={token.align[headerIdx] ? '' : `text-align: ${token.align[headerIdx]}`}>
  36. <MarkdownInlineTokens
  37. id={`${id}-${tokenIdx}-header-${headerIdx}`}
  38. tokens={header.tokens}
  39. />
  40. </th>
  41. {/each}
  42. </tr>
  43. </thead>
  44. <tbody>
  45. {#each token.rows as row, rowIdx}
  46. <tr>
  47. {#each row ?? [] as cell, cellIdx}
  48. <td style={token.align[cellIdx] ? '' : `text-align: ${token.align[cellIdx]}`}>
  49. <MarkdownInlineTokens
  50. id={`${id}-${tokenIdx}-row-${rowIdx}-${cellIdx}`}
  51. tokens={cell.tokens}
  52. />
  53. </td>
  54. {/each}
  55. </tr>
  56. {/each}
  57. </tbody>
  58. </table>
  59. {:else if token.type === 'blockquote'}
  60. <blockquote>
  61. <svelte:self id={`${id}-${tokenIdx}`} tokens={token.tokens} />
  62. </blockquote>
  63. {:else if token.type === 'list'}
  64. {#if token.ordered}
  65. <ol start={token.start || 1}>
  66. {#each token.items as item, itemIdx}
  67. <li>
  68. <svelte:self
  69. id={`${id}-${tokenIdx}-${itemIdx}`}
  70. tokens={item.tokens}
  71. top={token.loose}
  72. />
  73. </li>
  74. {/each}
  75. </ol>
  76. {:else}
  77. <ul>
  78. {#each token.items as item, itemIdx}
  79. <li>
  80. <svelte:self
  81. id={`${id}-${tokenIdx}-${itemIdx}`}
  82. tokens={item.tokens}
  83. top={token.loose}
  84. />
  85. </li>
  86. {/each}
  87. </ul>
  88. {/if}
  89. {:else if token.type === 'html'}
  90. {@html token.text}
  91. {:else if token.type === 'paragraph'}
  92. <p>
  93. <MarkdownInlineTokens id={`${id}-${tokenIdx}-p`} tokens={token.tokens ?? []} />
  94. </p>
  95. {:else if token.type === 'text'}
  96. {#if top}
  97. <p>
  98. {#if token.tokens}
  99. <MarkdownInlineTokens id={`${id}-${tokenIdx}-t`} tokens={token.tokens} />
  100. {:else}
  101. {unescapeHtml(token.text)}
  102. {/if}
  103. </p>
  104. {:else if token.tokens}
  105. <MarkdownInlineTokens id={`${id}-${tokenIdx}-p`} tokens={token.tokens ?? []} />
  106. {:else}
  107. {unescapeHtml(token.text)}
  108. {/if}
  109. {:else if token.type === 'space'}
  110. {''}
  111. {:else}
  112. {console.log('Unknown token', token)}
  113. {/if}
  114. {/each}