Skip to content

Commit 5e1ef13

Browse files
committed
feat: support runtime setting options
1 parent 018691b commit 5e1ef13

File tree

2 files changed

+60
-27
lines changed

2 files changed

+60
-27
lines changed

src/index.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import type { Options, PresetName } from 'markdown-it'
22
import MarkdownIt from 'markdown-it'
33

4-
export type {
5-
PluginSimple,
6-
PluginWithOptions,
7-
PluginWithParams,
8-
} from 'markdown-it'
4+
export type PluginSimple = (md: MarkdownItAsync) => void
5+
export type PluginWithOptions<T = any> = (md: MarkdownItAsync, options?: T) => void
6+
export type PluginWithParams = (md: MarkdownItAsync, ...params: any[]) => void
97

108
export interface MarkdownItAsyncOptions extends Omit<Options, 'highlight'> {
119
/**
@@ -43,7 +41,14 @@ export class MarkdownItAsync extends MarkdownIt {
4341
this.map = map
4442
}
4543

44+
use(plugin: PluginSimple): this
45+
use<T = any>(plugin: PluginWithOptions<T>, options?: T): this
46+
use(plugin: PluginWithParams, ...params: any[]): this {
47+
return super.use(plugin as any, ...params)
48+
}
49+
4650
async renderAsync(src: string, env?: any): Promise<string> {
51+
this.options.highlight = wrapHightlight(this.options.highlight, this.map)
4752
const result = this.render(src, env)
4853
return replaceAsync(result, placeholderRe, async (match, id) => {
4954
if (!this.map.has(id))
@@ -91,18 +96,28 @@ export function replaceAsync(string: string, searchValue: RegExp, replacer: (...
9196
}
9297
}
9398

99+
type NotNull<T> = T extends null | undefined ? never : T
100+
101+
const wrappedSet = new WeakSet<NotNull<Options['highlight']>>()
102+
94103
function wrapHightlight(highlight: MarkdownItAsyncOptions['highlight'], map: MarkdownItASyncPlaceholderMap): Options['highlight'] {
95104
if (!highlight)
96105
return undefined
97106

98-
return (str, lang, attrs) => {
107+
if (wrappedSet.has(highlight as any))
108+
return highlight as any
109+
110+
const wrapped: NotNull<Options['highlight']> = (str, lang, attrs) => {
99111
const promise = highlight(str, lang, attrs)
100112
if (typeof promise === 'string')
101113
return promise
102114
const id = randStr()
103115
map.set(id, [promise, str, lang, attrs])
104116
return placeholder(id)
105117
}
118+
119+
wrappedSet.add(wrapped)
120+
return wrapped
106121
}
107122

108123
export default createMarkdownItAsync

test/index.test.ts

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
import createMarkdownIt from 'markdown-it'
22
import { codeToHtml, createHighlighter } from 'shiki'
3-
import { expect, it } from 'vitest'
3+
import { describe, expect, it } from 'vitest'
44
import createMarkdownItAsync from '../src/'
55

6-
it('exported', async () => {
7-
const shiki = await createHighlighter({
6+
const fixture = `
7+
# Hello
8+
9+
Some code
10+
11+
\`\`\`ts
12+
console.log('Hello')
13+
\`\`\`
14+
`
15+
16+
describe('markdown-it-async', async () => {
17+
using shiki = await createHighlighter({
818
themes: ['vitesse-light'],
919
langs: ['ts'],
1020
})
@@ -14,27 +24,35 @@ it('exported', async () => {
1424
return shiki.codeToHtml(str, { lang, theme: 'vitesse-light' })
1525
},
1626
})
17-
const mda = createMarkdownItAsync({
18-
async highlight(str, lang) {
19-
return await codeToHtml(str, {
20-
lang,
21-
theme: 'vitesse-light',
22-
})
23-
},
24-
})
27+
const expectedResult = mds.render(fixture)
2528

26-
const fixture = `
27-
# Hello
29+
it('exported', async () => {
30+
const mda = createMarkdownItAsync({
31+
async highlight(str, lang) {
32+
return await codeToHtml(str, {
33+
lang,
34+
theme: 'vitesse-light',
35+
})
36+
},
37+
})
2838

29-
Some code
39+
expect(expectedResult)
40+
.toEqual(await mda.renderAsync(fixture))
41+
})
3042

31-
\`\`\`ts
32-
console.log('Hello')
33-
\`\`\`
34-
`
43+
it('via optons set', async () => {
44+
const mda = createMarkdownItAsync()
3545

36-
const result1 = mds.render(fixture)
37-
const result2 = await mda.renderAsync(fixture)
46+
mda.use((md) => {
47+
// @ts-expect-error cast, not yet have a solution to override this type
48+
md.options.highlight = async (str, lang) => {
49+
return await codeToHtml(str, {
50+
lang,
51+
theme: 'vitesse-light',
52+
})
53+
}
54+
})
3855

39-
expect(result1).toEqual(result2)
56+
expect(expectedResult).toEqual(await mda.renderAsync(fixture))
57+
})
4058
})

0 commit comments

Comments
 (0)