Skip to content

Commit 3e0a894

Browse files
committed
feat: implement factory function for MarkdownIt with math and container support
1 parent e776cbe commit 3e0a894

File tree

4 files changed

+29
-213
lines changed

4 files changed

+29
-213
lines changed

packages/markdown-parser/src/getMarkdown.ts renamed to packages/markdown-parser/src/factory.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import { applyContainers } from './plugins/containers'
55
import { applyMath } from './plugins/math'
66
import { applyRenderRules } from './renderers'
77

8-
export interface GetMarkdownOptions extends Record<string, any> {
8+
export interface FactoryOptions extends Record<string, any> {
99
markdownItOptions?: Record<string, any>
1010
enableMath?: boolean
1111
enableContainers?: boolean
1212
mathOptions?: { commands?: string[], escapeExclamation?: boolean }
1313
}
1414

15-
export function getMarkdown(opts: GetMarkdownOptions = {}): MarkdownIt {
15+
export function factory(opts: FactoryOptions = {}): MarkdownIt {
1616
const md = new MarkdownIt({
1717
html: true,
1818
linkify: true,

packages/markdown-parser/src/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1+
import type { FactoryOptions } from './factory'
12
import MarkdownIt from 'markdown-it'
23
import { full as markdownItEmoji } from 'markdown-it-emoji'
34
import markdownItFootnote from 'markdown-it-footnote'
45
import markdownItIns from 'markdown-it-ins'
56
import markdownItMark from 'markdown-it-mark'
67
import markdownItSub from 'markdown-it-sub'
78
import markdownItSup from 'markdown-it-sup'
8-
import * as markdownItCheckbox from 'markdown-it-task-checkbox'
99

10-
import { getMarkdown as factory } from './getMarkdown'
10+
import * as markdownItCheckbox from 'markdown-it-task-checkbox'
11+
import { factory } from './factory'
1112
import {
1213
parseInlineTokens,
1314
parseMarkdownToStructure,
@@ -33,7 +34,7 @@ export { applyMath, KATEX_COMMANDS, normalizeStandaloneBackslashT } from './plug
3334
// Re-export the node types for backward compatibility
3435
export * from './types'
3536

36-
export interface GetMarkdownOptions {
37+
export interface GetMarkdownOptions extends FactoryOptions {
3738
plugin?: Array<any>
3839
apply?: Array<(md: MarkdownIt) => void>
3940
/**
@@ -45,7 +46,7 @@ export interface GetMarkdownOptions {
4546

4647
export function getMarkdown(msgId: string = `editor-${Date.now()}`, options: GetMarkdownOptions = {}) {
4748
// keep legacy behaviour but delegate to new factory and reapply project-specific rules
48-
const md = factory({})
49+
const md = factory(options)
4950

5051
// Setup i18n translator function
5152
const defaultTranslations: Record<string, string> = {

playground/src/pages/markdown.vue

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<script setup lang="ts">
2-
import type { Highlighter } from 'shiki'
2+
import type { Highlighter, ThemeInput } from 'shiki'
33
import { Icon } from '@iconify/vue'
44
import katex from 'katex'
5-
import { disposeHighlighter, registerHighlight } from '../../../src/components/MarkdownCodeBlockNode/highlight'
5+
import { defaultLanguages, registerHighlight } from 'stream-markdown'
6+
import { getMarkdown } from '../../../packages/markdown-parser'
67
import { languageMap } from '../../../src/utils'
7-
import { getMarkdown } from '../../../src/utils/markdown/getMarkdown'
88
import { streamContent } from '../const/markdown'
99
// 每隔 10 毫秒输出一部分内容
1010
const content = ref<string>('')
@@ -25,7 +25,8 @@ useInterval(16, {
2525
2626
const highlighter = ref<Highlighter | null>(null)
2727
const selectedTheme = ref('vitesse-dark')
28-
const md = getMarkdown({
28+
29+
const md = getMarkdown('hi', {
2930
markdownItOptions: {
3031
highlight: (str: string, lang: string) => {
3132
const _lang = lang.split(':')[0] || 'plaintext'
@@ -38,17 +39,26 @@ const md = getMarkdown({
3839
},
3940
})
4041
md.renderer.rules.math_inline = (tokens: any[], index: number) => {
41-
const rendered = katex.renderToString(tokens[index].content, { throwOnError: false })
42+
const rendered = katex.renderToString(tokens[index].content, { throwOnError: false, strict: 'ignore' })
4243
if (rendered)
4344
return `<span class="math-inline">${rendered}</span>`
4445
return `<span class="math-inline">${tokens[index].content}</span>`
4546
}
4647
md.renderer.rules.math_block = (tokens: any[], index: number) => {
47-
const rendered = katex.renderToString(tokens[index].content, { throwOnError: false, displayMode: true })
48+
const rendered = katex.renderToString(tokens[index].content, { throwOnError: false, displayMode: true, strict: 'ignore' })
4849
if (rendered)
4950
return `<div class="math-block my-4">${rendered}</div>`
5051
return `<div class="math-block my-4">${tokens[index].content}</div>`
5152
}
53+
md.renderer.rules.fence = (tokens, idx) => {
54+
const token = tokens[idx]
55+
const langInfo = token.info ? token.info.trim() : ''
56+
const lang = langInfo.split(':')[0] || 'plaintext'
57+
if (highlighter.value) {
58+
return highlighter.value.codeToHtml(token.content, { lang: defaultLanguages.includes(lang) ? lang : 'plaintext', theme: selectedTheme.value })
59+
}
60+
return `<pre><code class="language-${lang}">${token.content}</code></pre>`
61+
}
5262
5363
const html = computed(() => md.render(content.value))
5464
// 主题切换
@@ -120,10 +130,12 @@ const themes = [
120130
121131
if (typeof window !== 'undefined') {
122132
watch(() => selectedTheme.value, async (newThemes) => {
123-
disposeHighlighter()
124-
highlighter.value = await registerHighlight({
125-
themes: [newThemes] as any,
126-
})
133+
if (!highlighter.value) {
134+
highlighter.value = await registerHighlight({
135+
themes: themes as ThemeInput[],
136+
})
137+
}
138+
highlighter.value?.loadTheme(newThemes as ThemeInput)
127139
}, { immediate: true })
128140
}
129141
// 格式化主题名称显示

src/components/MarkdownCodeBlockNode/highlight.ts

Lines changed: 0 additions & 197 deletions
This file was deleted.

0 commit comments

Comments
 (0)