Skip to content
This repository was archived by the owner on Feb 7, 2024. It is now read-only.

Commit 1d6afdf

Browse files
committedDec 14, 2023
feat(markdown-it): support fine-grain usage
1 parent bf5d09f commit 1d6afdf

File tree

6 files changed

+144
-85
lines changed

6 files changed

+144
-85
lines changed
 

‎package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
"@vitest/coverage-v8": "^1.0.4",
2626
"ansi-sequence-parser": "^1.1.1",
2727
"bumpp": "^9.2.1",
28-
"eslint-plugin-format": "^0.1.0",
2928
"eslint": "npm:eslint-ts-patch@8.55.0-1",
29+
"eslint-plugin-format": "^0.1.0",
3030
"eslint-ts-patch": "8.55.0-1",
3131
"esno": "^4.0.0",
3232
"fast-glob": "^3.3.2",

‎packages/markdown-it-shikiji/README.md

+31
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,31 @@ md.use(await Shikiji({
2424
}))
2525
```
2626

27+
## Fine-grained Bundle
28+
29+
By default, the full bundle of `shikiji` will be imported. If you are Shikiji's [fine-grained bundle](https://github.com/antfu/shikiji#fine-grained-bundle), you can import from `markdown-it-shikiji/core` and pass your own highlighter:
30+
31+
```ts
32+
import MarkdownIt from 'markdown-it'
33+
import { fromHighlighter } from 'markdown-it-shikiji/core'
34+
import { getHighlighterCore } from 'shikiji/core'
35+
import { getWasmInlined } from 'shikiji/wasm'
36+
37+
const highlighter = await getHighlighterCore({
38+
themes: [
39+
import('shikiji/themes/vitesse-light.mjs')
40+
],
41+
langs: [
42+
import('shikiji/langs/javascript.mjs'),
43+
],
44+
loadWasm: getWasmInlined
45+
})
46+
47+
const md = MarkdownIt()
48+
49+
md.use(fromHighlighter(highlighter, { /* options */ }))
50+
```
51+
2752
## Features
2853

2954
### Line Highlight
@@ -41,6 +66,12 @@ console.log('line4') // highlighted
4166
```
4267
````
4368

69+
````
70+
71+
```
72+
4473
## License
4574
4675
MIT
76+
```
77+
````

‎packages/markdown-it-shikiji/build.config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { defineBuildConfig } from 'unbuild'
33
export default defineBuildConfig({
44
entries: [
55
'src/index.ts',
6+
'src/core.ts',
67
],
78
declaration: true,
89
rollup: {

‎packages/markdown-it-shikiji/package.json

+4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
".": {
2222
"types": "./dist/index.d.mts",
2323
"default": "./dist/index.mjs"
24+
},
25+
"./core": {
26+
"types": "./dist/core.d.mts",
27+
"default": "./dist/core.mjs"
2428
}
2529
},
2630
"main": "./dist/index.mjs",
+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import type MarkdownIt from 'markdown-it'
2+
import { addClassToHast } from 'shikiji/core'
3+
import type { BuiltinTheme, CodeOptionsMeta, CodeOptionsThemes, CodeToHastOptions, HighlighterGeneric, ShikijiTransformer, TransformerOptions } from 'shikiji'
4+
import { parseHighlightLines } from '../../shared/line-highlight'
5+
6+
export interface MarkdownItShikijiExtraOptions {
7+
/**
8+
* Add `highlighted` class to lines defined in after codeblock
9+
*
10+
* @default true
11+
*/
12+
highlightLines?: boolean | string
13+
14+
/**
15+
* Custom meta string parser
16+
* Return an object to merge with `meta`
17+
*/
18+
parseMetaString?: (
19+
metaString: string,
20+
code: string,
21+
lang: string,
22+
) => Record<string, any> | undefined | null
23+
}
24+
25+
export type MarkdownItShikijiSetupOptions =
26+
& CodeOptionsThemes<BuiltinTheme>
27+
& TransformerOptions
28+
& CodeOptionsMeta
29+
& MarkdownItShikijiExtraOptions
30+
31+
export function setupMarkdownIt(
32+
markdownit: MarkdownIt,
33+
highlighter: HighlighterGeneric<any, any>,
34+
options: MarkdownItShikijiSetupOptions,
35+
) {
36+
const {
37+
highlightLines = true,
38+
parseMetaString,
39+
} = options
40+
41+
markdownit.options.highlight = (code, lang = 'text', attrs) => {
42+
const meta = parseMetaString?.(attrs, code, lang) || {}
43+
const codeOptions: CodeToHastOptions = {
44+
...options,
45+
lang,
46+
meta: {
47+
...options.meta,
48+
...meta,
49+
__raw: attrs,
50+
},
51+
}
52+
53+
const builtInTransformer: ShikijiTransformer[] = []
54+
55+
if (highlightLines) {
56+
const lines = parseHighlightLines(attrs)
57+
if (lines) {
58+
const className = highlightLines === true
59+
? 'highlighted'
60+
: highlightLines
61+
62+
builtInTransformer.push({
63+
name: 'markdown-it-shikiji:line-class',
64+
line(node, line) {
65+
if (lines.includes(line))
66+
addClassToHast(node, className)
67+
return node
68+
},
69+
})
70+
}
71+
}
72+
73+
builtInTransformer.push({
74+
name: 'markdown-it-shikiji:block-class',
75+
code(node) {
76+
node.properties.class = `language-${lang}`
77+
},
78+
})
79+
80+
return highlighter.codeToHtml(
81+
code,
82+
{
83+
...codeOptions,
84+
transformers: [
85+
...builtInTransformer,
86+
...codeOptions.transformers || [],
87+
],
88+
},
89+
)
90+
}
91+
}
92+
93+
export function fromHighlighter(
94+
highlighter: HighlighterGeneric<any, any>,
95+
options: MarkdownItShikijiSetupOptions,
96+
) {
97+
return function (markdownit: MarkdownIt) {
98+
setupMarkdownIt(markdownit, highlighter, options)
99+
}
100+
}
+7-84
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import type MarkdownIt from 'markdown-it'
2-
import { addClassToHast, bundledLanguages, getHighlighter } from 'shikiji'
3-
import type { BuiltinLanguage, BuiltinTheme, CodeOptionsMeta, CodeOptionsThemes, CodeToHastOptions, Highlighter, LanguageInput, ShikijiTransformer, TransformerOptions } from 'shikiji'
4-
import { parseHighlightLines } from '../../shared/line-highlight'
2+
import { bundledLanguages, getHighlighter } from 'shikiji'
3+
import type { BuiltinLanguage, BuiltinTheme, LanguageInput } from 'shikiji'
4+
import type { MarkdownItShikijiSetupOptions } from './core'
5+
import { setupMarkdownIt } from './core'
6+
7+
export * from './core'
58

69
export type MarkdownItShikijiOptions = MarkdownItShikijiSetupOptions & {
710
/**
@@ -12,86 +15,6 @@ export type MarkdownItShikijiOptions = MarkdownItShikijiSetupOptions & {
1215
langs?: Array<LanguageInput | BuiltinLanguage>
1316
}
1417

15-
export type MarkdownItShikijiSetupOptions = CodeOptionsThemes<BuiltinTheme>
16-
& TransformerOptions
17-
& CodeOptionsMeta
18-
& {
19-
/**
20-
* Add `highlighted` class to lines defined in after codeblock
21-
*
22-
* @default true
23-
*/
24-
highlightLines?: boolean | string
25-
26-
/**
27-
* Custom meta string parser
28-
* Return an object to merge with `meta`
29-
*/
30-
parseMetaString?: (
31-
metaString: string,
32-
code: string,
33-
lang: string,
34-
) => Record<string, any> | undefined | null
35-
}
36-
37-
function setup(markdownit: MarkdownIt, highlighter: Highlighter, options: MarkdownItShikijiSetupOptions) {
38-
const {
39-
highlightLines = true,
40-
parseMetaString,
41-
} = options
42-
43-
markdownit.options.highlight = (code, lang = 'text', attrs) => {
44-
const meta = parseMetaString?.(attrs, code, lang) || {}
45-
const codeOptions: CodeToHastOptions = {
46-
...options,
47-
lang,
48-
meta: {
49-
...options.meta,
50-
...meta,
51-
__raw: attrs,
52-
},
53-
}
54-
55-
const builtInTransformer: ShikijiTransformer[] = []
56-
57-
if (highlightLines) {
58-
const lines = parseHighlightLines(attrs)
59-
if (lines) {
60-
const className = highlightLines === true
61-
? 'highlighted'
62-
: highlightLines
63-
64-
builtInTransformer.push({
65-
name: 'markdown-it-shikiji:line-class',
66-
line(node, line) {
67-
if (lines.includes(line))
68-
addClassToHast(node, className)
69-
return node
70-
},
71-
})
72-
}
73-
}
74-
75-
builtInTransformer.push({
76-
name: 'markdown-it-shikiji:block-class',
77-
code(node) {
78-
node.properties.class = `language-${lang}`
79-
},
80-
})
81-
82-
return highlighter.codeToHtml(
83-
code,
84-
{
85-
...codeOptions,
86-
transformers: [
87-
...builtInTransformer,
88-
...codeOptions.transformers || [],
89-
],
90-
},
91-
)
92-
}
93-
}
94-
9518
export default async function markdownItShikiji(options: MarkdownItShikijiOptions) {
9619
const themeNames = ('themes' in options
9720
? Object.values(options.themes)
@@ -102,6 +25,6 @@ export default async function markdownItShikiji(options: MarkdownItShikijiOption
10225
})
10326

10427
return function (markdownit: MarkdownIt) {
105-
setup(markdownit, highlighter, options)
28+
setupMarkdownIt(markdownit, highlighter, options)
10629
}
10730
}

0 commit comments

Comments
 (0)
This repository has been archived.